functions.php에서 플러그인 클래스 내에 선언 된 함수를 어떻게 대체합니까?


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

functions.php의 클래스에 액세스 할 수 있다면 바꿀 수 있다고 생각합니다. 그런 다음 다음과 같이 작성할 수 있습니다.

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

functions.php 파일에서 클래스에 액세스 할 생각은 클래스가 functions.php에서 선언 된 파일을 포함하는 것이 었습니다.

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

그러나 플러그인이 WordPress에서 초기화 될 때 플러그인 파일이 포함되어 있기 때문에 작동하지 않습니다.

플러그인 파일을 건드리지 않고 기능을 다시 작성할 수있는 방법이 있습니까?

답변:


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

}

1
remove_action 함수가 있습니다 : codex.wordpress.org/Function_Reference/remove_action
Alex Older

그렇습니다.이 플러그인에는 전역 변수로 액세스 할 수있는 변수가 있습니다. 어리 석음 귀하의 답변에 감사드립니다.이 특별한 경우 (이 플러그인의 경우)에서 작동합니다.
Igor Skoldin

Alex Older는 자신의 답변이 왜 작동하는지 설명하는 장소에 연결했습니다. remove_action은 메소드를 제거하려는 정적 또는 인스턴스 클래스가있는 배열을 허용합니다.
ninja08

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
이것은 정답입니다. 이는보다 일반적으로 유용하며 OP의 특정 사례에만 국한되지 않습니다.
David R.

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.)

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.