Профессиональный плагин для управления миграциями базы данных WordPress с поддержкой безопасного переноса сущностей, автоматического выполнения и отката изменений.
- Описание
- Основные возможности
- Установка
- Быстрый старт
- Документация
- Примеры использования
- API и хуки
- Безопасность
- Требования
- Структура проекта
- Лицензия
Migrations Plugin — это мощный инструмент для управления изменениями базы данных WordPress. Плагин позволяет версионировать изменения структуры БД, автоматически применять их при обновлениях и безопасно откатывать при необходимости.
- ✅ Версионирование изменений БД — все изменения структуры базы данных хранятся в виде миграций
- ✅ Автоматическое выполнение — миграции выполняются автоматически при активации/обновлении плагина
- ✅ Безопасный перенос сущностей — перенос постов, пользователей, терминов с проверкой существования
- ✅ Откат изменений — возможность откатить любую миграцию через админ-панель
- ✅ Логирование — полная история выполненных миграций с временем выполнения и ошибками
- ✅ Админ-панель — удобный интерфейс для управления миграциями
- ✅ Автоматическое выполнение миграций при активации/обновлении плагина
- ✅ Ручной запуск миграций через админ-панель
- ✅ Откат миграций (rollback) в обратном порядке
- ✅ Логирование всех выполненных миграций
- ✅ Отслеживание статуса выполнения (completed/failed)
- ✅ Обработка ошибок с детальными сообщениями
- ✅ Перенос постов с проверкой существования по ID, slug, мета-полям
- ✅ Перенос пользователей с автоматическим обновлением существующих
- ✅ Перенос терминов (категории, теги, таксономии)
- ✅ Проверка существования таблиц и колонок перед созданием
- ✅ Обновление существующих элементов вместо создания дубликатов
- ✅ Выбор элементов для миграции через Entity_Selector
- ✅ Поддержка мета-данных и терминов при переносе
- ✅ Защита от SQL Injection (использование
$wpdb->prepare()) - ✅ Защита от XSS (экранирование всех выходных данных)
- ✅ Защита от CSRF (проверка nonce для всех действий)
- ✅ Защита от Local File Inclusion
- ✅ Проверка прав доступа для всех административных функций
- ✅ Валидация всех входных данных
Подробный отчет о безопасности см. в SECURITY.md
- WordPress 5.0 или выше
- PHP 7.2 или выше
- MySQL 5.6 или выше
-
Скачайте плагин
# Скопируйте папку migrations-plugin в wp-content/plugins/ -
Активируйте плагин
- Перейдите в Плагины → Установленные плагины
- Найдите "Migrations Plugin"
- Нажмите Активировать
-
Проверьте настройки
- Перейдите в Инструменты → Миграции
- Убедитесь, что таблица миграций создана
-
Создайте файл миграции в папке
migrations/:<?php // migrations/001_create_example_table.php class Migration_001_Create_Example_Table { public function up() { global $wpdb; $table_name = $wpdb->prefix . 'example_table'; $charset_collate = $wpdb->get_charset_collate(); $sql = "CREATE TABLE IF NOT EXISTS $table_name ( id bigint(20) NOT NULL AUTO_INCREMENT, name varchar(255) NOT NULL, created_at datetime DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY (id) ) $charset_collate;"; require_once(ABSPATH . 'wp-admin/includes/upgrade.php'); dbDelta($sql); } public function down() { global $wpdb; $table_name = $wpdb->prefix . 'example_table'; $wpdb->query("DROP TABLE IF EXISTS $table_name"); } }
-
Запустите миграцию
- Перейдите в Инструменты → Миграции
- Нажмите "Запустить все миграции" или "Запустить" для конкретной миграции
<?php
$post_data = array(
'post_title' => 'Название поста',
'post_name' => 'post-slug',
'post_content' => 'Содержимое',
'post_status' => 'publish',
'post_type' => 'post',
'meta' => array(
'custom_field' => 'значение',
),
);
$result = Entity_Migrator::migrate_post($post_data, array(
'update_if_exists' => true, // Обновлять если существует
));
if ($result['success']) {
echo "Действие: " . $result['action']; // 'created', 'updated' или 'skipped'
echo "ID поста: " . $result['post_id'];
}Плагин включает подробную документацию:
-
MIGRATIONS_GUIDE.md — Руководство по созданию миграций
- Что должно и не должно попадать в миграции
- Принципы написания миграций
- Примеры правильных миграций
- Чеклист перед созданием миграции
-
ENTITY_MIGRATION_GUIDE.md — Руководство по миграции сущностей
- Безопасный перенос постов, пользователей, терминов
- Проверка существования элементов
- Массовый импорт с выбором элементов
- Примеры использования Entity_Migrator и Entity_Selector
-
ADMIN_UI_GUIDE.md — Руководство по админ-панели
- Интерфейс управления миграциями
- Запуск и откат миграций
- Просмотр логов выполнения
-
SECURITY.md — Отчет о безопасности
- Защита от SQL Injection
- Защита от XSS
- Защита от CSRF
- Проверка прав доступа
<?php
class Migration_002_Create_Products_Table {
public function up() {
global $wpdb;
$table_name = $wpdb->prefix . 'products';
$charset_collate = $wpdb->get_charset_collate();
$sql = "CREATE TABLE IF NOT EXISTS $table_name (
id bigint(20) NOT NULL AUTO_INCREMENT,
name varchar(255) NOT NULL,
price decimal(10,2) NOT NULL,
description text,
created_at datetime DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (id),
KEY idx_name (name)
) $charset_collate;";
require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
dbDelta($sql);
}
public function down() {
global $wpdb;
$table_name = $wpdb->prefix . 'products';
$wpdb->query("DROP TABLE IF EXISTS $table_name");
}
}<?php
class Migration_003_Add_Status_Column {
public function up() {
global $wpdb;
$table_name = $wpdb->prefix . 'products';
// Проверяем существование колонки
$column_exists = $wpdb->get_results(
$wpdb->prepare(
"SHOW COLUMNS FROM {$table_name} LIKE %s",
'status'
)
);
if (empty($column_exists)) {
$wpdb->query("ALTER TABLE $table_name ADD COLUMN status varchar(50) DEFAULT 'active'");
}
}
public function down() {
global $wpdb;
$table_name = $wpdb->prefix . 'products';
$column_exists = $wpdb->get_results(
$wpdb->prepare(
"SHOW COLUMNS FROM {$table_name} LIKE %s",
'status'
)
);
if (!empty($column_exists)) {
$wpdb->query("ALTER TABLE $table_name DROP COLUMN status");
}
}
}<?php
class Migration_004_Safe_Create_Table {
public function up() {
global $wpdb;
$table_name = $wpdb->prefix . 'custom_data';
$charset_collate = $wpdb->get_charset_collate();
$sql = "CREATE TABLE IF NOT EXISTS $table_name (
id bigint(20) NOT NULL AUTO_INCREMENT,
post_id bigint(20) NOT NULL,
custom_value varchar(255),
PRIMARY KEY (id),
KEY idx_post_id (post_id)
) $charset_collate;";
$result = Entity_Migrator::safe_create_table($table_name, $sql);
if (!$result['success']) {
throw new Exception('Не удалось создать таблицу');
}
// Безопасное добавление колонки
if (!Entity_Migrator::column_exists($table_name, 'status')) {
Entity_Migrator::safe_add_column(
$table_name,
'status',
"varchar(50) DEFAULT 'active'"
);
}
}
public function down() {
global $wpdb;
$table_name = $wpdb->prefix . 'custom_data';
if (Entity_Migrator::table_exists($table_name)) {
$wpdb->query("DROP TABLE IF EXISTS $table_name");
}
}
}<?php
class Migration_005_Import_Posts {
public function up() {
// Получаем посты для импорта
$posts = Entity_Selector::get_posts_for_migration(array(
'post_type' => 'product',
'post_status' => 'publish',
'numberposts' => 10,
));
foreach ($posts as $post_data) {
unset($post_data['ID']); // Убираем ID для безопасного импорта
$result = Entity_Migrator::migrate_post($post_data, array(
'update_if_exists' => true,
'update_meta' => true,
'update_terms' => true,
));
if (!$result['success']) {
error_log('Ошибка импорта поста: ' . $result['error']);
}
}
}
public function down() {
// Откат миграции
// Удаление импортированных постов
}
}// Запустить все миграции
do_action('migrations_plugin_run');
// Откатить все миграции
do_action('migrations_plugin_rollback');// Изменить путь к папке с миграциями
add_filter('migrations_plugin_dir', function($dir) {
return get_template_directory() . '/migrations/';
});$runner = new Migration_Runner();
// Запустить все миграции
$results = $runner->run();
// Запустить конкретную миграцию
$results = $runner->run('001_example_migration');
// Откатить все миграции
$results = $runner->rollback();
// Откатить конкретную миграцию
$results = $runner->rollback('001_example_migration');Плагин соответствует стандартам безопасности WordPress:
- ✅ Защита от SQL Injection — все запросы используют
$wpdb->prepare() - ✅ Защита от XSS — все выходные данные экранируются
- ✅ Защита от CSRF — проверка nonce для всех действий
- ✅ Защита от Local File Inclusion — валидация путей к файлам
- ✅ Проверка прав доступа —
current_user_can()для всех административных функций - ✅ Валидация входных данных — санитизация всех пользовательских данных
Подробный отчет о безопасности см. в SECURITY.md
- WordPress: 5.0 или выше
- PHP: 7.2 или выше
- MySQL: 5.6 или выше
- Права доступа: Администратор для управления миграциями
migrations-plugin/
├── migrations/ # Папка с миграциями
│ ├── 001_example_migration.php
│ └── ...
├── includes/ # Основные классы
│ ├── class-migrations.php # Главный класс плагина
│ ├── class-migration-runner.php # Выполнение миграций
│ ├── class-entity-migrator.php # Перенос сущностей
│ ├── class-entity-selector.php # Выбор элементов
│ ├── class-export-loader.php # Загрузка экспортов
│ └── class-backup.php # Резервное копирование
├── admin/ # Админ-панель
│ └── class-migrations-admin.php # Интерфейс управления
├── exports/ # Экспорты данных
├── backups/ # Резервные копии
├── migrations-plugin.php # Главный файл плагина
├── README.md # Документация
├── MIGRATIONS_GUIDE.md # Руководство по миграциям
├── ENTITY_MIGRATION_GUIDE.md # Руководство по переносу сущностей
├── ADMIN_UI_GUIDE.md # Руководство по админ-панели
└── SECURITY.md # Отчет о безопасности
Плагин создает таблицу wp_migrations_log для хранения информации о выполненных миграциях:
| Колонка | Тип | Описание |
|---|---|---|
id |
bigint(20) | ID записи |
migration_name |
varchar(255) | Имя миграции |
migration_file |
varchar(255) | Имя файла миграции |
executed_at |
datetime | Дата и время выполнения |
execution_time |
decimal(10,4) | Время выполнения в секундах |
status |
varchar(20) | Статус (completed/failed) |
error_message |
text | Сообщение об ошибке (если есть) |
- Файл:
001_descriptive_name.php - Класс:
Migration_001_Descriptive_Name
Имя класса формируется автоматически:
- Префикс
Migration_ - Номер из имени файла
- Каждое слово с заглавной буквы, разделено подчеркиванием
- Файл:
001_create_users_table.php→ Класс:Migration_001_Create_Users_Table - Файл:
002_add_status_column.php→ Класс:Migration_002_Add_Status_Column - Файл:
003_migrate_old_data.php→ Класс:Migration_003_Migrate_Old_Data
add_filter('migrations_plugin_dir', function($dir) {
return get_template_directory() . '/custom-migrations/';
});Миграции автоматически выполняются:
- При активации плагина
- При обновлении версии плагина (изменение
MIGRATIONS_PLUGIN_VERSION)
// В wp-config.php
define('WP_DEBUG', true);
define('WP_DEBUG_LOG', true);- Перейдите в Инструменты → Миграции
- Просмотрите список выполненных миграций
- Нажмите на миграцию для просмотра деталей
- Первый релиз
- Автоматическое выполнение миграций
- Ручной запуск и откат через админ-панель
- Безопасный перенос сущностей WordPress
- Логирование выполненных миграций
- Полная документация
Для вопросов и предложений создавайте issue в репозитории проекта.
GPL v2 or later
Copyright (c) 2024
This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
VP
Важно: Перед выполнением миграций на продакшн-сервере всегда делайте резервную копию базы данных!
