( $this->callbacks[ $priority ] as $the_ ) { if( ! $this->doing_action ) { $args[ 0 ] = $value; } // Avoid the array_slice if possible. if ( $the_['accepted_args'] == 0 ) { $value = call_user_func_array( $the_['function'], array() ); } elseif ( $the_['accepted_args'] >= $num_args ) { $value = call_user_func_array( $the_['function'], $args ); } else { $value = call_user_func_array( $the_['function'], array_slice( $args, 0, (int)$the_['accepted_args'] ) ); } } } while ( false !== next( $this->iterations[ $nesting_level ] ) ); unset( $this->iterations[ $nesting_level ] ); unset( $this->current_priority[ $nesting_level ] ); $this->nesting_level--; return $value; } /** * Executes the callback functions hooked on a specific action hook. * * @since 4.7.0 * * @param mixed $args Arguments to pass to the hook callbacks. */ public function do_action( $args ) { $this->doing_action = true; $this->apply_filters( '', $args ); // If there are recursive calls to the current action, we haven't finished it until we get to the last one. if ( ! $this->nesting_level ) { $this->doing_action = false; } } /** * Processes the functions hooked into the 'all' hook. * * @since 4.7.0 * * @param array $args Arguments to pass to the hook callbacks. Passed by reference. */ public function do_all_hook( &$args ) { $nesting_level = $this->nesting_level++; $this->iterations[ $nesting_level ] = array_keys( $this->callbacks ); do { $priority = current( $this->iterations[ $nesting_level ] ); foreach ( $this->callbacks[ $priority ] as $the_ ) { call_user_func_array( $the_['function'], $args ); } } while ( false !== next( $this->iterations[ $nesting_level ] ) ); unset( $this->iterations[ $nesting_level ] ); $this->nesting_level--; } /** * Return the current priority level of the currently running iteration of the hook. * * @since 4.7.0 * * @return int|false If the hook is running, return the current priority level. If it isn't running, return false. */ public function current_priority() { if ( false === current( $this->iterations ) ) { return false; } return current( current( $this->iterations ) ); } /** * Normalizes filters set up before WordPress has initialized to WP_Hook objects. * * @since 4.7.0 * @static * * @param array $filters Filters to normalize. * @return WP_Hook[] Array of normalized filters. */ public static function build_preinitialized_hooks( $filters ) { /** @var WP_Hook[] $normalized */ $normalized = array(); foreach ( $filters as $tag => $callback_groups ) { if ( is_object( $callback_groups ) && $callback_groups instanceof WP_Hook ) { $normalized[ $tag ] = $callback_groups; continue; } $hook = new WP_Hook(); // Loop through callback groups. foreach ( $callback_groups as $priority => $callbacks ) { // Loop through callbacks. foreach ( $callbacks as $cb ) { $hook->add_filter( $tag, $cb['function'], $priority, $cb['accepted_args'] ); } } $normalized[ $tag ] = $hook; } return $normalized; } /** * Determines whether an offset value exists. * * @since 4.7.0 * * @link https://secure.php.net/manual/en/arrayaccess.offsetexists.php * * @param mixed $offset An offset to check for. * @return bool True if the offset exists, false otherwise. */ public function offsetExists( $offset ) { return isset( $this->callbacks[ $offset ] ); } /** * Retrieves a value at a specified offset. * * @since 4.7.0 * * @link https://secure.php.net/manual/en/arrayaccess.offsetget.php * * @param mixed $offset The offset to retrieve. * @return mixed If set, the value at the specified offset, null otherwise. */ public function offsetGet( $offset ) { return isset( $this->callbacks[ $offset ] ) ? $this->callbacks[ $offset ] : null; } /** * Sets a value at a specified offset. * * @since 4.7.0 * * @link https://secure.php.net/manual/en/arrayaccess.offsetset.php * * @param mixed $offset The offset to assign the value to. * @param mixed $value The value to set. */ public function offsetSet( $offset, $value ) { if ( is_null( $offset ) ) { $this->callbacks[] = $value; } else { $this->callbacks[ $offset ] = $value; } } /** * Unsets a specified offset. * * @since 4.7.0 * * @link https://secure.php.net/manual/en/arrayaccess.offsetunset.php * * @param mixed $offset The offset to unset. */ public function offsetUnset( $offset ) { unset( $this->callbacks[ $offset ] ); } /** * Returns the current element. * * @since 4.7.0 * * @link https://secure.php.net/manual/en/iterator.current.php * * @return array Of callbacks at current priority. */ public function current() { return current( $this->callbacks ); } /** * Moves forward to the next element. * * @since 4.7.0 * * @link https://secure.php.net/manual/en/iterator.next.php * * @return array Of callbacks at next priority. */ public function next() { return next( $this->callbacks ); } /** * Returns the key of the current element. * * @since 4.7.0 * * @link https://secure.php.net/manual/en/iterator.key.php * * @return mixed Returns current priority on success, or NULL on failure */ public function key() { return key( $this->callbacks ); } /** * Checks if current position is valid. * * @since 4.7.0 * * @link https://secure.php.net/manual/en/iterator.valid.php * * @return boolean */ public function valid() { return key( $this->callbacks ) !== null; } /** * Rewinds the Iterator to the first element. * * @since 4.7.0 * * @link https://secure.php.net/manual/en/iterator.rewind.php */ public function rewind() { reset( $this->callbacks ); } }