Plugin.php içinde bir eklenti sınıfında bildirilen bir işlevi nasıl değiştiririm?


9

Bir eklenti bir işlevi değiştirmek istiyorum. Eklentinin ana dosyasında şöyle bildirilir:

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

Oradan böyle ekle ekleyin:

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

Fonksiyonlar sınıfına erişim olsaydı değiştirmek mümkün olurdu sanırım. Sonra böyle bir şey yazabilirim:

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

Benim sınıflar function.php dosyasında bir erişim elde etmek benim düşüncem sınıf function.php içinde bildirildiği dosyayı dahil etmek oldu:

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

Ama bu çalışmıyor çünkü eklenti WordPress'te başlatıldığında eklentinin dosyası dahil, sanırım.

Eklentinin dosyalarına dokunmadan işlevi yeniden yazmanın bir yolu var mı?

Yanıtlar:


8

Bu çalışmalı:

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

}


Evet, kaçırdım, bu eklentinin global bir değişken olarak erişilebilen bir değişkeni var. Aptallığım. Cevabınız için teşekkürler, bu bu özel durumda çalışıyor (bu eklenti için).
Igor Skoldin

Alex Older, cevabının neden çalıştığını açıklayan yere bağlantı verdi. Remove_action, içinde bir yöntemi kaldırmak istediğiniz statik veya örnek sınıfına sahip bir diziyi kabul eder.
ninja08

11

Eklentiniz şu şekilde kaydedildiyse:

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();

Ardından, genel alana erişerek filtreyi kaldırabilirsiniz:

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();

Aksi takdirde, $wp_filter globalkayıt anahtarını taramanız gerekir :

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();

Bu kaynak yoğun bir işlemdir ve başka seçeneğiniz olmadığı sürece gerçekten yapılmamalıdır.


2
Bu kabul edilen cevap olmalı. Bu daha genel olarak faydalıdır ve yalnızca OP'nin özel durumu ile sınırlı değildir.
David R.

1

Bu eklenti, init işlevini wcpgsk_init()eklenebilir hale getirir , bu nedenle onu geçersiz kılmanın başka bir yolu, ilk olarak mutlaka kullanılması gereken bir eklentide tanımlamaktır (temanızın "function.php" sinde çok geç olduğu için). Böylece geçersiz kılmayı "wp-content / mu-plugins / function.php" içine koyabilirsiniz:

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

Ancak bunu geçersiz kılmanın daha iyi bir yolu, yüklemek runkit( https://github.com/padraic/runkit ) ve ardından doğrudan temanızın "function.php" dosyasına koymaktır:

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
    );
} );

(Bu bir şaka, btw.)

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.