web-dev-qa-db-ja.com

私のテーマのfunctions.phpからプラグインで行われたアクションフックを削除するにはどうすればいいですか?

プラグインクラスのどこかにこのフックがあります。

add_action( 'woocommerce_some_hook', array( $this, 'some_function') );

それは私がそこにいたくない何かを追加します。私のテーマのfunctions.phpでは、次のようなことをすべて試してみました:remove_action('woocommerce_some_hook','some_function');

または

remove_action( 'woocommerce_some_hook', array('original_plugin_class', 'some_function',));

それでも、フックを外すことはできません。

6
chas ant

WordPressがフックを処理する方法に伴う1つの問題は、OOPコールバックで特定のフックを削除するには、コールバックが追加されたときと同じ まったく同じインスタンス にアクセスする必要があるということです。 。これは一般的にあなた自身のプラグイン/テーマを扱うのに十分簡単です。

ただし、その開発者がクラスのインスタンスをグローバル化しない限り、別のプラグインからフックを削除することはほぼ不可能です。その場合は、globalキーワードを使用して通常どおりフックを削除できます。もう1つの一般的なパターンは、クラスのインスタンスを1つだけ許可するためにシングルトンメソッドを使用することです。

残念ながら、ファイルがインクルードされると、多くのプラグイン(WCを含む)がクラスを初期化するようです。さらに複雑にするために、それらはクラスのコンストラクタにフックを追加します。これはフックを外すことを非常に難しくします。

あなたがコールバックのNamespace\ClassとMethodを知っていれば、私は$wp_filterグローバル変数からフックを削除するクラスに取り組んできました。私はクラスの限定的なテストを行ったので、あなた自身の責任で使ってください、しかしそれは私のために働きます。

うまくいけば、これは正しい方向にあなたを指すでしょう。

<?php

namespace WPSE\Q_258764;

/**
 * Class for interacting with hooks
 */

class hooks {

  /**
   * @var Namespace of the hook
   *
   * @access protected
   * @since 0.2
   */
  protected $namespace;

  /**
   * Object constructor
   *
   * @param string $namespace The namespace of the hook. Optional.
   *
   * @access public
   * @since 0.2
   */
  public function __construct( $namespace = __NAMESPACE__ ) {
    $this->namespace = $namespace;
  }

  /**
   * Remove a hook from the $wp_filter global
   *
   * @param string   $tag      The hook which the callback is attached to
   * @param callable $callback The callback to remove
   * @param int      $priority The priority of the callback
   *
   * @access public
   * @since 0.2
   *
   * @return bool Whether the filter was originally in the $wp_filter global
   */
  public function remove_hook( $tag, $callback, $priority = 10 ) {
    global $wp_filter;
    $tag_hooks = $wp_filter[ $tag ]->callbacks[ $priority ];
    foreach ( $tag_hooks as $the_tag => $the_callback ) {
      if( $this->parse_callback( $the_callback ) === $callback ) {
        return \remove_filter( $tag, $the_callback[ 'function' ], $priority );
      }
    }
    return \remove_filter( $tag, $callback, $priority );
  }

  /**
   * Trim backslash from string
   *
   * @param string $string
   *
   * @access protected
   * @since 0.2
   *
   * @return string
   */
  protected function trim_backslash( $string ) {
    return trim( $string, '\\' );
  }

  /**
   * Remove the namespace from the string
   *
   * @param string $string
   *
   * @access protected
   * @since 0.2
   *
   * @return string
   */
  protected function remove_namespace( $string ) {
    return str_ireplace( $this->namespace, '', $string );
  }

  /**
   * Get the class name of an object
   *
   * @param object $object
   *
   * @access protected
   * @since 0.2
   *
   * @return string
   */
  protected function get_class( $object ) {
    return get_class( $object );
  }

  /**
   * Return the callback object
   *
   * @param array $callback
   *
   * @access protected
   * @since 0.2
   *
   * @return object
   */
  protected function callback_object( $callback ) {
    return $callback[ 'function' ][ 0 ];
  }

  /**
   * Return the callback method
   *
   * @param array $callback
   *
   * @access protected
   * @since 0.2
   *
   * @return string
   */
  protected function callback_method( $callback ) {
    return $callback[ 'function' ][ 1 ];
  }

  /**
   * Return the class from the callback
   *
   * @param array $callback
   *
   * @access protected
   * @since 0.2
   *
   * @return string
   */
  protected function get_class_from_callback( $callback ) {
    return $this->get_class( $this->callback_object( $callback ) );
  }

  /**
   * Wrapper for strtolower
   *
   * @param string $string
   *
   * @access protected
   * @since 0.2
   *
   * @return string
   */
  protected function strtolower( $string ) {
    return strtolower( $string );
  }

  /**
   * Parse the callback into an array
   *
   * @param array $callback
   *
   * @access protected
   * @since 0.2
   *
   * @return array
   */
  protected function parse_callback( $callback ) {
    return is_array( $callback[ 'function' ] ) ?
      [ $this->class( $callback ), $this->method( $callback ) ] : false;
  }

  /**
   * Return the class of a callback
   *
   * @param array $callback
   *
   * @access protected
   * @since 0.2
   *
   * @return string
   */
  protected function class( $callback ) {
    $class = $this->get_class_from_callback( $callback );
    $class = $this->strtolower( $class );
    $class = $this->remove_namespace( $class );
    return $this->trim_backslash( $class );
  }

  /**
   * Return the method of a callback
   *
   * @param array $callback
   *
   * @access protected
   * @since 0.2
   *
   * @return string
   */
  protected function method( $callback ) {
    return $callback[ 'function' ][ 1 ];
  }
}

編集:これはWPバージョン4.7以上でのみ動作します。

8
Nathan Johnson

あなたが試すことができます、

remove_action( 'woocommerce_some_hook', array(new original_plugin_class(), 'some_function',));

グローバルに作成されていない場合は、クラスのインスタンスを作成する必要があります。彼らがクラスのインスタンスをどこかに作成したとすると、@ TrubinEが述べたようにそれを使用できます。

0
Vinoth Kumar

フックが設定されたインスタンスを渡す必要があります

global $my_class;
remove_action( 'woocommerce_some_hook', array( $my_class, 'some_function' ) );

クラスのインスタンスが使用可能であることを確認してください。

0
TrubinE