如何从我的主题中的unctions.php中删除插件中的动作钩子?

时间:2017-03-03 作者:chas ant

plugin类的某个地方有一个钩子:

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

这增加了我不想要的东西。在我的功能中。php在我的主题中,我尝试了以下所有方法:remove_action(\'woocommerce_some_hook\',\'some_function\');

remove_action( \'woocommerce_some_hook\', array(\'original_plugin_class\', \'some_function\',));
但是,我还是不能把钩子取下来!

3 个回复
SO网友:Nathan Johnson

WordPress处理钩子的方式有一个问题,即要用OOP回调删除特定钩子,必须访问与添加回调时完全相同的类实例。这通常很容易在您自己的插件/主题中处理。

然而,除非开发人员全球化了类的实例,否则几乎不可能从另一个插件中删除挂钩。如果是这样,那么您可以使用global 关键字,然后像正常情况一样移除挂钩。另一种流行的模式是使用singleton方法只允许类的一个实例。

不幸的是,似乎有很多插件(包括WC)在包含该文件时初始化该类。为了使事情更加复杂,他们在类的构造函数中添加了挂钩。这使得移除挂钩极其困难。

我一直在学习一个类,该类将从$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 ];
  }
}
编辑:这仅适用于大于4.7的WP版本。

SO网友:TrubinE

有必要传递一个设置了钩子的实例

global $my_class;
remove_action( \'woocommerce_some_hook\', array( $my_class, \'some_function\' ) );
确保类的实例可用

SO网友:Vinoth Kumar

你可以试试,

remove_action( \'woocommerce_some_hook\', array(new original_plugin_class(), \'some_function\',));
如果类不是全局创建的,则需要创建该类的实例。假设他们在某处创建了类的实例,那么您可以使用上面提到的@TrubinE。

相关推荐

使用快速编辑更新POST时,POST_ROW_ACTIONS过滤器不工作

我使用post\\u row\\u操作创建了两个链接,页面加载时显示良好。但使用快速编辑更新帖子后,链接将消失。是WordPress的bug还是我错过了什么。我的代码如下所示。add_filter(\'post_row_actions\', \'add_new_link\', 10, 2); public function add_new_link($actions, $page_object) { $actions[\'new_action\'] = \'<