remove_action()

最后更新于:2021-11-27 21:40:11

remove_action( string$hook_name, callable$callback, int$priority=10)

Removes a callback function from an action hook.

参数

$hook_name

(string) (Required) The action hook to which the function to be removed is hooked.

$callback

(callable) (Required) The name of the function which should be removed.

$priority

(int) (Optional) The exact priority used when adding the original action callback.

Default value: 10

响应

(bool) Whether the function is removed.

源文件

文件: gc-includes/plugin.php

function remove_action( $hook_name, $callback, $priority = 10 ) {
	return remove_filter( $hook_name, $callback, $priority );
}
/**
 * Make sure the function does not exist before defining it
 */
if( ! function_exists( 'remove_class_filter' ) ){
	/**
	 * Remove Class Filter Without Access to Class Object
	 *
	 * In order to use the core GeChiUI remove_filter() on a filter added with the callback
	 * to a class, you either have to have access to that class object, or it has to be a call
	 * to a static method.  This method allows you to remove filters with a callback to a class
	 * you don't have access to.
	 *
	 * Works with GeChiUI 1.2+ (4.7+ support added 9-19-2016)
	 * Updated 2-27-2017 to use internal GeChiUI removal for 4.7+ (to prevent PHP warnings output)
	 *
	 * @param string $tag         Filter to remove
	 * @param string $class_name  Class name for the filter's callback
	 * @param string $method_name Method name for the filter's callback
	 * @param int    $priority    Priority of the filter (default 10)
	 *
	 * @return bool Whether the function is removed.
	 */
	function remove_class_filter( $tag, $class_name = '', $method_name = '', $priority = 10 ) {
		global $gc_filter;
		// Check that filter actually exists first
		if ( ! isset( $gc_filter[ $tag ] ) ) {
			return FALSE;
		}
		/**
		 * If filter config is an object, means we're using GeChiUI 4.7+ and the config is no longer
		 * a simple array, rather it is an object that implements the ArrayAccess interface.
		 *
		 * To be backwards compatible, we set $callbacks equal to the correct array as a reference (so $gc_filter is updated)
		 *
		 * @see https://make.gechiui.org/core/2016/09/08/gc_hook-next-generation-actions-and-filters/
		 */
		if ( is_object( $gc_filter[ $tag ] ) && isset( $gc_filter[ $tag ]->callbacks ) ) {
			// Create $fob object from filter tag, to use below
			$fob       = $gc_filter[ $tag ];
			$callbacks = &$gc_filter[ $tag ]->callbacks;
		} else {
			$callbacks = &$gc_filter[ $tag ];
		}
		// Exit if there aren't any callbacks for specified priority
		if ( ! isset( $callbacks[ $priority ] ) || empty( $callbacks[ $priority ] ) ) {
			return FALSE;
		}
		// Loop through each filter for the specified priority, looking for our class & method
		foreach ( (array) $callbacks[ $priority ] as $filter_id => $filter ) {
			// Filter should always be an array - array( $this, 'method' ), if not goto next
			if ( ! isset( $filter['function'] ) || ! is_array( $filter['function'] ) ) {
				continue;
			}
			// If first value in array is not an object, it can't be a class
			if ( ! is_object( $filter['function'][0] ) ) {
				continue;
			}
			// Method doesn't match the one we're looking for, goto next
			if ( $filter['function'][1] !== $method_name ) {
				continue;
			}
			// Method matched, now let's check the Class
			if ( get_class( $filter['function'][0] ) === $class_name ) {
				// GeChiUI 4.7+ use core remove_filter() since we found the class object
				if ( isset( $fob ) ) {
					// Handles removing filter, reseting callback priority keys mid-iteration, etc.
					$fob->remove_filter( $tag, $filter['function'], $priority );
				} else {
					// Use legacy removal process (pre 4.7)
					unset( $callbacks[ $priority ][ $filter_id ] );
					// and if it was the only filter in that priority, unset that priority
					if ( empty( $callbacks[ $priority ] ) ) {
						unset( $callbacks[ $priority ] );
					}
					// and if the only filter for that tag, set the tag to an empty array
					if ( empty( $callbacks ) ) {
						$callbacks = array();
					}
					// Remove this filter from merged_filters, which specifies if filters have been sorted
					unset( $GLOBALS['merged_filters'][ $tag ] );
				}
				return TRUE;
			}
		}
		return FALSE;
	}
}
/**
 * Make sure the function does not exist before defining it
 */
if( ! function_exists( 'remove_class_action') ){
	/**
	 * Remove Class Action Without Access to Class Object
	 *
	 * In order to use the core GeChiUI remove_action() on an action added with the callback
	 * to a class, you either have to have access to that class object, or it has to be a call
	 * to a static method.  This method allows you to remove actions with a callback to a class
	 * you don't have access to.
	 *
	 * Works with GeChiUI 1.2+ (4.7+ support added 9-19-2016)
	 *
	 * @param string $tag         Action to remove
	 * @param string $class_name  Class name for the action's callback
	 * @param string $method_name Method name for the action's callback
	 * @param int    $priority    Priority of the action (default 10)
	 *
	 * @return bool               Whether the function is removed.
	 */
	function remove_class_action( $tag, $class_name = '', $method_name = '', $priority = 10 ) {
		remove_class_filter( $tag, $class_name, $method_name, $priority );
	}
}
/**
* Different way to remove hooks declare inside class
*/

class MyClass {
	
	/**
	 * The single instance of the class.
	 * 
	 */
	protected static $_instance = null;

	/**
	 * Main plugins instance
	 *
	 * Ensures only one instance of this class
	 * Its always good practice to user single instance of the class so we can modify hooks initialized on this class
	 */
	public static function get_instance() {
		if ( is_null( self::$_instance ) ) {
			self::$_instance = new self();
		}
		return self::$_instance;
	}

	/**
	* Register hoooks
	*/
	public function __construct() {
		/*
		* @hooked add_custom_body_class 10
		*/
		add_filter( 'body_class', array( $this, 'add_custom_body_class' ) );
		/*
		* @hooked static static_body_class - 20
		*/
		add_filter( 'body_class', array( 'MyClass', 'static_body_class' ),  20 );
	}
	/**
	* @return array of class
	*/
	public function add_custom_body_class( $class ) {
		$class[ 'custom_class' ] = 'customClass';
		return $class;
	}
	/**
	* @return array of class
	*/
	static function static_body_class( $class ) {
		$class[ 'static_custom_class' ] = 'staticCustomClass';
		return $class;
	}
}
$my_class = MyClass::get_instance();

/**
* Remove methods: add_custom_body_class attached to body class
*/
add_action( 'gc_head', 'themeslug_remove_hooks' );
function themeslug_remove_hooks() {
	/**
	* Always use same class object, this can be achieve by restricting multiple instance of the class
	*/
	$is_action_removed = remove_action( 'body_class', array( MyClass::get_instance(), 'add_custom_body_class'  ) );
	/**
	* Remove static method class by using class name with same priority 20
	*/
	$is_action_removed = remove_action( 'body_class', array( 'MyClass', 'static_body_class'  ), 20 );
}