mirror of
https://github.com/processwire/processwire.git
synced 2025-08-21 14:02:59 +02:00
Some minor optimizations in WireHooks class, plus enable before/after option for $type argument in runHooks method that was mentioned in the phpdoc but wasn't fully supported yet
This commit is contained in:
@@ -529,7 +529,7 @@ abstract class Wire implements WireTranslatable, WireFuelable, WireTrackable {
|
||||
*
|
||||
* @param string $method Method or property to run hooks for.
|
||||
* @param array $arguments Arguments passed to the method and hook.
|
||||
* @param string $type May be either 'method' or 'property', depending on the type of call. Default is 'method'.
|
||||
* @param string|array $type May be either 'method', 'property' or array of hooks (from getHooks) to run. Default is 'method'.
|
||||
* @return array Returns an array with the following information:
|
||||
* [return] => The value returned from the hook or NULL if no value returned or hook didn't exist.
|
||||
* [numHooksRun] => The number of hooks that were actually run.
|
||||
@@ -597,8 +597,8 @@ abstract class Wire implements WireTranslatable, WireFuelable, WireTrackable {
|
||||
* - Also considers the class parents for hooks.
|
||||
*
|
||||
* ~~~~~
|
||||
* if($pages->hasHook('find')) {
|
||||
* // the Pages::find method is hooked
|
||||
* if($pages->hasHook('find()')) {
|
||||
* // the Pages::find() method is hooked
|
||||
* }
|
||||
* ~~~~~
|
||||
*
|
||||
|
@@ -673,11 +673,12 @@ class WireHooks {
|
||||
* @param Wire $object
|
||||
* @param string $method Method or property to run hooks for.
|
||||
* @param array $arguments Arguments passed to the method and hook.
|
||||
* @param string $type May be any one of the following:
|
||||
* @param string|array $type May be any one of the following:
|
||||
* - method: for hooked methods (default)
|
||||
* - property: for hooked properties
|
||||
* - before: only run before hooks and do nothing else
|
||||
* - after: only run after hooks and do nothing else
|
||||
* - Or array[] of hooks (from getHooks method) to run (does not call hooked method)
|
||||
* @return array Returns an array with the following information:
|
||||
* [return] => The value returned from the hook or NULL if no value returned or hook didn't exist.
|
||||
* [numHooksRun] => The number of hooks that were actually run.
|
||||
@@ -688,33 +689,46 @@ class WireHooks {
|
||||
public function runHooks(Wire $object, $method, $arguments, $type = 'method') {
|
||||
|
||||
$hookTimer = self::___debug ? $this->hookTimer($object, $method, $arguments) : null;
|
||||
$realMethod = "___$method";
|
||||
$cancelHooks = false;
|
||||
$profiler = $this->wire->wire('profiler');
|
||||
$hooks = null;
|
||||
|
||||
if(is_array($type)) {
|
||||
// array of hooks to run provided in $type argument
|
||||
$hooks = $type;
|
||||
$type = 'custom';
|
||||
}
|
||||
|
||||
$result = array(
|
||||
'return' => null,
|
||||
'numHooksRun' => 0,
|
||||
'methodExists' => false,
|
||||
'methodExists' => ($type === 'method' ? method_exists($object, $realMethod) : false),
|
||||
'replace' => false,
|
||||
);
|
||||
|
||||
$realMethod = "___$method";
|
||||
if($type == 'method') $result['methodExists'] = method_exists($object, $realMethod);
|
||||
// if(!$result['methodExists'] && !$this->hasHook($object, $method . ($type == 'method' ? '()' : ''))) {
|
||||
if(!$result['methodExists'] && !$this->isHookedOrParents($object, $method, $type)) {
|
||||
return $result; // exit quickly when we can
|
||||
if($type === 'method' || $type === 'property') {
|
||||
if(!$result['methodExists'] && !$this->isHookedOrParents($object, $method, $type)) {
|
||||
return $result; // exit quickly when we can
|
||||
}
|
||||
}
|
||||
|
||||
$hooks = $this->getHooks($object, $method);
|
||||
$cancelHooks = false;
|
||||
$profiler = $this->wire->wire('profiler');
|
||||
if($hooks === null) $hooks = $this->getHooks($object, $method);
|
||||
|
||||
foreach(array('before', 'after') as $when) {
|
||||
|
||||
if($type === 'method' && $when === 'after' && $result['replace'] !== true) {
|
||||
if($result['methodExists']) {
|
||||
$result['return'] = $object->_callMethod($realMethod, $arguments);
|
||||
} else {
|
||||
$result['return'] = null;
|
||||
if($type === 'method') {
|
||||
if($when === 'after' && $result['replace'] !== true) {
|
||||
if($result['methodExists']) {
|
||||
$result['return'] = $object->_callMethod($realMethod, $arguments);
|
||||
} else {
|
||||
$result['return'] = null;
|
||||
}
|
||||
}
|
||||
} else if($type === 'after') {
|
||||
if($when === 'before') continue;
|
||||
} else if($type === 'before') {
|
||||
if($when === 'after') break;
|
||||
}
|
||||
|
||||
foreach($hooks as $priority => $hook) {
|
||||
@@ -843,6 +857,26 @@ class WireHooks {
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter and return hooks matching given property and value
|
||||
*
|
||||
* @param array $hooks Hooks from getHooks() method
|
||||
* @param string $property Property name from hook (or hook options)
|
||||
* @param string|bool|int $value Value to match
|
||||
* @return array
|
||||
*
|
||||
*/
|
||||
public function filterHooks(array $hooks, $property, $value) {
|
||||
foreach($hooks as $key => $hook) {
|
||||
if(array_key_exists($property, $hook)) {
|
||||
if($hook[$property] !== $value) unset($hooks[$key]);
|
||||
} else if(array_key_exists($property, $hook['options'])) {
|
||||
if($hook['options'][$property] !== $value) unset($hooks[$key]);
|
||||
}
|
||||
}
|
||||
return $hooks;
|
||||
}
|
||||
|
||||
/**
|
||||
* Start timing a hook and return the timer name
|
||||
*
|
||||
|
Reference in New Issue
Block a user