it-swarm.com.de

Wie entferne ich Action Hooks, die in einem Plugin von functions.php in meinem Theme erstellt wurden?

Irgendwo in der Plugin-Klasse gibt es diesen Hook:

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

es fügt etwas hinzu, das ich dort nicht will. In meiner functions.php in meinem Theme habe ich alles ausprobiert wie: remove_action('woocommerce_some_hook','some_function');

oder

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

aber trotzdem kann ich den haken einfach nicht entfernen!

6
chas ant

Ein Problem bei der Verarbeitung von Hooks durch WordPress besteht darin, dass Sie zum Entfernen eines bestimmten Hooks mit einem OOP -Rückruf Zugriff auf das exakt dieselbe Instanz der Klasse haben müssen, als der Rückruf hinzugefügt wurde. Dies ist in der Regel einfach genug, um mit Ihren eigenen Plugins/Themes umzugehen.

Es ist jedoch fast unmöglich, einen Hook von einem anderen Plugin zu entfernen, es sei denn, dieser Entwickler hat die Instanz der Klasse globalisiert. In diesem Fall können Sie das Schlüsselwort global verwenden und den Haken wie gewohnt entfernen. Ein weiteres beliebtes Muster ist die Verwendung einer Singleton-Methode, um nur eine Instanz der Klasse zuzulassen.

Leider scheinen viele Plugins (einschließlich WC) die Klasse zu initialisieren, wenn die Datei enthalten ist. Um die Sache noch weiter zu komplizieren, fügen sie Hooks im Konstruktor der Klasse hinzu. Dies macht es äußerst schwierig, Haken zu entfernen.

Ich habe an einer Klasse gearbeitet, die einen Haken aus der globalen Variablen $wp_filter entfernt, wenn Sie den Namespace\Class und die Methode des Rückrufs kennen. Ich habe die Klasse nur in begrenztem Umfang getestet. Die Verwendung erfolgt auf eigenes Risiko, aber bei mir funktioniert es.

Hoffentlich weist dies Sie in die richtige Richtung.

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

Bearbeiten: Dies funktioniert nur mit WP Versionen größer als 4.7.

8
Nathan Johnson

Du kannst es versuchen,

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

sie müssen die Instanz der Klasse erstellen, wenn sie nicht global erstellt wurden. Angenommen, sie haben die Instanz der Klasse irgendwo erstellt, dann können Sie diese wie @TrubinE erwähnt verwenden.

0
Vinoth Kumar

Es muss eine Instanz übergeben werden, in der der Hook eingerichtet wurde

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

stellen Sie sicher, dass die Instanz der Klasse verfügbar ist

0
TrubinE