Удаление, активация и деактивация плагина: типичные функции и инструкции

15 авг. 2011 г., 02:21:36
Просмотры: 62.1K
Голосов: 110

Я разрабатываю плагин для WordPress. Какие типичные функции следует включить в процесс удаления?

Например, нужно ли удалять таблицы, которые я создал при установке?

Следует ли очищать записи опций?

Что-нибудь еще?

2
Комментарии

Я потратил так много времени, пытаясь заставить это работать. Проблема в том, что хук init не работает внутри регистрирующих хуков. Я предполагаю, что ни один хук (экшен или фильтр) не будет работать так рано. Прочитайте заметки по ссылке ниже. http://codex.wordpress.org/Function_Reference/register_activation_hook Там говорится: "Регистрация хука внутри хука plugins_loaded происходит слишком поздно, и он не сработает! (Даже если кажется, что это работает для register_deactivation_hook до хука wp_loaded.)"

Anton Anton
9 нояб. 2011 г. 14:43:50

Я тот, кто обновил кодекс до упомянутого вами, так что это учтено в ответе выше ↑. :)

kaiser kaiser
28 февр. 2012 г. 02:00:19
Все ответы на вопрос 2
23
165

Существует три различных хука. Они срабатывают в следующих случаях:

  • Удаление
  • Деактивация
  • Активация

Как безопасно запускать функции в этих сценариях

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

Поскольку вы можете использовать этот код в плагине, который использует:

  • обычные функции,
  • класс или
  • внешний класс,

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

Важное замечание заранее!

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

(1) Активация/Деактивация/Удаление плагинов.

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

  • Никогда не выводите ничего через echo/print во время функций обратного вызова настройки. Это приведет к сообщению headers already sent, и ядро порекомендует деактивировать и удалить ваш плагин... не спрашивайте: я знаю...
  • Вы не увидите никакого визуального вывода. Но я добавил операторы exit() во все различные функции обратного вызова, чтобы вы могли понять, что действительно происходит. Просто раскомментируйте их, чтобы увидеть работу.
  • Очень важно проверять, что __FILE__ != WP_PLUGIN_INSTALL и (если нет: прерывать выполнение!), чтобы убедиться, что плагин действительно удаляется. Я рекомендую просто запускать функции on_deactivation() во время разработки, чтобы сэкономить время на восстановление всего. По крайней мере, я так делаю.
  • Я также добавляю некоторые меры безопасности. Некоторые из них уже выполняются ядром, но, как говорится, Лучше перестраховаться, чем потом жалеть!.
    • Сначала я запрещаю прямой доступ к файлу, если ядро не загружено: defined( 'ABSPATH' ) OR exit;
    • Затем я проверяю, имеет ли текущий пользователь права на выполнение этой задачи.
    • Последней задачей я проверяю реферер. Примечание: Могут быть неожиданные результаты с экраном wp_die(), запрашивающим соответствующие права (и хотите ли вы попробовать снова... ну конечно), если у вас произошла ошибка. Это происходит, потому что ядро перенаправляет вас, устанавливает текущее значение $GLOBALS['wp_list_table']->current_action(); в error_scrape, а затем проверяет реферер для check_admin_referer('plugin-activation-error_' . $plugin);, где $plugin — это $_REQUEST['plugin']. Так что перенаправление происходит на полпути загрузки страницы, и вы получаете эту странную полосу прокрутки и экран смерти внутри желтого уведомления/сообщения администратора. Если это произойдет: сохраняйте спокойствие и просто ищите ошибку с помощью exit() и пошаговой отладки.

(A) Плагин с обычными функциями

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

<?php
defined( 'ABSPATH' ) OR exit;
/**
 * Plugin Name: (WCM) Activate/Deactivate/Uninstall - Functions
 * Description: Пример плагина, демонстрирующий функции обратного вызова для активации/деактивации/удаления с обычными функциями.
 * Author:      Franz Josef Kaiser/wecodemore
 * Author URL:  http://unserkaiser.com
 * Plugin URL:  http://wordpress.stackexchange.com/questions/25910/uninstall-activate-deactivate-a-plugin-typical-features-how-to/25979#25979
 */

