स्थापना रद्द करें, सक्रिय करें, एक प्लगइन निष्क्रिय करें: विशिष्ट विशेषताएं और कैसे-करें


100

मैं एक wordpress plugin बना रहा हूँ। अनइंस्टॉल सुविधा में मुझे क्या विशिष्ट चीजें शामिल करनी चाहिए?

उदाहरण के लिए, क्या मुझे स्थापित फ़ंक्शन में बनाई गई किसी भी तालिका को हटाना चाहिए?

क्या मैं अपने विकल्प प्रविष्टियों को साफ कर सकता हूं?

और कुछ?


मैंने इसे काम करने की कोशिश में बहुत समय बर्बाद किया। समस्या यह है कि इनिट हुक, रजिस्टर करने के हुक के अंदर काम नहीं कर रहा है। मुझे लगता है कि एक हुक (एक्शन या फिल्टर) इतनी जल्दी काम नहीं करेगा। नीचे दिए गए लिंक द्वारा नोट्स पढ़ें। codex.wordpress.org/Function_Reference/register_activation_hook यह कहता है: "आपके प्लग-इन हुक के अंदर हुक दर्ज करने में बहुत देर हो चुकी है और यह बहुत देर तक नहीं चलेगा! (यहां तक ​​कि जब यह wp_loaded हुक तक register_dctivation_hook के लिए काम करने लगता है)"
Anton

मैं वही हूं जिसने आपके द्वारा बताए गए कोडेक्स को अपडेट किया है, इसलिए यह ऊपर। उत्तर में माना जाता है। :)
kaiser

जवाबों:


150

तीन अलग-अलग हुक हैं। वे निम्नलिखित मामलों में ट्रिगर करते हैं:

  • स्थापना रद्द करें
  • क्रियाशीलता छोड़ना
  • सक्रियण

परिदृश्यों के दौरान कार्यों को सुरक्षित रूप से कैसे ट्रिगर किया जाए

निम्नलिखित सुरक्षित कॉलबैक फ़ंक्शंस के सही तरीके दिखाता है जो उल्लिखित कार्यों के दौरान ट्रिगर हो जाते हैं।

जैसा कि आप इस कोड का उपयोग करने वाले प्लगइन में कर सकते हैं

  • सादे कार्य,
  • एक वर्ग या
  • एक बाहरी वर्ग,

मैं तीन अलग डेमो प्लगइन्स दिखाऊंगा जिन्हें आप निरीक्षण कर सकते हैं और फिर बाद में कोड को अपने स्वयं के प्लगइन में लागू कर सकते हैं।

महत्वपूर्ण नोट अग्रिम!

जैसा कि यह विषय अत्यंत कठिन और बहुत विस्तृत है और इसमें एक दर्जन + किनारे मामले हैं, यह उत्तर कभी भी सही नहीं होगा। मैं समय के साथ इसमें सुधार करता रहूंगा, इसलिए नियमित आधार पर वापस जांच करें।

(1) सक्रिय करें / निष्क्रिय करें / प्लगइन्स अनइंस्टॉल करें।

प्लगइन सेटअप कॉलबैक को कोर द्वारा ट्रिगर किया जाता है और आपको इस बात पर कोई प्रभाव नहीं पड़ता है कि कोर यह कैसे करता है। ध्यान रखने योग्य कुछ बातें हैं:

  • 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()और चरण-दर-चरण डीबगिंग के साथ त्रुटि की खोज करें ।

(ए) सादा कार्य प्लगइन

याद रखें कि फ़ंक्शन परिभाषा से पहले कॉलबैक को हुक करने पर यह काम नहीं कर सकता है।

<?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' );

(बी) एक वर्ग आधारित / ओओपी वास्तुकला

आजकल के प्लगइन्स में यह सबसे आम उदाहरण है।

<?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
    }
}

(सी) बाहरी सेटअप ऑब्जेक्ट के साथ एक वर्ग आधारित / ओओपी वास्तुकला

इस परिदृश्य मानता है कि आप एक मुख्य प्लगइन फ़ाइल और एक दूसरे नाम की फ़ाइल मिला 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' );

स्रोत

यह अद्यतन कार्य एक अच्छा-अच्छा / अच्छी तरह से लिखा उदाहरण नहीं है, लेकिन जैसा कि कहा गया है: यह एक उदाहरण है और तकनीक अच्छी तरह से काम करती है। बाद में अद्यतन के साथ सुधार होगा।


