Меняем id блога в WordPress

Сделав в wordpress мультисайтинг, я добавил в сеть ещё один сайт, а через некоторое время добавил английскую версию для блога, который в списке сайтов стоял первым. Английская версия встала, разумеется, в конец, а мне хотелось, чтобы она стояла под своей русской версией. Есть много способов сделать это, например, создав greasemonkey-скрипт, или написав плагин для wordpress, и, пожалуй, самым неразумным будет изменение данных в mysql-базе, но именно так я и поступил =)

Итак, есть блог с идентификатором 1, потом ещё один блог с id 2, и английская версия первого блога с id 3. Английская версия должна стать блогом с id 2, а блог с текущим id 2 должен стать с id 3. Пока есть блог с id 2, я не могу сразу блог с id 3 делать блогом с id 2, поэтому 2 сначала будет становиться 4, потом 3 будет становиться 2, и в конце уже 4 будет становиться 3.

Список блогов находится в таблице wp_blogs, начнём с неё:

UPDATE wp_blogs SET blog_id=4 WHERE blog_id=2;
UPDATE wp_blogs SET blog_id=2 WHERE blog_id=3;
UPDATE wp_blogs SET blog_id=3 WHERE blog_id=4;

Но осталась ещё куча данных, завязанных на старые id, их нужно искать и менять. Начнём с таблиц.

При создании каждого блога, в mysql-базе создаются таблицы commentmeta, comments, links, options, postmeta, posts, term_relationships, term_taxonomy, terms с префиксом «wp_n_», где n – идентификатор блога в таблице wp_blogs (кроме блога с id 1). Если непонятно написал – создаются таблицы вида wp_2_commentmeta и т.д.

Переименовывать будем командой RENAME TABLE. Но для каждого блога 9 таблиц, и нам нужно сначала 2 перевести в 4, а только потом 3 в 2 и 4 в 3, поэтому выйдет 27 команд. Писать от руки – долго, поэтому пусть команды сгенерируются сами.

Select Concat( 'RENAME TABLE ', table_name, ' TO ', REPLACE(table_name, 'wp_2_', 'wp_4_'), ';' )
From information_schema.tables
Where table_schema = 'имя_базы' AND table_name LIKE 'wp_2_%';

Осталось только их скопировать и выполнить. Далее то же самое нужно сделать, для wp_3_ -> wp_2_ и wp_4_ -> wp_3_ (заменять не только в REPLACE, но и в LIKE).

По поводу LIKE: условие сейчас не совсем корректное. В LIKE нижнее подчёркивание «_» это один любой символ. То есть условие подходит и для «wpp2w», «wpa2z» и прочих подобных. Но так как мы знаем, что у нас в базе ничего подобного нет, в данном случае можно пренебречь. Корректное условие такое: AND table_name LIKE ‘wp!_2!_%’ escape ‘!’;

Не понравилось, что в таблице wp_n_options роли пользователя сохранены под именем wp_n_user_roles. Зачем эта привязка, нельзя было просто user_roles? Впрочем, меняем:

UPDATE wp_2_options SET option_name='wp_2_user_roles' WHERE option_name='wp_3_user_roles';
UPDATE wp_3_options SET option_name='wp_3_user_roles' WHERE option_name='wp_2_user_roles';

Осталось ещё изменить данные в wp_usermeta:

UPDATE wp_usermeta SET meta_key=REPLACE(meta_key,'wp_2_','wp_4_') WHERE meta_key LIKE 'wp_2_%';
UPDATE wp_usermeta SET meta_key=REPLACE(meta_key,'wp_3_','wp_2_') WHERE meta_key LIKE 'wp_3_%';
UPDATE wp_usermeta SET meta_key=REPLACE(meta_key,'wp_4_','wp_3_') WHERE meta_key LIKE 'wp_4_%';

Теперь всё связано как надо. Если путь сохранения файлов был типа «wp-content/blogs.dir/2/files», то можно и его заменить на соответствующий.

Оставьте комментарий