function WCM_Setup_Demo_on_activation()
{
    if ( ! current_user_can( 'activate_plugins' ) )
        return;
    $plugin = isset( $_REQUEST['plugin'] ) ? $_REQUEST['plugin'] : '';
    check_admin_referer( "activate-plugin_{$plugin}" );

    # Раскомментируйте следующую строку, чтобы увидеть функцию в действии
    # exit( var_dump( $_GET ) );
}

function WCM_Setup_Demo_on_deactivation()
{
    if ( ! current_user_can( 'activate_plugins' ) )
        return;
    $plugin = isset( $_REQUEST['plugin'] ) ? $_REQUEST['plugin'] : '';
    check_admin_referer( "deactivate-plugin_{$plugin}" );

    # Раскомментируйте следующую строку, чтобы увидеть функцию в действии
    # exit( var_dump( $_GET ) );
}

function WCM_Setup_Demo_on_uninstall()
{
    if ( ! current_user_can( 'activate_plugins' ) )
        return;
    check_admin_referer( 'bulk-plugins' );

    // Важно: Проверьте, что файл тот же,
    // который был зарегистрирован во время хука удаления.
    if ( __FILE__ != WP_UNINSTALL_PLUGIN )
        return;

    # Раскомментируйте следующую строку, чтобы увидеть функцию в действии
    # exit( var_dump( $_GET ) );
}

register_activation_hook(   __FILE__, 'WCM_Setup_Demo_on_activation' );
register_deactivation_hook( __FILE__, 'WCM_Setup_Demo_on_deactivation' );
register_uninstall_hook(    __FILE__, 'WCM_Setup_Demo_on_uninstall' );

(B) Архитектура на основе классов/OOP

Это наиболее распространенный пример в современных плагинах.

<?php
defined( 'ABSPATH' ) OR exit;
/**
 * Plugin Name: (WCM) Activate/Deactivate/Uninstall - CLASS
 * Description: Пример плагина, демонстрирующий функции обратного вызова для активации/деактивации/удаления в классах/объектах.
 * Author:      Franz Josef Kaiser/wecodemore
 * Author URL:  http://unserkaiser.com
 * Plugin URL:  http://wordpress.stackexchange.com/questions/25910/uninstall-activate-deactivate-a-plugin-typical-features-how-to/25979#25979
 */

register_activation_hook(   __FILE__, array( 'WCM_Setup_Demo_Class', 'on_activation' ) );
register_deactivation_hook( __FILE__, array( 'WCM_Setup_Demo_Class', 'on_deactivation' ) );
register_uninstall_hook(    __FILE__, array( 'WCM_Setup_Demo_Class', 'on_uninstall' ) );

add_action( 'plugins_loaded', array( 'WCM_Setup_Demo_Class', 'init' ) );
class WCM_Setup_Demo_Class
{
    protected static $instance;

    public static function init()
    {
        is_null( self::$instance ) AND self::$instance = new self;
        return self::$instance;
    }

    public static function on_activation()
    {
        if ( ! current_user_can( 'activate_plugins' ) )
            return;
        $plugin = isset( $_REQUEST['plugin'] ) ? $_REQUEST['plugin'] : '';
        check_admin_referer( "activate-plugin_{$plugin}" );

        # Раскомментируйте следующую строку, чтобы увидеть функцию в действии
        # exit( var_dump( $_GET ) );
    }

    public static function on_deactivation()
    {
        if ( ! current_user_can( 'activate_plugins' ) )
            return;
        $plugin = isset( $_REQUEST['plugin'] ) ? $_REQUEST['plugin'] : '';
        check_admin_referer( "deactivate-plugin_{$plugin}" );

        # Раскомментируйте следующую строку, чтобы увидеть функцию в действии
        # exit( var_dump( $_GET ) );
    }

    public static function on_uninstall()
    {
        if ( ! current_user_can( 'activate_plugins' ) )
            return;
        check_admin_referer( 'bulk-plugins' );

        // Важно: Проверьте, что файл тот же,
        // который был зарегистрирован во время хука удаления.
        if ( __FILE__ != WP_UNINSTALL_PLUGIN )
            return;

        # Раскомментируйте следующую строку, чтобы увидеть функцию в действии
        # exit( var_dump( $_GET ) );
    }

