Как реализовать обновление плагина WordPress, которое изменяет базу данных?

10

Я разрабатываю плагин WordPress, который имеет несколько собственных таблиц базы данных. Плагин создает эти таблицы при активации и удаляет их при удалении / удалении.

Я должен реализовать процесс обновления плагина, который обновляет код плагина, а также структуру таблиц. Простейший случай - добавить новый столбец в одну из таблиц. Более сложный случай - создать новую структуру таблиц и соответствующим образом обновить содержимое.

Как бы вы порекомендовали решить эту проблему? Есть ли встроенные функции WordPress, которые могут помочь?

Миша Морошко
источник

Ответы:

4

Правильный способ сделать это в наши дни - включить вашу схему в виде файла в источник плагина и использовать встроенную функцию WordPress dbDelta () для обновления базы данных по мере необходимости с использованием этой схемы. Требуемый код очень прост:

$sql = file_get_contents( plugin_dir_path(__FILE__) . "/schema.sql" );
dbDelta( $sql );

Это создаст и обновит базу данных для вас по мере необходимости. Когда я последний раз проверял, он не удалял старые неиспользуемые столбцы, так что вам нужно будет кодировать это с помощью проверки версии. Это прекрасная особенность WordPress и огромная экономия времени. Будьте осторожны при создании файла schema.sql, который копирует интервал в экспорт схемы mysql именно так, как считается, что код dbDelta () очень суетлив относительно интервала. Вам также следует проверить версию базы данных, и, если она не самая последняя, ​​позвоните по указанному выше, чтобы обновить базу данных. Вам также может потребоваться выполнить определенные обновления, чтобы покрыть изменения, которые dbDelta () не получает (например, удаление столбца). Легко написать простой логический тест if, чтобы увидеть, обновилась ли версия, и выполнить эти обновления вручную с помощью $ wpdb. Например, вы можете удалить столбец, который сейчас не используется.

$installed_ver = get_option(MY_DB_VERSION);
$wpp = $wpdb->prefix . "mypluginname";
if ($installed_ver < 102)
        $wpdb->query("ALTER TABLE ${wpp}_movies DROP nft_date");
if ($installed_ver < 107)
        $wpdb->query("ALTER TABLE ${wpp}_movies CHANGE lastupdated "
        . "lastupdated TIMESTAMP on update CURRENT_TIMESTAMP "
        . "NOT NULL DEFAULT CURRENT_TIMESTAMP");

update_option(MY_DB_VERSION, $db_version);

Это упрощается из-за запуска кода, извинения, если я нарушил его в процессе упрощения его публикации.

Также имейте в виду, что начиная с WordPress 3.9.2, WordPress не всегда запускает хук активации при обновлении плагина (в частности, если массовое обновление выполняется на странице «Обновления Dashboard»).

Брайан С
источник
В эти дни я начал брать версию БД со времени модификации файла schema.sql. Это означает, что простого обновления файла sche.sql достаточно, чтобы вызвать обновление базы данных; Не нужно помнить, чтобы редактировать версию базы данных. Что-то вроде: $ db_version = filemtime («schema.sql»);
Брайан C
1
Итак, если время файла изменяется от чего-то внешнего, например, от движущихся серверов, меняются версия mtime и db?
Уолф
Время файла всегда в GMT, и серверы редко различаются на несколько секунд, поэтому практически невозможно, чтобы это вызвало двойной запуск. Однако, даже если он снова сработает, никакого вреда не будет, поскольку он запускается один раз и выполняет сравнение с работающей БД, очевидно, ничего не меняя. Это прекрасная вещь в dbDelta () - она ​​может запускаться несколько раз без проблем. Хороший вопрос, спасибо.
Брайан С
3

Короче да - $wpdbкласс. См. Кодекс для получения дополнительной информации.

Всякий раз, когда вы взаимодействуете с пользовательской таблицей (или любой другой таблицей, на самом деле), вы должны пройти через нее $wpdb- в частности, убедитесь, что вы знакомы с prepareметодом, который может помочь избежать запросов и предотвратить инъекции.

Вы должны быть уже знакомы, так как вы должны использовать его для создания таблицы. На вашем установочном крюке у вас должно быть что-то вроде:

$charset_collate = '';
if ( ! empty($wpdb->charset) )
    $charset_collate = "DEFAULT CHARACTER SET $wpdb->charset";
if ( ! empty($wpdb->collate) )
    $charset_collate .= " COLLATE $wpdb->collate";

//Create custom table
$sql_custom_table ="CREATE TABLE {$wpdb->prefix}my_table (
    id bigint(20) unsigned NOT NULL auto_increment,
    column_a varchar(255) default NULL,
    column_b varchar(255) default NULL,
    PRIMARY KEY  (id)
    ) $charset_collate; ";

require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
dbDelta($sql_custom_table);

Этот код фактически запускается всякий раз, когда подключаемый модуль активирован (т.е. не только установлен). Так что он будет работать, когда кто-то автоматически обновит плагин . Примечание. Если они обновляются, заменяя плагин вручную - тогда это не произойдет - поэтому вам нужно будет активировать приведенный выше код admin_initпри обновлении вашего плагина (сохраните номер версии в таблице параметров, проверьте текущую версию) ,

Теперь вы обычно не хотите, чтобы команда CREATE TABLESQL выполнялась каждый раз, когда вы обновляете плагин dBDelta().

Перед выполнением вышеуказанной команды - она ​​проверяет, существует ли таблица. Более того, он проверяет типы столбцов. Поэтому, если таблица не существует, она создает ее, если она существует, но некоторые типы столбцов изменились, она обновляет их, а если столбец не существует - она ​​добавляет его.

К сожалению, если вы удалите столбец из вышеперечисленного, он не удалит столбец автоматически. Для удаления столбцов / таблиц вам необходимо их специально DROP(проверять, существуют ли они перед вами).

Стивен Харрис
источник