1
यह महान है लेकिन मैं वास्तव में जानना चाहता हूं कि वे चीजें हैं जो मुझे अपने निष्क्रियकरण विधि में शामिल करनी चाहिए ... उदाहरण के लिए, क्या मुझे डेटाबेस में अपनी तालिकाओं को हटा देना चाहिए या उपयोगकर्ता द्वारा उनके दिमाग को बदलने और प्लगइन को फिर से सक्रिय करने की स्थिति में उन्हें छोड़ देना चाहिए। ?
redconservatory

1
विज्ञापन "BUT": मैंने उल्लेख किया कि 3 विधियाँ हैं। सक्रियण के लिए एक, अस्थायी निष्क्रियता के लिए एक और अनस्टाल के लिए एक है। Imho "अनइंस्टॉल" कहता है "मुझे हटाओ और मैंने जो कुछ भी किया है", जबकि "निष्क्रिय" एक अस्थायी स्थिति है और इसे फिर से किया जा सकता है। लेकिन: अद्यतन देखें। मैंने आपके Q + के बारे में टिप्पणियां जोड़ीं और इसे कुछ विकास सिफारिशों के साथ बढ़ाया।
कैसर

3
आह मैं अब समझ गया। बस एक सवाल, अनइंस्टॉल कब किया जाता है? जब फ़ाइलें हटा दी जाती हैं ??
redconservatory

1
@aendrew वे केवल साइड में उपयोग किए जाते हैं check_admin_referer()। उन्हें स्वच्छता प्राप्त करने की आवश्यकता नहीं है क्योंकि कोर स्वयं ऐसा नहीं करता है और वैसे भी इसकी तुलना असमान $_REQUESTमूल्यों के खिलाफ करेगा । लेकिन अगर वे उस वजह से छोटी लड़कियों की तरह रोने लगती हैं, तो बस इसका इस्तेमाल करें filter_var()या उस esc_attr()पर।
kaiser

2
आप कॉलबैक फ़ंक्शन में WP_UNINSTALL_PLUGIN लिए जाँच करनी चाहिए नहीं तो wp_register_uninstall_hook का उपयोग कर, केवल यदि आप uninstall.php का उपयोग
पॉल

17

पीएचपी संस्करण या इंस्टॉल किए गए एक्सटेंशन जैसे आवश्यक उपलब्धि के लिए वर्तमान प्रणाली का परीक्षण करने के लिए आप कुछ इस तरह का उपयोग कर सकते हैं:

<?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 के लिए जाँच के साथ टेस्ट करें:

यहाँ छवि विवरण दर्ज करें


उलझन में स्पर्श करें, इसलिए मूल रूप से register_activation_hookयहां कॉल नहीं है - इसका उपयोग क्यों नहीं करें? यह आग पहले या बाद में भी बुझेगी register_activation_hookऔर register_activation_hookऊपर से नहीं गुजरेगी तो भी क्या आग लगेगी ?
ओरियन्रुश

यह केवल प्लगइन पेज पर सक्रियण हुक के बाद चलता है।
फॉक्सिया

मैं देख रहा हूँ - लेकिन यदि प्लगइन प्लगइन पेज के बाहर सक्रिय है (थीम निर्भरता के हिस्से के रूप में कहें) तो आपके चेक नहीं छोड़ दिए जाएंगे? इसलिए मैंने add_action( 'admin_notices', 't5_check_admin_notices', 0 );एक सक्रियण हुक में जाने की कोशिश की और प्लगइन बिना जांच किए सक्रिय हो गया। । ।
ओरियन्रुश

@kaiser ने बताया है कि सक्रियण हुक कैसे काम करता है, मैं एक विकल्प दिखाना चाहता था। यदि प्लगइन प्रति प्लगइन पेज सक्रिय नहीं है, तो एक घातक त्रुटि हो सकती है, हाँ। यह दृष्टिकोण गंभीर पुन: लिखने के बिना सक्रियण हुक पर काम नहीं कर सकता है, क्योंकि वह हुक बाद में आग लगाता है admin_notices
फुकिया

वास्तव में सिर्फ आसान तरीके से ठोकर खाई: stackoverflow.com/a/13927297/362445
orionrush
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.