    public function __construct()
    {
        # Инициализация плагина: Подключите ваши функции обратного вызова
    }
}

(C) Архитектура на основе классов/OOP с внешним объектом настройки

Этот сценарий предполагает, что у вас есть главный файл плагина и второй файл с именем setup.php в подкаталоге плагина с именем inc: ~/wp-content/plugins/your_plugin/inc/setup.php. Это будет работать даже если папка плагина находится вне стандартной структуры WP, если папка контента переименована или если ваш файл настройки имеет другое имя. Только папка inc должна иметь то же имя и расположение относительно корневой директории плагина.

Примечание: Вы можете просто взять три функции register_*_hook() и классы и вставить их в свой плагин.

Главный файл плагина:

<?php
defined( 'ABSPATH' ) OR exit;
/**
 * Plugin Name: (WCM) Activate/Deactivate/Uninstall - FILE/CLASS
 * Description: Пример плагина
 * Author:      Franz Josef Kaiser/wecodemore
 * Author URL:  http://unserkaiser.com
 * Plugin URL:  http://wordpress.stackexchange.com/questions/25910/uninstall-activate-deactivate-a-plugin-typical-features-how-to/25979#25979
 */

register_activation_hook(   __FILE__, array( 'WCM_Setup_Demo_File_Inc', 'on_activation' ) );
register_deactivation_hook( __FILE__, array( 'WCM_Setup_Demo_File_Inc', 'on_deactivation' ) );
register_uninstall_hook(    __FILE__, array( 'WCM_Setup_Demo_File_Inc', 'on_uninstall' ) );

add_action( 'plugins_loaded', array( 'WCM_Setup_Demo_File', 'init' ) );
class WCM_Setup_Demo_File
{
    protected static $instance;

    public static function init()
    {
        is_null( self::$instance ) AND self::$instance = new self;
        return self::$instance;
    }

    public function __construct()
    {
        add_action( current_filter(), array( $this, 'load_files' ), 30 );
    }

    public function load_files()
    {
        foreach ( glob( plugin_dir_path( __FILE__ ).'inc/*.php' ) as $file )
            include_once $file;
    }
}

Файл настройки:

<?php
defined( 'ABSPATH' ) OR exit;

class WCM_Setup_Demo_File_Inc
{
    public static function on_activation()
    {
        if ( ! current_user_can( 'activate_plugins' ) )
            return;
        $plugin = isset( $_REQUEST['plugin'] ) ? $_REQUEST['plugin'] : '';
        check_admin_referer( "activate-plugin_{$plugin}" );

        # Раскомментируйте следующую строку, чтобы увидеть функцию в действии
        # exit( var_dump( $_GET ) );
    }

    public static function on_deactivation()
    {
        if ( ! current_user_can( 'activate_plugins' ) )
            return;
        $plugin = isset( $_REQUEST['plugin'] ) ? $_REQUEST['plugin'] : '';
        check_admin_referer( "deactivate-plugin_{$plugin}" );

        # Раскомментируйте следующую строку, чтобы увидеть функцию в действии
        # exit( var_dump( $_GET ) );
    }

    public static function on_uninstall()
    {
        if ( ! current_user_can( 'activate_plugins' ) )
            return;
        check_admin_referer( 'bulk-plugins' );

        // Важно: Проверьте, что файл тот же,
        // который был зарегистрирован во время хука удаления.
        if ( __FILE__ != WP_UNINSTALL_PLUGIN )
            return;

        # Раскомментируйте следующую строку, чтобы увидеть функцию в действии
        # exit( var_dump( $_GET ) );
    }
}

(2) Обновления плагинов

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

К сожалению, пока нет возможности выполнить что-то при установке или обновлении плагина/темы. К счастью, есть обходной путь: подключите пользовательскую функцию к пользовательской опции (да, это некрасиво — но работает).

