Руководство по файлу uninstall.php в WordPress

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

Как работает uninstall.php

Обычно вам нужно добавить файл uninstall.php в основную (корневую) директорию плагина. К примеру, у вас есть плагин под названием Add Data to WP Database, и его основная директория – это /add-data-wp-database/. В эту директорию мы можем добавить файл uninstall.php со следующим кодом:

/add-data-wp-database/
	/add-data-wp-database.php
	/index.php
	/uninstall.php <--- here it is.
	/readme.txt

Теперь при деинсталляции (удалении) плагина через экран Plugins в панели администратора, WordPress найдет и выполнит uninstall.php. Такой подход позволяет разработчикам плагинов удалять любые нежелательные или неиспользуемые данные из БД.

Вот как это работает в двух словах. Для более подробной информации вы можете обратиться к Кодексу WP.

Какой код подойдет для размещения в uninstall.php

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

<?php // exit if uninstall constant is not defined
if (!defined('WP_UNINSTALL_PLUGIN')) exit;

Эти строки должны быть расположены в самом начале uninstall.php перед любым другим кодом. В коде проверяется константа WP_UNINSTALL_PLUGIN, которая определяется WordPress непосредственно перед загрузкой uninstall.php. Если кто-то попытается получить доступ к файлу со стороны, выполнение скрипта немедленно завершится.

Чтобы дать вам лучшее представление, вот пример файла uninstall.php, который удаляет несколько типов данных. Обратите внимание, что большая часть кода исключена для ясности:

<?php // exit if uninstall constant is not defined
if (!defined('WP_UNINSTALL_PLUGIN')) exit;

// remove plugin options

// remove plugin transients

// remove plugin cron events

// ..etc., based on what needs to be removed

Отсюда видно, что подходы в плане кода сильно зависят от данных, которые требуется удалить или изменить. Код будет варьироваться от плагина к плагину. Вам нужно точно знать, какие данные вы хотите удалить, прежде чем использовать соответствующую методику. В следующих разделах этого руководства мы рассмотрим методы удаления всех типов данных из БД WordPress.

Удаление опций (параметров) плагина

Самым популярным методом удаления параметров плагина является функция delete_option(). К примеру, чтобы удалить параметр под названием myplugin_options, добавьте следующий код в файл uninstall.php:

// delete plugin options
delete_option('myplugin_options');

Или, если у вас есть несколько опций для удаления, используйте массив:

// delete multiple options
$options = array(
	'myplugin_option_1',
	'myplugin_option_2',
	'myplugin_option_3',
);
foreach ($options as $option) {
	if (get_option($option)) delete_option($option);
}

Просто переименуйте элементы массива (к примеру, myplugin_option_1 и т.д.), указав опции вашего плагина, которые вы хотите удалить. Все просто!

Удаление transient’ов плагина

Еще один распространенный подход – удаление всех transient’ов плагина из БД. Для этого мы можем использовать функцию delete_transient():

// delete plugin transient
delete_transient('myplugin_transient');

Если вам нужно удалить несколько transient’ов, то тогда вы можете воспользоваться массивом:

// delete multiple transients
$transients = array(
	'myplugin_transient_1',
	'myplugin_transient_2',
	'myplugin_transient_3',
);
foreach ($transients as $transient) {
	delete_transient($transient);
}

Просто переименуйте элементы массива (к примеру, myplugin_transient_1 и т.д.), указав transient’ы вашего плагина, которые вы хотите удалить.

Удаление событий cron

Следующая методика показывает, как удалять события cron с помощью функции wp_unschedule_event(). Вот пример:

// delete cron event
$timestamp = wp_next_scheduled('myplugin_cron_event');
wp_unschedule_event($timestamp, 'myplugin_cron_event');

Хитрость здесь состоит в том, чтобы использовать wp_next_scheduled() с целью получения правильного значения $timestamp для события, которое вы хотите удалить.

Удаление таблиц базы данных

Одна из моих любимых методик. Будьте с ней аккуратнее. Убедитесь, что название таблицы задано верно. Вот пример того, как удалить таблицу под названием myplugin_table:

