मैं फंक्शन की जगह, प्लगइन के वर्ग के अंदर, फ़ंक्शन में कैसे घोषित कर सकता हूं।


9

मैं एक प्लगइन में एक फ़ंक्शन को संशोधित करना चाहता हूं। यह इस तरह से प्लगइन की मुख्य फ़ाइल में घोषित किया गया है:

class WCPGSK_Main {
  ...
  public function wcpgsk_email_after_order_table($order) {
    ...
  }
}

इस तरह से वहाँ से बुलाया जोड़ें:

add_action( 'woocommerce_email_after_order_table', array($this, 'wcpgsk_email_after_order_table') );

मुझे लगता है कि यह कार्य करने के लिए संभव हो सकता है अगर कार्यों में कक्षा के लिए एक पहुँच थी। तब मैं कुछ इस तरह लिख पाऊंगा:

$wcpgsk = new WCPGSK_Main;

remove_action( 'woocommerce_email_after_order_table', array($wcpgsk, 'wcpgsk_email_after_order_table') );

function customized_wcpgsk_email_after_order_table($order) {
  ...
}
add_action( 'woocommerce_email_after_order_table', array($wcpgsk, 'customized_wcpgsk_email_after_order_table') );

मेरी सोच थी कि टास्क में क्लास का एक्सेस मिल जाए।

require_once('/wp-content/plugins/woocommerce-poor-guys-swiss-knife/woocommerce-poor-guys-swiss-knife.php');
$wcpgsk = new WCPGSK_Main;
...

लेकिन यह काम नहीं करता है क्योंकि प्लगइन की फ़ाइल शामिल है जब प्लगइन वर्डप्रेस में इनिशियलाइज़ हो रहा है, मुझे लगता है।

क्या प्लगइन की फ़ाइलों को छूने के बिना फ़ंक्शन को फिर से लिखने का एक तरीका है?

जवाबों:


8

यह काम करना चाहिए:

add_action( 'woocommerce_init', 'remove_wcpgsk_email_order_table' );
function remove_wcpgsk_email_order_table() {

    global $wcpgsk;
    remove_action( 'woocommerce_email_after_order_table', array( $wcpgsk, 'wcpgsk_email_after_order_table' ) );

}


हां, मैं चूक गया हूं, इस प्लगइन का एक चर है जो वैश्विक रूप से एक्सेस किया जा सकता है। मेरी मूर्खता। आपके उत्तर के लिए धन्यवाद, यह इस विशेष मामले में काम कर रहा है (इस प्लगइन के लिए)।
इगोर स्कोल्डिन

एलेक्स ओल्डर उस जगह से जुड़ा हुआ है जो बताता है कि उसका जवाब क्यों काम करता है। Remove_action स्थिर या आवृत्ति वर्ग के साथ एक सरणी को स्वीकार करता है जिसके भीतर आप एक विधि निकालना चाहते हैं।
निंजा ०।

11

यदि आपका प्लगइन इस तरह पंजीकृत है:

class Test_Class_Parent {
  function __construct() {
    add_action('wp_head',array($this,'test_method'));
  }

  function test_method() {
    echo 'Echoed from the parent';
  }
}
$p = new Test_Class_Parent();

तब आपको वैश्विक एक्सेस करके फ़िल्टर को निकालने में सक्षम होना चाहिए:

class Test_Class_Child extends Test_Class_Parent {
  function __construct() {
    $this->unregister_parent_hook();
    add_action('wp_head',array($this,'test_method'));
  }

  function unregister_parent_hook() {
    global $p;
    remove_action('wp_head',array($p,'test_method'));
  }

  function test_method() {
    echo 'Echoed from the child';
  }
}
$c = new Test_Class_Child();

अन्यथा, आपको $wp_filter globalपंजीकरण कुंजी के लिए क्रॉल करना होगा :

class Test_Class_Child extends Test_Class_Parent {
  function __construct() {
    $this->unregister_parent_hook();
    add_action('wp_head',array($this,'test_method'));
  }