function prefix_upgrade_plugin() 
{
    $v = 'plugin_db_version';
    $update_option = null;
    // Обновление до версии 2
    if ( 2 !== get_option( $v ) ) 
    {
        if ( 2 < get_option( $v ) )
        {
            // Функция обратного вызова должна вернуть true при успехе
            $update_option = custom_upgrade_cb_fn_v3();

            // Обновляем опцию только в случае успеха
            if ( $update_option )
                update_option( $v, 2 );
        }
    }

    // Обновление до версии 3, выполняется сразу после обновления до версии 2
    if ( 3 !== get_option( $v ) ) 
    {
        // Повторно запускаем с начала, если предыдущее обновление не удалось
        if ( 2 < get_option( $v ) )
            return prefix_upgrade_plugin();

        if ( 3 < get_option( $v ) )
        {
            // Функция обратного вызова должна вернуть true при успехе
            $update_option = custom_upgrade_cb_fn_v3();

            // Обновляем опцию только в случае успеха
            if ( $update_option )
                update_option( $v, 3 );
        }
    }

    // Возвращаем результат функции обновления, чтобы можно было проверить успех/неудачу/ошибку
    if ( $update_option )
        return $update_option;

return false;
}
add_action('admin_init', 'prefix_upgrade_plugin' );

Источник

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

15 авг. 2011 г. 21:18:05
Комментарии

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

redconservatory redconservatory
16 авг. 2011 г. 00:25:01

Насчёт "НО": Я упомянул, что есть 3 метода. Один для активации, один для временной деактивации и один для удаления. По моему мнению, "uninstall" означает "Удали меня и всё, что я сделал", в то время как "deactivate" — это временное состояние, которое может быть отменено. Но: Смотрите обновление. Я добавил комментарии по вашему вопросу + дополнил его некоторыми рекомендациями по разработке.

kaiser kaiser
16 авг. 2011 г. 00:55:23

А, теперь я понимаю. Просто вопрос: когда вызывается uninstalled? Когда файлы удаляются??

redconservatory redconservatory
17 авг. 2011 г. 01:40:41

Хм. Хороший вопрос. plugin.php — это файл, который содержит register_uninstall_hook и загружается вместе с ранними файлами в wp-settings.php (это основной файл, на который всегда стоит смотреть). Я обновил вопрос с docblocks из ядра.

kaiser kaiser
17 авг. 2011 г. 11:14:20

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

kaiser kaiser
17 авг. 2011 г. 11:20:25

Для будущих читателей: Я удалил docBlocks, так как они были из WP 3.2.1. Вы всё ещё можете просмотреть правки этого вопроса, чтобы увидеть основные функции.

kaiser kaiser
7 янв. 2012 г. 19:55:01

Но я всё равно не понимаю, когда происходит "удаление". При удалении плагина? При деактивации?

onetrickpony onetrickpony
9 янв. 2012 г. 21:09:05

@OneTrickPony Будет вызвано, когда пользователь нажимает на ссылку удаления, которая запускает процесс самостоятельного удаления плагина. Я обновил ответ.

kaiser kaiser
9 янв. 2012 г. 21:48:51

Я не видел такой ссылки. Предполагается, что она должна отображаться рядом с (де)активацией/редактированием/удалением?

onetrickpony onetrickpony
10 янв. 2012 г. 23:36:26

@OneTrickPony Хорошо, я не могу больше обновлять, так как наткнулся на вики сообщества, но ответ на вопрос "что происходит при удалении" звучит так: Функция register_uninstall_hook() добавляет файл удаления и callback-функцию в опцию 'uninstall_plugins' в таблице Options базы данных. Затем это вызывается через функцию uninstall_plugin($name), которая вызывается функцией delete_plugin($array_of_plugins). Последняя функция запускается в зависимости от действия, установленного в /wp-admin/plugin.php, когда (в switch) case равен 'delete-selected'. Это означает, что установлен $_REQUEST['verify-delete']. Понятно? :)

kaiser kaiser
10 янв. 2012 г. 23:51:55

Подведем итог: В админке /wp-admin/plugin.php » isset( $_REQUEST['verify-delete'] ) » delete_plugin($array_of_plugins) » uninstall_plugin($name) » update_option('uninstall_plugins',$array) » define('WP_UNINSTALL_PLUGIN') И include WP_PLUGIN_DIR.'/'.dirname($file).'/uninstall.php'

kaiser kaiser
10 янв. 2012 г. 23:55:41