// delete database table
global $wpdb;
$table_name = $wpdb->prefix .'myplugin_table';
$wpdb->query("DROP TABLE IF EXISTS {$table_name}");

В методике используется класс wpdb для определения $table_name, после чего удаляется таблица, если она существует. Опять же, очень важно заменить myplugin_table на правильное имя таблицы, которую вы хотите удалить. Никаких других изменений в коде не требуется. Проверьте все очень тщательно!

Удаление записей и страниц

Чтобы удалить запись или страницу, мы можем использовать wp_trash_post(). К примеру, чтобы удалить пост с ID 44, нам нужен будет следующий код:

// delete post id 44
wp_trash_post(44);

Хитрость этой техники заключается в определении правильного ID для страницы или записи. Есть несколько способов сделать это. Самый простой – сохранить ID любых записей и страниц, которые добавляются вашим плагином. К примеру, если ваш плагин добавляет три страницы при первой активации, вы можете добавить ID этих страниц в БД в качестве опции. Затем вы сможете обратиться к этим опциям и получить корректные посты для удаления. В коде это выглядит примерно так:

// delete pages
$myplugin_pages = get_option('myplugin_pages');
if (is_array($myplugin_pages) && !empty($myplugin_pages)) {
	foreach ($myplugin_pages as $myplugin_page) {
		wp_trash_post($myplugin_page);
	}
}

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

Удаление произвольных типов записей

Здесь речь пойдет об удалении постов, которые определены как произвольный тип записей (CPT). Соответственно, мы удаляем не сам тип записей, а все записи, которые относятся к этому типу. Чтобы сделать это, мы можем использовать функцию wp_delete_post. Вот пример, как удалить все записи, которые относятся к произвольному типу myplugin_cpt:


// delete custom post type posts
$myplugin_cpt_args = array('post_type' => 'myplugin_cpt', 'posts_per_page' => -1);
$myplugin_cpt_posts = get_posts($myplugin_cpt_args);
foreach ($myplugin_cpt_posts as $post) {
	wp_delete_post($post->ID, false);
}

Здесь мы используем get_posts, чтобы получить все записи, которые относятся к произвольному типу myplugin_cpt. Затем мы циклически проходим по результатам и используем wp_delete_post для удаления каждой записи этого типа. Единственное, что вам нужно изменить в коде – это название (слаг) произвольного типа записей, myplugin_cpt.

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

Примечание: Функция wp_delete_post удаляет не только все записи, но и все, что привязано к ним, включая комментарии, метаданные, термы и т.д.

Второй параметр wp_delete_post задан в false. Это означает, что пост будет перемещен в Корзину, откуда пользователь сможет при желании восстановить его позднее. Если вы хотите удалять посты без корзины, то тогда смените данный параметр на true.

Удаление метаданных пользователей

Чтобы удалить пользовательские метаданные, используйте функцию delete_user_meta(). К примеру, чтобы удалить все метаданные myplugin_user_meta, укажите следующий код:

// delete user meta
$users = get_users();
foreach ($users as $user) {
	delete_user_meta($user->ID, 'myplugin_user_meta');
}

Здесь мы используем get_users() для получения массива пользователей. Затем мы проходим по массиву и используем delete_user_meta для удаления всех пользовательских метаданных с названием myplugin_user_meta. Таким образом, чтобы использовать эту методику, просто поставьте вместо myplugin_user_meta название ваших метаданных, которые вы хотите удалить.

Примечание: если вы хотите удалить метаданные у определенного подмножества пользователей, то в таком случае вам необходимо обратиться к WP_User_Query::prepare_query().

Удаление метаданных записей

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

// delete post meta
$myplugin_post_args = array('posts_per_page' => -1);
$myplugin_posts = get_posts($myplugin_post_args);
foreach ($myplugin_posts as $post) {
	delete_post_meta($post->ID, 'myplugin_post_meta');
}

В данной технике используется get_posts() для получения всех записей. Затем мы проходимся по ним и удаляем все метаданные под названием myplugin_post_meta. Просто замените myplugin_post_meta на ваше название метаданных, чтобы использовать эту технику.

