|array|array */ protected $queries; protected $removed = array(); public function __construct() { $this->queries = array(); $this->removed = array(); } /** * @param array|array|array $queries */ public function setQueries($queries) { $this->queries = $queries; } /** * @return bool */ public function execute() { if (count($this->queries) === 0) { return true; } global $wp_filter; /** @var $wp_filter \WP_Hook[] */ if (empty($wp_filter)) { return true; } $this->removed = array(); foreach ($this->queries as $query) { $tag = null; if ($query instanceof ClassMethodFilterQuery || $query instanceof FunctionFilterQuery) { $tag = $query->getTag(); } if (isset($tag)) { if (isset($wp_filter[$tag])) { $hookObj = &$wp_filter[$tag]; $this->executeHookObj($hookObj, $tag, $query); } } else { foreach ($wp_filter as $tag => &$hookObj) { $this->executeHookObj($hookObj, $tag, $query); } } } return true; } /** * @param \WP_Hook $hookObj * @param string $tag * @param ClassMethodFilterQuery|FunctionFilterQuery $query */ protected function executeHookObj(&$hookObj, $tag, $query) { $newCallbacks = array(); $removedCallbacks = array(); foreach ($hookObj->callbacks as $priority => $callbacks) { $priority_callbacks = array(); $removedPriorityCallbacks = array(); foreach ($callbacks as $idx => $callback) { $details = new CallBackDetails($callback); $save = true; if ($query instanceof TagFilterQuery) { /** @var TagFilterQuery $query */ if ($query->isAction($query::ACTION_REMOVE_OTHERS)) { $save = in_array($tag, $query->getList()); } elseif ($query->isAction($query::ACTION_REMOVE_ALL_IN_TAG)) { $save = ! in_array($tag, $query->getList()); } } elseif ($query instanceof ClassMethodFilterQuery) { /** @var ClassMethodFilterQuery $query */ if ($details->isType($details::TYPE_COMPLETE)) { if ( ! $save && $query->isAction($query::ACTION_SAVE)) { $save = in_array($details->getFunc(), $query->getList()); } elseif ($save && $query->isAction($query::ACTION_REMOVE)) { $save = ! in_array($details->getFunc(), $query->getList()); } } } elseif ($query instanceof FunctionFilterQuery) { /** @var FunctionFilterQuery $query */ if ($details->isType($details::TYPE_FUNCTION) || $details->isType($details::TYPE_CLOSURE)) { if ( ! $save && $query->isAction($query::ACTION_SAVE)) { $save = in_array($details->getFunc(), $query->getList()); } elseif ($save && $query->isAction($query::ACTION_REMOVE)) { $save = ! in_array($details->getFunc(), $query->getList()); } } } if ($save) { $priority_callbacks[$idx] = $callback; } else { $removedPriorityCallbacks[$idx] = $callback; } } if ($priority_callbacks) { $newCallbacks[$priority] = $priority_callbacks; } if ($removedPriorityCallbacks) { $removedCallbacks[$priority] = $removedPriorityCallbacks; } } if (isset($this->removed[$tag])) { foreach ($this->removed[$tag] as $priority => $callbacks) { $priority_callbacks = array(); foreach ($callbacks as $idx => $callback) { $details = new CallBackDetails($callback); $save = false; if ($query instanceof ClassMethodFilterQuery) { /** @var ClassMethodFilterQuery $query */ if ($details->isType($details::TYPE_COMPLETE)) { $save = in_array($details->getFunc(), $query->getList()) && $query->isAction($query::ACTION_SAVE); } } elseif ($query instanceof FunctionFilterQuery) { /** @var FunctionFilterQuery $query */ if ($details->isType($details::TYPE_FUNCTION) || $details->isType($details::TYPE_CLOSURE)) { $save = in_array($details->getFunc(), $query->getList()) && $query->isAction($query::ACTION_SAVE); } } if ($save) { $priority_callbacks[$idx] = $callback; unset($this->removed[$tag][$priority][$idx]); } } if ($priority_callbacks) { $newCallbacks[$priority] = $priority_callbacks; } } } $hookObj->callbacks = $newCallbacks; $this->maybeUpdatePriorities($hookObj); if ($removedCallbacks) { if ( ! isset($this->removed[$tag])) { $this->removed[$tag] = array(); } foreach ($removedCallbacks as $prior => $callback) { $this->removed[$tag][$prior] = $callback; } } } public function restore() { global $wp_filter; /** @var $wp_filter \WP_Hook[] */ if ($wp_filter) { foreach ($this->removed as $tag => $callbacks) { if (isset($wp_filter[$tag])) { $hookObj = &$wp_filter[$tag]; } else { $hookObj = new \WP_Hook(); } foreach ($callbacks as $prior => $callback) { $hookObj->callbacks[$prior] = $callback; } ksort($hookObj->callbacks, SORT_NUMERIC); $this->maybeUpdatePriorities($hookObj); } } $this->removed = array(); return true; } private function maybeUpdatePriorities($hookObj) { try { $reflection = new \ReflectionClass($hookObj); $property = $reflection->getProperty('priorities'); $property->setAccessible(true); $property->setValue($hookObj, array_keys($hookObj->callbacks)); } catch (\ReflectionException $e) { } } }