WP_UNINSTALL_PLUGIN определяется только если в папке плагина найден файл uninstall.php. Если вы используете метод с хуком удаления, а не метод с uninstall.php, константа не будет определена. Это видно при изучении исходного кода. На момент написания этого ответа текущей была версия: http://core.trac.wordpress.org/browser/tags/3.2.1/wp-admin/includes/plugin.php#L804

bcworkz bcworkz
18 нояб. 2013 г. 00:51:28

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

kaiser kaiser
18 нояб. 2013 г. 01:30:59

Примечание: Я изучил это и оставил комментарий к пул-реквесту, который я сделал. Обновления будут позже.

kaiser kaiser
18 нояб. 2013 г. 01:54:45

Я проверяю код, основанный на классовом подходе, и стандарты кода VIP вызывают у меня проблемы с этими глобальными переменными $_REQUEST, утверждая, что они не санированы. Есть идеи, как это обойти?

aendra aendra
14 авг. 2014 г. 03:58:26

@aendrew Они используются только в check_admin_referer(). Их не нужно санировать, потому что ядро само этого не делает и в любом случае сравнивает с несанированными значениями $_REQUEST. Но если они начнут ныть как маленькие девочки из-за этого, просто используйте filter_var() или esc_attr().

kaiser kaiser
14 авг. 2014 г. 04:09:14

@kaiser Так я и думал. На ваш ответ даже ссылаются в официальной документации WP, так что, вероятно, это не проблема. Спасибо, что ответили!

aendra aendra
17 авг. 2014 г. 05:26:48

@kaiser Хотя, просто к сведению — phpcs всё равно выдаёт ту же ошибку, даже если обернуть $_REQUEST в filter_var() или esc_attr(). Похоже, это скорее проблема самого phpcs, чем что-то ещё...

aendra aendra
17 авг. 2014 г. 05:35:49

Вам не следует проверять WP_UNINSTALL_PLUGIN в функции обратного вызова, если используете wp_register_uninstall_hook, это нужно делать только при использовании uninstall.php

paul paul
21 янв. 2015 г. 21:13:41

Я не на 100% уверен, что вариант (c) работает в версии 4.2.4 (и возможно в более ранних). В моих тестах метод on_activation() никогда не вызывался. Вместо этого в логах появлялось PHP-предупреждение: call_user_func_array() expects parameter 1 to be a valid callback, class 'WCM_Setup_Demo_File_Inc' not found in /path/to/wp-includes/plugin.php on line 496