Удаление метаданных только у произвольных типов записей

Если вы хотите удалить метаданные ТОЛЬКО у произвольного типа записей, то в таком случае замените значение $myplugin_post_args в коде выше на следующее:

array('post_type' => 'myplugin_cpt', 'posts_per_page' => -1);

Здесь мы добавили параметр post_type к get_posts(). Чтобы использовать технику для вашего произвольного типа записей, замените myplugin_cpt на название вашего типа.

Альтернативный метод использования delete_metadata()

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

// delete post meta
delete_metadata('post', 0, 'myplugin_meta_key', '', true);

Техника завязана на следующих параметрах:

  • $meta_type – тип объекта (комментарий, пост, терм или пользователь).
  • $object_id – ID объекта или 0 для всех
  • $meta_key – название метаданных
  • $meta_value – значение метаданных
  • $delete_all – удаление всех метаданных

Мы передали этим параметрам следующие аргументы соответственно:

  • post – мы выбрали записи в качестве объекта
  • 0 – выбрали все записи
  • myplugin_meta_key – название наших метаданных
  • (empty) – оставляем пустым для выбора всех метаданных
  • true – важно оставить именно true для удаления всех подходящих результатов.

Как и можно было себе представить, delete_metadata() – очень гибкий и мощный инструмент, позволяющий удалять практически любые метаданные, существующие в БД WordPress.

Пример файла uninstall.php

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

<?php /* Example uninstall.php file Contains examples provided in the tutorial: WordPress uninstall.php file - The Complete Guide @ https://digwp.com/2019/10/wordpress-uninstall-php/ */ // exit if uninstall constant is not defined if (!defined('WP_UNINSTALL_PLUGIN')) exit; // delete plugin options delete_option('myplugin_options'); // delete plugin transient delete_transient('myplugin_transient'); // delete cron event $timestamp = wp_next_scheduled('myplugin_cron_event'); wp_unschedule_event($timestamp, 'myplugin_cron_event'); // delete database table global $wpdb; $table_name = $wpdb->prefix .'myplugin_table';
$wpdb->query("DROP TABLE IF EXISTS {$table_name}");

// delete pages
$myplugin_pages = get_option('myplugin_pages');
if (is_array($myplugin_pages) && !empty($myplugin_pages)) {
	foreach ($myplugin_pages as $myplugin_page) {
		wp_trash_post($myplugin_page);
	}
}

// delete custom post type posts
$myplugin_cpt_args = array('post_type' => 'myplugin_cpt', 'posts_per_page' => -1);
$myplugin_cpt_posts = get_posts($myplugin_cpt_args);
foreach ($myplugin_cpt_posts as $post) {
	wp_delete_post($post->ID, false);
}

// delete user meta
$users = get_users();
foreach ($users as $user) {
	delete_user_meta($user->ID, 'myplugin_user_meta');
}

// delete post meta
$myplugin_post_args = array('posts_per_page' => -1);
$myplugin_posts = get_posts($myplugin_post_args);
foreach ($myplugin_posts as $post) {
	delete_post_meta($post->ID, 'myplugin_post_meta');
}

Этот код предназначен для добавления в чистый файл uninstall.php.

Немного предостережений и напутствий

Как бы ни был полезен файл uninstall.php, важно соблюдать осторожность при удалении любых данных из БД. К примеру, в некоторых случаях пользователи могут удалить плагин случайно или временно. Поэтому, если пользователь тщательно настраивал параметры для плагина, он может быть очень расстроен, узнав, что изменения были потеряны.

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

if (!get_option('plugin_do_uninstall', false)) exit;

Этот метод позволит предотвратить нежелательную потерю данных. Всегда думайте о пользователях!

Источник: digwp.com

Понравилась статья? Поделиться с друзьями:
Комментарии: 1
  1. Алекс

    Спасибо, полезно. Придется немножко попотеть с пропиской и настройкой кода, но оно того стоит!

Добавить комментарий

Получать новые комментарии по электронной почте. Вы можете подписаться без комментирования.