卸载、激活、停用插件:典型功能和使用方法

时间:2011-08-14 作者:redconservatory

我正在制作WordPress插件。卸载功能中应该包含哪些典型内容?

例如,我应该删除在install函数中创建的所有表吗?

我是否清理选项条目?

还有别的吗?

2 个回复
最合适的回答,由SO网友:kaiser 整理而成

有三个不同的挂钩。它们在以下情况下触发:

  • 卸载
  • 停用
  • 激活
    • 如何在场景中安全触发函数

      以下显示了安全挂接在上述操作中触发的回调函数的正确方法。

      因为您可以在使用

      普通函数、类或外部类,我将显示三种不同的demo plugins 您可以在自己的插件中检查并稍后实现代码。

      重要提示提前

      由于这个主题非常困难,非常详细,有十几个以上的边缘案例,这个答案永远不会完美。随着时间的推移,我会不断改进,所以请定期查看。

      (1) 激活/停用/卸载插件

      • Never, 曾经echo/print 任何事(!)在安装回调期间。这将导致headers already sent 消息和核心将建议停用和删除您的插件。。。不要问:我知道
      • 您将看不到任何视觉输出<但是我添加了exit() 对所有不同回调的声明,以便您能够了解实际发生的情况。只需取消对它们的注释,就可以看到它们在工作__FILE__ != WP_PLUGIN_INSTALL 和(如果不是:中止!)看看是否真的在卸载插件。我建议直接触发on_deactivation() 在开发过程中进行回调,这样您就节省了恢复所有内容所需的时间。至少我是这样做的<首先,我不允许在未加载core时直接访问文件:defined( \'ABSPATH\' ) OR exit;wp_die() 当您遇到错误时,屏幕会询问适当的权限(如果您想再试一次…,当然可以)。当core重定向您、设置当前$GLOBALS[\'wp_list_table\']->current_action();error_scrape 然后检查推荐人check_admin_referer(\'plugin-activation-error_\' . $plugin);, 哪里$plugin$_REQUEST[\'plugin\']. 因此,重定向发生在页面加载量的一半时,您会看到这个有线滚动条,并看到黄色的管理通知/消息框。如果发生这种情况:保持冷静,用一些exit() 以及逐步调试

        <?php
        defined( \'ABSPATH\' ) OR exit;
        /**
         * Plugin Name: (WCM) Activate/Deactivate/Uninstall - Functions
         * Description: Example Plugin to show activation/deactivation/uninstall callbacks for plain functions.
         * 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}" );
        
            # Uncomment the following line to see the function in action
            # 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}" );
        
            # Uncomment the following line to see the function in action
            # exit( var_dump( $_GET ) );
        }
        
        function WCM_Setup_Demo_on_uninstall()
        {
            if ( ! current_user_can( \'activate_plugins\' ) )
                return;
            check_admin_referer( \'bulk-plugins\' );
        
            // Important: Check if the file is the one
            // that was registered during the uninstall hook.
            if ( __FILE__ != WP_UNINSTALL_PLUGIN )
                return;
        
            # Uncomment the following line to see the function in action
            # 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)基于类的/面向对象架构这是当今插件中最常见的例子。

        <?php
        defined( \'ABSPATH\' ) OR exit;
        /**
         * Plugin Name: (WCM) Activate/Deactivate/Uninstall - CLASS
         * Description: Example Plugin to show activation/deactivation/uninstall callbacks for classes/objects.
         * 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}" );
        
                # Uncomment the following line to see the function in action
                # 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}" );
        
                # Uncomment the following line to see the function in action
                # exit( var_dump( $_GET ) );
            }
        
            public static function on_uninstall()
            {
                if ( ! current_user_can( \'activate_plugins\' ) )
                    return;
                check_admin_referer( \'bulk-plugins\' );
        
                // Important: Check if the file is the one
                // that was registered during the uninstall hook.
                if ( __FILE__ != WP_UNINSTALL_PLUGIN )
                    return;
        
                # Uncomment the following line to see the function in action
                # exit( var_dump( $_GET ) );
            }
        
            public function __construct()
            {
                # INIT the plugin: Hook your callbacks
            }
        }
        
        (C)带有外部安装对象的基于类的/面向对象体系结构此场景假定您有一个主插件文件和另一个名为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: Example Plugin
         * 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}" );
        
                # Uncomment the following line to see the function in action
                # 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}" );
        
                # Uncomment the following line to see the function in action
                # exit( var_dump( $_GET ) );
            }
        
            public static function on_uninstall()
            {
                if ( ! current_user_can( \'activate_plugins\' ) )
                    return;
                check_admin_referer( \'bulk-plugins\' );
        
                // Important: Check if the file is the one
                // that was registered during the uninstall hook.
                if ( __FILE__ != WP_UNINSTALL_PLUGIN )
                    return;
        
                # Uncomment the following line to see the function in action
                # exit( var_dump( $_GET ) );
            }
        }
        
        (2)插件更新如果您编写的插件有自己的DB表或选项,可能会出现需要更改或升级的情况。

        遗憾的是,到目前为止,还不可能在插件/主题安装或更新/升级上运行某些东西。很高兴有一个解决方法:将自定义函数挂接到自定义选项上(是的,这很蹩脚,但很有效)。

        function prefix_upgrade_plugin() 
        {
            $v = \'plugin_db_version\';
            $update_option = null;
            // Upgrade to version 2
            if ( 2 !== get_option( $v ) ) 
            {
                if ( 2 < get_option( $v ) )
                {
                    // Callback function must return true on success
                    $update_option = custom_upgrade_cb_fn_v3();
        
                    // Only update option if it was an success
                    if ( $update_option )
                        update_option( $v, 2 );
                }
            }
        
            // Upgrade to version 3, runs just after upgrade to version 2
            if ( 3 !== get_option( $v ) ) 
            {
                // re-run from beginning if previous update failed
                if ( 2 < get_option( $v ) )
                    return prefix_upgrade_plugin();
        
                if ( 3 < get_option( $v ) )
                {
                    // Callback function must return true on success
                    $update_option = custom_upgrade_cb_fn_v3();
        
                    // Only update option if it was an success
                    if ( $update_option )
                        update_option( $v, 3 );
                }
            }
        
            // Return the result from the update cb fn, so we can test for success/fail/error
            if ( $update_option )
                return $update_option;
        
        return false;
        }
        add_action(\'admin_init\', \'prefix_upgrade_plugin\' );
        
        <支持>Source

        这个更新函数不是一个很好/写得不好的示例,但正如所说的那样:这是一个示例,该技术运行良好。将在以后的更新中对此进行改进。

SO网友:fuxia

要测试当前系统所需的功能,如PHP版本或已安装的扩展,您可以使用以下内容:

<?php  # -*- coding: utf-8 -*-
/**
 * Plugin Name: T5 Check Plugin Requirements
 * Description: Test for PHP version and installed extensions
 * Plugin URI:
 * Version:     2013.03.31
 * Author:      Thomas Scholz
 * Author URI:  http://toscho.de
 * Licence:     MIT
 * License URI: http://opensource.org/licenses/MIT
 */

/*
 * Don\'t start on every page, the plugin page is enough.
 */
if ( ! empty ( $GLOBALS[\'pagenow\'] ) && \'plugins.php\' === $GLOBALS[\'pagenow\'] )
    add_action( \'admin_notices\', \'t5_check_admin_notices\', 0 );

/**
 * Test current system for the features the plugin needs.
 *
 * @return array Errors or empty array
 */
function t5_check_plugin_requirements()
{
    $php_min_version = \'5.4\';
    // see 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[] = "Your server is running PHP version $php_current_version but
            this plugin requires at least PHP $php_min_version. Please run an upgrade.";

    foreach ( $extensions as $extension )
        if ( ! extension_loaded( $extension ) )
            $errors[] = "Please install the extension $extension to run this plugin.";

    return $errors;

}

/**
 * Call t5_check_plugin_requirements() and deactivate this plugin if there are error.
 *
 * @wp-hook admin_notices
 * @return  void
 */
function t5_check_admin_notices()
{
    $errors = t5_check_plugin_requirements();

    if ( empty ( $errors ) )
        return;

    // Suppress "Plugin activated" notice.
    unset( $_GET[\'activate\'] );

    // this plugin\'s name
    $name = get_file_data( __FILE__, array ( \'Plugin Name\' ), \'plugin\' );

    printf(
        \'<div class="error"><p>%1$s</p>
        <p><i>%2$s</i> has been deactivated.</p></div>\',
        join( \'</p><p>\', $errors ),
        $name[0]
    );
    deactivate_plugins( plugin_basename( __FILE__ ) );
}
通过检查PHP 5.5进行测试:

enter image description here

结束