  function unregister_parent_hook() {
    global $wp_filter;
    if (!empty($wp_filter['wp_head'])) {
      foreach($wp_filter['wp_head'] as $cb) {
        foreach ($cb as $k => $v) {
          if (
            isset($v['function'])
            && is_a($v['function'][0],'Test_Class_Parent')
            && isset($v['function'][1])
            && 'test_method' == $v['function'][1]
          ) {
            remove_action('wp_head',$k);
          }
        }
      }
    }
  }

  function test_method() {
    echo 'Echoed from the child';
  }
}
$c = new Test_Class_Child();

यह संसाधन गहन है और वास्तव में ऐसा नहीं किया जाना चाहिए जब तक कि आपके पास कोई अन्य विकल्प न हो।


2
यह स्वीकृत उत्तर होना चाहिए। यह आमतौर पर उपयोगी है, और केवल ओपी के विशिष्ट मामले तक सीमित नहीं है।
डेविड आर।

1

वह प्लगइन इसके init फ़ंक्शन को प्लग-इन करता है wcpgsk_init(), इसलिए इसे ओवरराइड करने का एक और तरीका यह है कि इसे पहले एक मस्ट-यूज़ प्लगइन में परिभाषित किया जाए (क्योंकि यह आपके विषय के "functions.php" में बहुत देर हो चुकी है)। इसलिए आप "wp-content / mu-plugins / functions.php" में अपना ओवरराइड डाल सकते हैं।

function wcpgsk_init() {
    global $wcpgsk, $wcpgsk_about, $wcpgsk_options, $wcpgsk_session, $wcpgsk_woocommerce_active;    
    //only continue loading
    if ( $wcpgsk_woocommerce_active && version_compare( WOOCOMMERCE_VERSION, "2.0" ) >= 0 ) {
        $FILE = WP_PLUGIN_DIR . '/woocommerce-poor-guys-swiss-knife/woocommerce-poor-guys-swiss-knife.php'; // Fake __FILE__
        $dirname = dirname( $FILE ) . '/';
        $wcpgsk_options = get_option('wcpgsk_settings', true);
        require_once( $dirname . 'classes/woocommerce-poor-guys-swiss-knife.php' );
        require_once( $dirname . 'classes/woocommerce-poor-guys-swiss-knife-about.php' );   
        require_once( $dirname . 'wcpgsk-af.php' );

        if ( !is_admin() ) :
            add_action( 'plugins_loaded', 'wcpgsk_load_wcsession_helper' );
        endif;

        // Your override.
        class My_WCPGSK_Main extends WCPGSK_Main {
            public function wcpgsk_email_after_order_table($order) {
                echo "O la la";
            }
        }
        define( 'WCRGSK_DOMAIN', WCPGSK_DOMAIN ); // Fix typo! (WooCommerce Rich Guys Swiss Knife?)

        //load into our global
        $wcpgsk = new My_WCPGSK_Main( $FILE );
        $wcpgsk->version = '2.2.4'; 
        $wcpgsk->wcpgsk_hook_woocommerce_filters();


    } elseif ( version_compare( WOOCOMMERCE_VERSION, "2.0" ) < 0 ) {
        add_action( 'admin_notices', 'wcpgsk_woocommerce_version_message', 0 ) ;    
        return;
    } else {
        return;
    }
}

लेकिन इसे ओवरराइड करने का एक और बेहतर तरीका यह है कि इसे स्थापित करें runkit( https://github.com/padraic/runkit ) और फिर इसे सीधे अपने विषय के "functions.php" में बदलें।

add_action( 'init', function () {
    $code = <<<'EOD'
echo "O la la";
EOD;
    runkit_method_redefine(
        'WCPGSK_Main',
        'wcpgsk_email_after_order_table',
        '$order',
        $code,
        RUNKIT_ACC_PUBLIC
    );
} );

(यह एक मजाक है, btw।)

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.