1
0
mirror of https://github.com/processwire/processwire.git synced 2025-08-11 01:04:16 +02:00

Add support for combined hooks that can be executed as either method or property per issue processwire/processwire-issues#232

This commit is contained in:
Ryan Cramer
2019-03-29 11:07:40 -04:00
parent c4086084d8
commit 478d299322
2 changed files with 34 additions and 29 deletions

View File

@@ -632,10 +632,10 @@ abstract class Wire implements WireTranslatable, WireFuelable, WireTrackable {
* @param object|null|callable $toObject Object to call $toMethod from,
* Or null if $toMethod is a function outside of an object,
* Or function|callable if $toObject is not applicable or function is provided as a closure.
* @param string $toMethod Method from $toObject, or function name to call on a hook event. Optional.
* @param string|array $toMethod Method from $toObject, or function name to call on a hook event, or $options array. Optional.
* @param array $options Options that can modify default behaviors:
* - `type` (string): May be either 'method' or 'property'. If property, then it will respond to $obj->property
* rather than $obj->method(). The default type is 'method'.
* - `type` (string): May be 'method', 'property' or 'either'. If property, then it will respond to $obj->property
* rather than $obj->method(). If 'either' it will respond to both. The default type is 'method'.
* - `before` (bool): Execute the hook before the method call? (allows modification of arguments).
* Not applicable if 'type' is 'property'.
* - `after` (bool): Execute the hook after the method call? (allows modification of return value).
@@ -690,8 +690,9 @@ abstract class Wire implements WireTranslatable, WireFuelable, WireTrackable {
* - Inline function (closure) if providing implemention inline.
* - Procedural function name, if hook is implemented by a procedural function.
* - Null if you want to use the 3rd argument and don't need this argument.
* @param string $toMethod Method from $toObject, or function name to call on a hook event.
* This argument can be sustituted as the 2nd argument when the 2nd argument isn't needed.
* @param string|array $toMethod Method from $toObject, or function name to call on a hook event.
* This argument can be sustituted as the 2nd argument when the 2nd argument isnt needed,
* or it can be the $options argument.
* @param array $options Array of options that can modify behavior:
* - `type` (string): May be either 'method' or 'property'. If property, then it will respond to $obj->property
* rather than $obj->method(). The default type is 'method'.
@@ -737,8 +738,9 @@ abstract class Wire implements WireTranslatable, WireFuelable, WireTrackable {
* - Inline function (closure) if providing implemention inline.
* - Procedural function name, if hook is implemented by a procedural function.
* - Null if you want to use the 3rd argument and don't need this argument.
* @param string $toMethod Method from $toObject, or function name to call on a hook event.
* This argument can be sustituted as the 2nd argument when the 2nd argument isn't needed.
* @param string|array $toMethod Method from $toObject, or function name to call on a hook event.
* This argument can be sustituted as the 2nd argument when the 2nd argument isn't needed,
* or it can be the $options argument.
* @param array $options Array of options that can modify behavior:
* - `type` (string): May be either 'method' or 'property'. If property, then it will respond to $obj->property
* rather than $obj->method(). The default type is 'method'.
@@ -784,8 +786,9 @@ abstract class Wire implements WireTranslatable, WireFuelable, WireTrackable {
* - Inline function (closure) if providing implemention inline.
* - Procedural function name, if hook is implemented by a procedural function.
* - Null if you want to use the 3rd argument and don't need this argument.
* @param string $toMethod Method from $toObject, or function name to call on a hook event.
* This argument can be sustituted as the 2nd argument when the 2nd argument isn't needed.
* @param string|array $toMethod Method from $toObject, or function name to call on a hook event.
* This argument can be sustituted as the 2nd argument when the 2nd argument isnt needed,
* or it can be the $options argument.
* @param array $options Options typically aren't used in this context, but see Wire::addHookBefore() $options if you'd like.
* @return string A special Hook ID that should be retained if you need to remove the hook later.
*
@@ -843,8 +846,9 @@ abstract class Wire implements WireTranslatable, WireFuelable, WireTrackable {
* - Inline function (closure) if providing implemention inline.
* - Procedural function name, if hook is implemented by a procedural function.
* - Null if you want to use the 3rd argument and don't need this argument.
* @param string $toMethod Method from $toObject, or function name to call on a hook event.
* This argument can be sustituted as the 2nd argument when the 2nd argument isn't needed.
* @param string|array $toMethod Method from $toObject, or function name to call on a hook event.
* This argument can be sustituted as the 2nd argument when the 2nd argument isnt needed,
* or it can be the $options argument.
* @param array $options Options typically aren't used in this context, but see Wire::addHookBefore() $options if you'd like.
* @return string A special Hook ID that should be retained if you need to remove the hook later.
* @since 3.0.16 Added as an alias to addHook() for syntactic clarity, previous versions can use addHook() method with same arguments.

View File

@@ -138,23 +138,22 @@ class WireHooks {
*
* @param Wire $object
* @param string $method Optional method that hooks will be limited to. Or specify '*' to return all hooks everywhere.
* @param int $type Type of hooks to return, specify one of the following constants:
* @param int $getHooks Get hooks of type, specify one of the following constants:
* - WireHooks::getHooksAll returns all hooks [0] (default)
* - WireHooks::getHooksLocal returns local hooks [1] only
* - WireHooks::getHooksStatic returns static hooks [2] only
* @return array
*
*/
public function getHooks(Wire $object, $method = '', $type = self::getHooksAll) {
public function getHooks(Wire $object, $method = '', $getHooks = self::getHooksAll) {
$hooks = array();
// see if we can do a quick exit
if($method && $method !== '*' && !$this->isHookedOrParents($object, $method)) return $hooks;
// first determine which local hooks when should include
if($type !== self::getHooksStatic) {
if($getHooks !== self::getHooksStatic) {
$localHooks = $object->getLocalHooks();
if($method && $method !== '*') {
// populate all local hooks for given method
@@ -170,7 +169,7 @@ class WireHooks {
}
// if only local hooks requested, we can return them now
if($type === self::getHooksLocal) return $hooks;
if($getHooks === self::getHooksLocal) return $hooks;
$needSort = false;
$namespace = __NAMESPACE__ ? __NAMESPACE__ . "\\" : "";
@@ -480,7 +479,7 @@ class WireHooks {
* @param object|null|callable $toObject Object to call $toMethod from,
* Or null if $toMethod is a function outside of an object,
* Or function|callable if $toObject is not applicable or function is provided as a closure.
* @param string $toMethod Method from $toObject, or function name to call on a hook event. Optional.
* @param string|array $toMethod Method from $toObject, or function name to call on a hook event, or $options array.
* @param array $options See $defaultHookOptions at the beginning of this class. Optional.
* @return string A special Hook ID that should be retained if you need to remove the hook later
* @throws WireException
@@ -713,7 +712,7 @@ class WireHooks {
'replace' => false,
);
if($type === 'method' || $type === 'property') {
if($type === 'method' || $type === 'property' || $type === 'either') {
if(!$result['methodExists'] && !$this->isHookedOrParents($object, $method, $type)) {
return $result; // exit quickly when we can
}
@@ -740,6 +739,8 @@ class WireHooks {
foreach($hooks as $priority => $hook) {
if(!$hook['options'][$when]) continue;
if($type === 'property' && $hook['options']['type'] === 'method') continue;
if($type === 'method' && $hook['options']['type'] === 'property') continue;
if(!empty($hook['options']['objMatch'])) {
/** @var Selectors $objMatch */