Статьи

Плагин WordPress обновляет правильный путь

Несколько недель назад я получил электронное письмо о WP Photo Sphere , плагине для WordPress, который я разработал. Возникла большая проблема: обновление плагина сломало его на некоторых установках. После некоторых исследований я обнаружил, что проблема связана с опциями, используемыми плагином: в этих установках не было значений по умолчанию для новых опций, которые я добавил.

Обновления плагинов WordPress

Эти значения были важны, поэтому мне нужен был способ создания значений по умолчанию. Но, вопреки тому, что я думал, WordPress не предоставляет какого-либо собственного способа управления процессом обновления.

Вот почему я подумал написать этот урок. Во-первых, мы увидим, зачем нам нужен процесс обновления и почему WordPress не обеспечивает такой процесс. Затем я покажу вам, как правильно создать собственный процесс для обновления ваших параметров.

Почему важен процесс обновления вашего плагина

Часто, изменение файлов недостаточно для правильного обновления чего-либо. Например, когда вы вручную обновляете файлы WordPress до новой версии, платформа попросит вас нажать кнопку, чтобы обновить базу данных.

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

Например, давайте посмотрим на следующий код.

function my_awesome_plugin_activation () { update_option( 'my_awesome_plugin_option' , 'default value' ); } register_activation_hook( __FILE__ , 'my_awesome_plugin_activation' ); 

Если вы не знакомы с использованием update_option() вместо add_option() , не беспокойтесь, мы объясним это позже, когда рассмотрим, как обрабатывать наш процесс обновления.

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

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

Чтобы быть более точным, это было, но WordPress остановил это поведение в версии 3.1. Команда разработчиков объяснила этот выбор, и вы можете прочитать все объяснение в блоге Make WordPress Core . Основная причина в том, что он не вызывался каждый раз, потому что, если пользователь вручную обновляет плагин, ловушка активации может быть пропущена.

Так что WordPress не предоставляет способ автоматического вызова функции по умолчанию сразу после обновления плагина. Вот почему вам нужно создать свой собственный процесс.

Как обрабатывать процесс обновления

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

Принцип этого метода

Глобальный принцип нашего метода заключается в том, что мы будем хранить номер версии нашего плагина в двух местах: в константе в основном файле плагина и в опции в базе данных.

Число в базе данных будет хранить версию, установленную в данный момент пользователем, а число в константе — текущая версия. Если эти два числа отличаются, то параметры базы данных не обновлялись с момента последнего обновления плагина, поэтому нам нужно это сделать.

В этом случае мы вызываем функцию, которая обновляет все необходимые параметры. Эта функция также обновляет номер версии, хранящийся в базе данных: таким образом, мы не будем вызывать эту функцию больше, чем необходимо.

Константа

Теперь, когда мы рассмотрели, что будем делать, пришло время кодировать! Сначала добавьте определение константы в основной файл вашего плагина, указав номер текущей версии в качестве значения. Чтобы предотвратить какие-либо проблемы, мы проверяем, если это еще не выходит.

 if (!defined( 'MY_AWESOME_PLUGIN_VERSION' )) define( 'MY_AWESOME_PLUGIN_VERSION' , '3.4.1' ); 

Обычно версии плагинов идентифицируются по номерам, но, если вы используете другую систему, не стесняйтесь использовать ее. Единственным ограничением здесь является наличие уникального идентификатора для каждой версии или, по крайней мере, для каждой версии, которая требует изменений в базе данных (новые параметры, новые значения по умолчанию и т. Д.).

Функция проверки

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

 function my_awesome_plugin_check_version () { } add_action( 'plugins_loaded' , 'my_awesome_plugin_check_version' ); 

Эта функция будет простой. Мы извлекаем номер версии, хранящийся в базе данных, как любой другой вариант, и сравниваем его с константой. Если эти значения отличаются, мы вызываем my_awesome_plugin_activation() .

 if (MY_AWESOME_PLUGIN_VERSION !== get_option( 'my_awesome_plugin_version' )) my_awesome_plugin_activation(); 

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

Так почему же мы вызываем функцию активации? Чтобы было ясно, мы могли бы создать новую функцию, посвященную процессу обновления. Но если вы сделаете это, вы увидите, что эта новая функция будет очень похожа на активацию, поскольку обновление опции может быть достигнуто так же, как мы ее создаем.

Обновление номера версии в базе данных

