web-dev-qa-db-fra.com

Comment supprimer le hook d'action fait dans un plugin de functions.php dans mon thème?

Quelque part dans la classe du plugin, il y a ce hook:

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

il ajoute quelque chose que je ne veux pas là. Dans mon functions.php dans mon thème, j'ai tout essayé tel que: remove_action('woocommerce_some_hook','some_function');

ou

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

mais je ne peux tout simplement pas enlever le crochet!

6
chas ant

Un problème lié à la manière dont WordPress traite les points d'ancrage est que, pour supprimer un point spécifique avec un rappel OOP, vous devez avoir accès à la même instance de la classe exactement comme lorsque le rappel a été ajouté. C’est généralement assez facile à gérer dans vos propres plugins/thèmes.

Cependant, il est presque impossible de supprimer un hook d'un autre plugin à moins que ce développeur ait globalisé l'instance de la classe. Si c'est le cas, vous pouvez utiliser le mot clé global et supprimer le crochet comme d'habitude. Un autre modèle répandu consiste à utiliser une méthode singleton pour n'autoriser qu'une instance de la classe.

Malheureusement, il semble que beaucoup de plugins (y compris WC) initialisent la classe lorsque le fichier est inclus. Pour compliquer davantage les choses, ils ajoutent des points dans le constructeur de la classe. Cela rend extrêmement difficile le retrait des crochets.

J'ai travaillé sur une classe qui supprimera un crochet de la variable globale $wp_filter si vous connaissez le Namespace\Class and Method du rappel. J'ai fait des tests limités dans la classe, utilisez donc à vos risques et périls, mais cela fonctionne pour moi.

Espérons que cela vous indiquera la bonne direction.

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

Edit: cela ne fonctionnera que sur WP versions supérieures à 4.7.

8
Nathan Johnson

Tu peux essayer,

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

vous devez créer l'instance de la classe quand elles ne sont pas créées globalement. Supposons que s'ils ont créé l'instance de la classe à un endroit quelconque, vous pouvez utiliser celui-ci comme indiqué par @TrubinE.

0
Vinoth Kumar

Il est nécessaire de passer une instance dans laquelle le hook a été mis en place

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

assurez-vous que l'instance de la classe est disponible

0
TrubinE