Работа с несколькими БД в Yii

22.12.2012

Yii framework

Периодически возникает потребность в расширении функциональности блога, а дописывать его на yii у меня нет ни времени, ни желания, и вот в который раз задумываюсь над переносом блога на WordPress. А что думать — надо делать, переносить руками 70 постов тоже нежелательно, поэтому и решил написать небольшой экшен на yii, для конвертации данных из БД блога в WP, а заодно и показать как просто работать с несколькими подключениями к базе данных.

Кроме этого в статье познакомимся с некоторыми особенностями wordpress.

WordPress

Создаем чистый блог на wp и генерируем новое приложение yii. Далее копируем дамп базы блога в какую-нибудь локальную БД и конфигурируем два подключения:

'db'=>array(
    'class'=>'CDbConnection',
    'connectionString' => 'mysql:host=localhost;dbname=blog_test',
    'emulatePrepare' => true,
    'username' => 'root',
    'password' => '',
    'charset' => 'utf8',
),
'db2'=>array(
    'class'=>'CDbConnection',
    'connectionString' => 'mysql:host=localhost;dbname=wp',
    'emulatePrepare' => true,
    'username' => 'root',
    'password' => '',
    'charset' => 'utf8',
),

Важно указать классы компонентов(CDbConnection), иначе будет ошибка. И последнее что осталось сделать — сгенерировать модели в gii.

Генерация моделей в Gii

По умолчанию используется первое подключение db, а в моделях, использующих db2 переопределяется метод getDbConnection():

public function getDbConnection() {
    return Yii::app()->db2;
}

И последнее — пишем сам экшен, нам надо перенести теги, посты ну и связи тегов с постами.

За теги в wordpress отвечают 3 таблицы: wp_terms(список тегов), wp_term_relationships(связь между постами и тегами), wp_term_taxonomy(связи терминов и категорий терминов, описание категорий терминов, а также сколько раз термин был назначен постам). В wp_terms есть поле slug, также в таблице wp_posts поле post_name, которое содержит имя записи, используемой для построения url, в wp оно генерируется с помощью функции urlencode, но также его можно генерировать любой собственной функцией, например транслитом от названия статьи.

Вот какой экшен у меня получился:

// Переносим теги
$yiiTags = BlgTag::model()->findAll();
foreach($yiiTags as $yiiTag) {
	$wpTerm = new WpTerms();
	$wpTerm->name = $yiiTag->name;
	$wpTerm->slug = urlencode($yiiTag->name);
	$wpTerm->save();
	// Добавляем термин в таксономию
	$wpTermTax = new WpTermTaxonomy();
	$wpTermTax->term_id = $wpTerm->getPrimaryKey();
	$wpTermTax->taxonomy = 'category';
	$wpTermTax->parent = 0;
	$wpTermTax->count = 0;
	$wpTermTax->description = '';
	$wpTermTax->save();
}

// Переносим посты
$yiiPosts = BlgPost::model()->findAll();
foreach($yiiPosts as $yiiPost) {
	$wpPost = new WpPosts();
	$wpPost->post_author = 1;
	$wpPost->post_date = date('Y-m-d H:i:s', $yiiPost->createTime);
	$wpPost->post_date_gmt = $wpPost->post_date;
	$wpPost->post_content = $yiiPost->text;
	$wpPost->post_title = $yiiPost->title;
	$wpPost->post_status = 'publish';
	$wpPost->post_name = $yiiPost->url;
	$wpPost->guid = 'http://wp/?p='.$yiiPost->url;
	$wpPost->post_type = 'post';
	$wpPost->post_excerpt = '';
	$wpPost->to_ping = '';
	$wpPost->pinged = '';
	$wpPost->post_content_filtered = '';
	$wpPost ->save();

	// Переносим теги
	$tags = explode(', ', $yiiPost->tags);
	$tags = array_diff($tags, array(''));
	foreach($tags as $k=>$v) {
		$termId = WpTerms::model()->findByAttributes(array('name'=>trim($v)))->term_id;
		$termTaxId = WpTermTaxonomy::model()->findByAttributes(array('term_id' => $termId))->term_taxonomy_id;
		$termTax = new WpTermRelationships();
		$termTax->object_id = $wpPost->getPrimaryKey();
		$termTax->term_taxonomy_id = $termTaxId;
		$termTax->term_order = 0;
		$termTax->save();
	}
}

Вначале я напутал в заполнении таблицы wp_term_relationships, вместо WpTermTaxonomy-> term_taxonomy_id я вставлял id-тега, но потом мне помогла разобраться диаграмма связей таблиц WP: http://codex.wordpress.org/Database_Description.
В дополнение хочу сказать, что структура БД моего блога, аналогичная структуре демонстрационного блога, с небольшими доработками, это можно заметить из кода выше.

Вот что мы получаем после выполнения скрипта:

Управление записями в WordPress

И последние что осталось сделать — исправить алгоритм формирования URL, для этого идем в Параметры → Постоянные ссылки, в Общих настройках выбираем Произвольно и исправляем текстовое поле на: /content/%postname%/:

Параметры формирования URL в WordPress

Итог — данные полностью перенесены на WordPress с сохранением URL! Осталось только перенести шаблон, подключить необходимые модули, настроить некоторые мелочи и всё будет готово ;)

blog comments powered by Disqus
Наверх