Вы можете делать все что угодно в функции активации, которая называется выше. Тем не менее, есть одна вещь, необходимая, обновление номера версии, хранящейся в базе данных. Таким образом, мы не будем вызывать нашу функцию каждый раз при загрузке страницы.

 update_option( 'my_awesome_plugin_version' , MY_AWESOME_PLUGIN_VERSION); 

Обратите внимание на хитрость: мы не используем add_option() , просто update_option() . Фактически, если опция еще не существует, update_option() создаст ее. Если он существует, он обновит свое значение до указанного. Вот почему мы можем без проблем использовать нашу функцию активации в качестве функции обновления.

Обновление параметров

Не отменяйте выбор пользователей!

Обновление любой опции может быть выполнено так же, как мы обновили номер версии: вы вызываете update_option() , и все готово, даже если WordPress видит эту опцию впервые.

Однако мы не всегда хотим обновлять значения параметров. Фактически, если вы используете опции, это часто позволяет вашим пользователям персонализировать настройки. Используя update_option() вы будете переопределять выбор пользователей каждый раз, когда обновляете плагин, а это не то, что мы хотим делать.

Выше мы видели, что get_option() возвращает false если опция не существует. Мы будем использовать это поведение, чтобы проверить, существует ли опция, которую мы хотим обновить, в базе данных. Если это так, мы ничего не делаем. В противном случае мы создаем опцию.

 if (get_option( 'my_awesome_option' ) === false ) update_option( 'my_awesome_option' , 'my_value' ); 

Обратите внимание, что этот тест необходим для опций, которые вы не хотите переопределять. В некоторых случаях мы можем захотеть сделать это, подумайте о номере версии, где мы, конечно же, не хотим сохранять старое значение!

Особый случай — Массивы

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

 update_option( 'my_awesome_plugin_settings' , array ( 'awesome_titles' => true , 'any_number' => 7 )); 

Использование массивов — хорошая идея, если вам нужно несколько настроек. Таким образом, вы не используете много записей в базе данных, и вы ограничиваете шансы иметь опцию с тем же именем, используемым другим плагином. Тем не менее, это может вызвать проблемы, когда мы думаем о процессе обновления.

Чтобы понять почему, предположим, что в качестве опции у вас есть массив с некоторыми ключами. Ваши пользователи обязательно персонализируют эти ценности. С помощью теста, который мы сделали выше, мы можем создать опцию, только если она не существует, и эти варианты не будут отменены. Это кажется простым, но что, если вы хотите создать новый ключ в вашем массиве?

Если опция существует в базе данных, предыдущий код не создаст ее, поэтому ваш новый ключ не будет существовать. Но если мы удалим условие, массив будет получать значения по умолчанию при каждом новом обновлении. Не идеально. К счастью, есть решение!

Сначала мы определяем массив, содержащий значения по умолчанию для наших параметров (с новыми ключами, если они существуют).

 $default = array ( 'awesome_title' => true , 'any_number' => 7 , 'new_option' => 'default' ) 

Затем мы получаем массив, в настоящее время хранящийся в базе данных.

 $option = get_option( 'my_awesome_plugin_settings' ); 

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

 $option_to_store = array_merge( $default , $option ); 

Наконец, мы сохраняем результат в базе данных с помощью update_option() .

 update_option( 'my_awesome_plugin_settings' , $option_to_store ); 

Мы близки к концу, но теперь нам нужно исправить ошибку, с которой вы можете столкнуться, если функция выполняется в первый раз.

Эта функция вызывается, когда плагин активирован, это то, что мы хотим. Но в этом случае опция еще не существует, поэтому get_option() возвращает false . Проблема в том, что использование false в качестве параметра для array_merge() приведет к ошибке.

Что нам нужно, так это просто: если опция не существует, мы хотим, чтобы $option была пустым массивом. Для этого мы можем использовать второй параметр get_option() который представляет значение по умолчанию для получения (чтобы не возвращать false ).

 $option = get_option( 'my_awesome_plugin_settings' , array ()); 

Вывод

После того, как вы прошли через это, обработка процесса обновления для плагина WordPress не слишком сложна. Тем не менее, важно использовать опции, так как не инициализация опций может вызвать некоторые проблемы.

В настоящее время WordPress не предоставляет собственный способ обработки обновлений плагинов. Дело в том, что, учитывая проблемы, которые мы перечислили выше, если мы увидим, что этот тип функций введен однажды, он должен быть реализован аналогично этому учебнику.

Вы можете получить код для моего примера плагина здесь . Рассматривайте этот код как каркас для реализации собственного процесса обновления плагина WordPress. Если у вас есть какие-либо отзывы, пожалуйста, дайте мне знать в комментариях ниже.