Это выглядит логично, потому что включаемый файл не подключается до тех пор, пока плагин не станет активным (так как файл подключается в __construct(), который выполняется только на хуке plugins_loaded

RichardTape RichardTape
6 авг. 2015 г. 21:34:22

@kaiser В этом ответе вы предлагаете проверять __FILE__ != WP_UNINSTALL_PLUGIN, однако на самом деле достаточно проверить, определена ли константа. Вам не нужно проверять её значение, и более того, оно не всегда будет корректным.

J.D. J.D.
29 апр. 2016 г. 00:18:58

@J.D. Я не знал об этой ошибке при массовом удалении. Причина, по которой я проверяю, проста: убедиться, что правильный плагин вызывает это. После 5 лет я уже не совсем уверен в своих изначальных намерениях. Что касается вашей ссылки на Trac: возможно, вам стоит пересмотреть проблему, с которой вы столкнулись: массовое удаление не работает. Понижение константы может быть не лучшим решением. На мой взгляд, все равно должен быть способ определить, какой именно плагин удаляется.

kaiser kaiser
29 апр. 2016 г. 05:28:54

Код удаления содержит 2 ошибки. 1. Как говорит @paul, WP_UNINSTALL_PLUGIN не определена. 2. И check_admin_referer( 'bulk-plugins' ) завершается неудачей, блокируя удаление.

"Лучше перестраховаться" звучит хорошо, но изменения в ядре WP могут вызывать ошибки.

Использование register_uninstall_hook() вместо uninstall.php означает, что нужно быть осторожным, в том числе в любом __construct(). Если все статично, возможно, проблем не будет.

В комментариях упоминался https://tommcfarlin.com/wordpress-plugin-boilerplate/ Это более современное решение, и в нем нет current_user_can, check_admin_referer или register_uninstall_hook.

kitchin kitchin
21 мар. 2018 г. 15:51:05
Показать остальные 18 комментариев
6
19

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

<?php  # -*- coding: utf-8 -*-
/**
 * Plugin Name: T5 Проверка требований плагина
 * Description: Проверка версии PHP и установленных расширений
 * Plugin URI:
 * Version:     2013.03.31
 * Author:      Fuxia Scholz
 * Licence:     MIT
 * License URI: http://opensource.org/licenses/MIT
 */

/*
 * Не запускать на каждой странице, достаточно страницы плагинов.
 */
if ( ! empty ( $GLOBALS['pagenow'] ) && 'plugins.php' === $GLOBALS['pagenow'] )
    add_action( 'admin_notices', 't5_check_admin_notices', 0 );

/**
 * Проверяет текущую систему на соответствие требованиям плагина.
 *
 * @return array Ошибки или пустой массив
 */
function t5_check_plugin_requirements()
{
    $php_min_version = '5.4';
    // см. http://www.php.net/manual/en/extensions.alphabetical.php
    $extensions = array (
        'iconv',
        'mbstring',
        'id3'
    );
    $errors = array ();

    $php_current_version = phpversion();

    if ( version_compare( $php_min_version, $php_current_version, '>' ) )
        $errors[] = "Ваш сервер использует PHP версии $php_current_version, но
            для работы этого плагина требуется как минимум PHP $php_min_version. Пожалуйста, обновите PHP.";

    foreach ( $extensions as $extension )
        if ( ! extension_loaded( $extension ) )
            $errors[] = "Для работы этого плагина необходимо установить расширение $extension.";

    return $errors;

}

/**
 * Вызывает t5_check_plugin_requirements() и деактивирует плагин при наличии ошибок.
 *
 * @wp-hook admin_notices
 * @return  void
 */
function t5_check_admin_notices()
{
    $errors = t5_check_plugin_requirements();

    if ( empty ( $errors ) )
        return;

    // Подавить уведомление "Плагин активирован".
    unset( $_GET['activate'] );

    // Название этого плагина
    $name = get_file_data( __FILE__, array ( 'Plugin Name' ), 'plugin' );

    printf(
        '<div class="error"><p>%1$s</p>
        <p><i>%2$s</i> был деактивирован.</p></div>',
        join( '</p><p>', $errors ),
        $name[0]
    );
    deactivate_plugins( plugin_basename( __FILE__ ) );
}

Проверка для PHP 5.5:

Проверка требований плагина

9 апр. 2013 г. 21:45:04
Комментарии

Немного запутался, то есть здесь нет вызова register_activation_hook — почему бы его не использовать? Также сработает ли это до или после register_activation_hook и будет ли register_activation_hook срабатывать, даже если проверка выше не пройдёт?

orionrush orionrush
31 июл. 2013 г. 15:52:24

Он срабатывает после хука активации только на странице плагина.

fuxia fuxia
31 июл. 2013 г. 15:54:36

Понял — но если плагин активируется вне страницы плагина (например, как часть зависимостей темы), то ваши проверки будут пропущены, верно? Я попробовал переместить add_action( 'admin_notices', 't5_check_admin_notices', 0 ); в хук активации, и плагин активируется без выполнения проверок...

orionrush orionrush
31 июл. 2013 г. 16:30:41

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

fuxia fuxia
31 июл. 2013 г. 16:46:13

Собственно, только что наткнулся на простой способ: http://stackoverflow.com/a/13927297/362445

orionrush orionrush
31 июл. 2013 г. 16:50:02

Думаю, это должно сработать: `register_activation_hook( FILE, function() { add_option('Activated_Plugin','Plugin-Slug'); });

add_action('admin_init', 'load_plugin'); function load_plugin() { if ( ! current_user_can( 'activate_plugins' ) ) return; if(is_admin()&&get_option('Activated_Plugin')=='Plugin-Slug') { delete_option('Activated_Plugin'); add_action( 'admin_notices', 't5_check_admin_notices', 0 ); } }`

orionrush orionrush
31 июл. 2013 г. 16:50:33
Показать остальные 1 комментариев