mirror of
https://github.com/processwire/processwire.git
synced 2025-08-15 11:14:12 +02:00
Add support for hooking multiple methods to the same event handler via addHook*() calls by separating the methods to hook with commas, or by providing an array rather than a string. Also updated the corresponding removeHook() method to support removing multiple in the same call.
This commit is contained in:
@@ -627,8 +627,9 @@ abstract class Wire implements WireTranslatable, WireFuelable, WireTrackable {
|
|||||||
*
|
*
|
||||||
* #pw-internal
|
* #pw-internal
|
||||||
*
|
*
|
||||||
* @param string $method Method name to hook into, NOT including the three preceding underscores.
|
* @param string|array $method Method name to hook into, NOT including the three preceding underscores.
|
||||||
* May also be Class::Method for same result as using the fromClass option.
|
* May also be Class::Method for same result as using the fromClass option.
|
||||||
|
* May also be array or CSV string of hook definitions to attach multiple to the same $toMethod (since 3.0.137).
|
||||||
* @param object|null|callable $toObject Object to call $toMethod from,
|
* @param object|null|callable $toObject Object to call $toMethod from,
|
||||||
* Or null if $toMethod is a function outside of an object,
|
* 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.
|
* Or function|callable if $toObject is not applicable or function is provided as a closure.
|
||||||
@@ -650,8 +651,10 @@ abstract class Wire implements WireTranslatable, WireFuelable, WireTrackable {
|
|||||||
* must match, in order to execute hook. Default is null.
|
* must match, in order to execute hook. Default is null.
|
||||||
* - `objMatch` (array|null): Selectors object that the current object must match in order to execute hook.
|
* - `objMatch` (array|null): Selectors object that the current object must match in order to execute hook.
|
||||||
* Default is null.
|
* Default is null.
|
||||||
* @return string A special Hook ID that should be retained if you need to remove the hook later
|
* @return string A special Hook ID that should be retained if you need to remove the hook later.
|
||||||
|
* If multiple methods were hooked then it is a CSV string of hook IDs, accepted removeHook method (since 3.0.137).
|
||||||
* @throws WireException
|
* @throws WireException
|
||||||
|
* @see https://processwire.com/docs/modules/hooks/
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public function addHook($method, $toObject, $toMethod = null, $options = array()) {
|
public function addHook($method, $toObject, $toMethod = null, $options = array()) {
|
||||||
@@ -682,9 +685,10 @@ abstract class Wire implements WireTranslatable, WireFuelable, WireTrackable {
|
|||||||
*
|
*
|
||||||
* #pw-group-hooks
|
* #pw-group-hooks
|
||||||
*
|
*
|
||||||
* @param string $method Method to hook in one of the following formats (please omit 3 leading underscores):
|
* @param string|array $method Method to hook in one of the following formats (please omit 3 leading underscores):
|
||||||
* - `Class::method` - If hooking to *all* object instances of the class.
|
* - `Class::method` - If hooking to *all* object instances of the class.
|
||||||
* - `method` - If hooking to a single object instance.
|
* - `method` - If hooking to a single object instance.
|
||||||
|
* - Since 3.0.137 it may also be multiple methods to hook in CSV string or array.
|
||||||
* @param object|null|callable $toObject Specify one of the following:
|
* @param object|null|callable $toObject Specify one of the following:
|
||||||
* - Object instance to call `$toMethod` from (like `$this`).
|
* - Object instance to call `$toMethod` from (like `$this`).
|
||||||
* - Inline function (closure) if providing implemention inline.
|
* - Inline function (closure) if providing implemention inline.
|
||||||
@@ -698,7 +702,8 @@ abstract class Wire implements WireTranslatable, WireFuelable, WireTrackable {
|
|||||||
* rather than $obj->method(). The default type is 'method'.
|
* rather than $obj->method(). The default type is 'method'.
|
||||||
* - `priority` (int): A number determining the priority of a hook, where lower numbers are executed before
|
* - `priority` (int): A number determining the priority of a hook, where lower numbers are executed before
|
||||||
* higher numbers. The default priority is 100.
|
* higher numbers. The default priority is 100.
|
||||||
* @return string A special Hook ID that should be retained if you need to remove the hook later.
|
* @return string A special Hook ID (or CSV string of hook IDs) that should be retained if you need to remove the hook later.
|
||||||
|
* @see https://processwire.com/docs/modules/hooks/
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public function addHookBefore($method, $toObject, $toMethod = null, $options = array()) {
|
public function addHookBefore($method, $toObject, $toMethod = null, $options = array()) {
|
||||||
@@ -730,9 +735,10 @@ abstract class Wire implements WireTranslatable, WireFuelable, WireTrackable {
|
|||||||
*
|
*
|
||||||
* #pw-group-hooks
|
* #pw-group-hooks
|
||||||
*
|
*
|
||||||
* @param string $method Method to hook in one of the following formats (please omit 3 leading underscores):
|
* @param string|array $method Method to hook in one of the following formats (please omit 3 leading underscores):
|
||||||
* - `Class::method` - If hooking to *all* object instances of the class.
|
* - `Class::method` - If hooking to *all* object instances of the class.
|
||||||
* - `method` - If hooking to a single object instance.
|
* - `method` - If hooking to a single object instance.
|
||||||
|
* - Since 3.0.137 it may also be multiple methods to hook in CSV string or array.
|
||||||
* @param object|null|callable $toObject Specify one of the following:
|
* @param object|null|callable $toObject Specify one of the following:
|
||||||
* - Object instance to call `$toMethod` from (like `$this`).
|
* - Object instance to call `$toMethod` from (like `$this`).
|
||||||
* - Inline function (closure) if providing implemention inline.
|
* - Inline function (closure) if providing implemention inline.
|
||||||
@@ -746,7 +752,8 @@ abstract class Wire implements WireTranslatable, WireFuelable, WireTrackable {
|
|||||||
* rather than $obj->method(). The default type is 'method'.
|
* rather than $obj->method(). The default type is 'method'.
|
||||||
* - `priority` (int): A number determining the priority of a hook, where lower numbers are executed before
|
* - `priority` (int): A number determining the priority of a hook, where lower numbers are executed before
|
||||||
* higher numbers. The default priority is 100.
|
* higher numbers. The default priority is 100.
|
||||||
* @return string A special Hook ID that should be retained if you need to remove the hook later.
|
* @return string A special Hook ID (or CSV string of hook IDs) that should be retained if you need to remove the hook later.
|
||||||
|
* @see https://processwire.com/docs/modules/hooks/
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public function addHookAfter($method, $toObject, $toMethod = null, $options = array()) {
|
public function addHookAfter($method, $toObject, $toMethod = null, $options = array()) {
|
||||||
@@ -778,9 +785,10 @@ abstract class Wire implements WireTranslatable, WireFuelable, WireTrackable {
|
|||||||
*
|
*
|
||||||
* #pw-group-hooks
|
* #pw-group-hooks
|
||||||
*
|
*
|
||||||
* @param string $property Name of property you want to add, must not collide with existing property or method names:
|
* @param string|array $property Name of property you want to add, must not collide with existing property or method names:
|
||||||
* - `Class::property` to add the property to all instances of Class.
|
* - `Class::property` to add the property to all instances of Class.
|
||||||
* - `property` if just adding to a single object instance.
|
* - `property` if just adding to a single object instance.
|
||||||
|
* - Since 3.0.137 it may also be multiple properties to hook in CSV string or array.
|
||||||
* @param object|null|callable $toObject Specify one of the following:
|
* @param object|null|callable $toObject Specify one of the following:
|
||||||
* - Object instance to call `$toMethod` from (like `$this`).
|
* - Object instance to call `$toMethod` from (like `$this`).
|
||||||
* - Inline function (closure) if providing implemention inline.
|
* - Inline function (closure) if providing implemention inline.
|
||||||
@@ -790,7 +798,8 @@ abstract class Wire implements WireTranslatable, WireFuelable, WireTrackable {
|
|||||||
* This argument can be sustituted as the 2nd argument when the 2nd argument isn’t needed,
|
* This argument can be sustituted as the 2nd argument when the 2nd argument isn’t needed,
|
||||||
* or it can be the $options argument.
|
* 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.
|
* @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.
|
* @return string A special Hook ID (or CSV string of hook IDs) that should be retained if you need to remove the hook later.
|
||||||
|
* @see https://processwire.com/docs/modules/hooks/
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public function addHookProperty($property, $toObject, $toMethod = null, $options = array()) {
|
public function addHookProperty($property, $toObject, $toMethod = null, $options = array()) {
|
||||||
@@ -841,6 +850,7 @@ abstract class Wire implements WireTranslatable, WireFuelable, WireTrackable {
|
|||||||
* @param string $method Name of method you want to add, must not collide with existing property or method names:
|
* @param string $method Name of method you want to add, must not collide with existing property or method names:
|
||||||
* - `Class::method` to add the method to all instances of Class.
|
* - `Class::method` to add the method to all instances of Class.
|
||||||
* - `method` to just add to a single object instance.
|
* - `method` to just add to a single object instance.
|
||||||
|
* - Since 3.0.137 it may also be multiple methods to hook in CSV string or array.
|
||||||
* @param object|null|callable $toObject Specify one of the following:
|
* @param object|null|callable $toObject Specify one of the following:
|
||||||
* - Object instance to call `$toMethod` from (like `$this`).
|
* - Object instance to call `$toMethod` from (like `$this`).
|
||||||
* - Inline function (closure) if providing implemention inline.
|
* - Inline function (closure) if providing implemention inline.
|
||||||
@@ -850,8 +860,9 @@ abstract class Wire implements WireTranslatable, WireFuelable, WireTrackable {
|
|||||||
* This argument can be sustituted as the 2nd argument when the 2nd argument isn’t needed,
|
* This argument can be sustituted as the 2nd argument when the 2nd argument isn’t needed,
|
||||||
* or it can be the $options argument.
|
* 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.
|
* @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.
|
* @return string A special Hook ID (or CSV string of hook IDs) 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.
|
* @since 3.0.16 Added as an alias to addHook() for syntactic clarity, previous versions can use addHook() method with same arguments.
|
||||||
|
* @see https://processwire.com/docs/modules/hooks/
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public function addHookMethod($method, $toObject, $toMethod = null, $options = array()) {
|
public function addHookMethod($method, $toObject, $toMethod = null, $options = array()) {
|
||||||
@@ -882,7 +893,8 @@ abstract class Wire implements WireTranslatable, WireFuelable, WireTrackable {
|
|||||||
*
|
*
|
||||||
* #pw-group-hooks
|
* #pw-group-hooks
|
||||||
*
|
*
|
||||||
* @param string|null $hookId ID of hook to remove (ID is returned by the addHook() methods)
|
* @param string|array|null $hookId ID of hook to remove (ID is returned by the addHook() methods)
|
||||||
|
* Since 3.0.137 it may also be an array or CSV string of hook IDs to remove.
|
||||||
* @return $this
|
* @return $this
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
@@ -265,9 +265,13 @@ class WireData extends Wire implements \IteratorAggregate, \ArrayAccess {
|
|||||||
$keys = array();
|
$keys = array();
|
||||||
}
|
}
|
||||||
if($from->wire($key) !== null) return null; // don't allow API vars to be retrieved this way
|
if($from->wire($key) !== null) return null; // don't allow API vars to be retrieved this way
|
||||||
if($from instanceof WireData) $value = $from->get($key);
|
if($from instanceof WireData) {
|
||||||
else if($from instanceof WireArray) $value = $from->getProperty($key);
|
$value = $from->get($key);
|
||||||
else $value = $from->$key;
|
} else if($from instanceof WireArray) {
|
||||||
|
$value = $from->getProperty($key);
|
||||||
|
} else {
|
||||||
|
$value = $from->$key;
|
||||||
|
}
|
||||||
if(!count($keys)) return $value; // final value
|
if(!count($keys)) return $value; // final value
|
||||||
if(is_object($value)) {
|
if(is_object($value)) {
|
||||||
if(count($keys) > 1) {
|
if(count($keys) > 1) {
|
||||||
|
@@ -474,19 +474,26 @@ class WireHooks {
|
|||||||
* $this->addHook($method, 'function_name'); or $this->addHook($method, 'function_name', $options);
|
* $this->addHook($method, 'function_name'); or $this->addHook($method, 'function_name', $options);
|
||||||
*
|
*
|
||||||
* @param Wire $object
|
* @param Wire $object
|
||||||
* @param string $method Method name to hook into, NOT including the three preceding underscores.
|
* @param string|array $method Method name to hook into, NOT including the three preceding underscores.
|
||||||
* May also be Class::Method for same result as using the fromClass option.
|
* May also be Class::Method for same result as using the fromClass option.
|
||||||
|
* May also be array OR CSV string of either of the above to add multiple (since 3.0.137).
|
||||||
* @param object|null|callable $toObject Object to call $toMethod from,
|
* @param object|null|callable $toObject Object to call $toMethod from,
|
||||||
* Or null if $toMethod is a function outside of an object,
|
* 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.
|
* Or function|callable if $toObject is not applicable or function is provided as a closure.
|
||||||
* @param string|array $toMethod Method from $toObject, or function name to call on a hook event, or $options array.
|
* @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.
|
* @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
|
* @return string A special Hook ID that should be retained if you need to remove the hook later.
|
||||||
|
* If the $method argument was a CSV string or array of multiple methods to hook, then CSV string of hook IDs
|
||||||
|
* will be returned, and the same CSV string can be used with removeHook() calls. (since 3.0.137).
|
||||||
* @throws WireException
|
* @throws WireException
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public function addHook(Wire $object, $method, $toObject, $toMethod = null, $options = array()) {
|
public function addHook(Wire $object, $method, $toObject, $toMethod = null, $options = array()) {
|
||||||
|
|
||||||
|
if(is_array($method) || strpos($method, ',') !== false) {
|
||||||
|
return $this->addHooks($object, $method, $toObject, $toMethod, $options);
|
||||||
|
}
|
||||||
|
|
||||||
if(is_array($toMethod)) {
|
if(is_array($toMethod)) {
|
||||||
// $options array specified as 3rd argument
|
// $options array specified as 3rd argument
|
||||||
if(count($options)) {
|
if(count($options)) {
|
||||||
@@ -673,6 +680,77 @@ class WireHooks {
|
|||||||
return $id;
|
return $id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a hooks to multiple methods at once
|
||||||
|
*
|
||||||
|
* This is the same as addHook() except that the $method argument is an array or CSV string of hook definitions.
|
||||||
|
* See the addHook() method for more detailed info on arguments.
|
||||||
|
*
|
||||||
|
* @param Wire $object
|
||||||
|
* @param array|string $methods Array of one or more strings hook definitions, or CSV string of hook definitions
|
||||||
|
* @param object|null|callable $toObject
|
||||||
|
* @param string|array|null $toMethod
|
||||||
|
* @param array $options
|
||||||
|
* @return string CSV string of hook IDs that were added
|
||||||
|
* @throws WireException
|
||||||
|
* @since 3.0.137
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
protected function addHooks(Wire $object, $methods, $toObject, $toMethod = null, $options = array()) {
|
||||||
|
|
||||||
|
if(!is_array($methods)) {
|
||||||
|
// potentially multiple methods defined in a CSV string
|
||||||
|
// could also be a single method with CSV arguments
|
||||||
|
|
||||||
|
$str = (string) $methods;
|
||||||
|
$argSplit = '|';
|
||||||
|
|
||||||
|
// skip optional useless parenthesis in definition to avoid unnecessary iterations
|
||||||
|
if(strpos($str, '()') !== false) $str = str_replace('()', '', $str);
|
||||||
|
|
||||||
|
if(strpos($str, '(') === false) {
|
||||||
|
// If there is a parenthesis then it is multi-method definition without arguments
|
||||||
|
// Example: "Pages::saveReady, Pages::saved"
|
||||||
|
$methods = explode(',', $str);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// Single or multi-method definitions, at least one with arguments
|
||||||
|
// Isolate commas that are for arguments versus comments that separate multiple hook methods:
|
||||||
|
// Single method example: "Page(template=order)::changed(0:order_status, 1:name=pending)"
|
||||||
|
// Multi method example: "Page(template=order)::changed(0:order_status, 1:name=pending), Page::saved"
|
||||||
|
|
||||||
|
while(strpos($str, $argSplit) !== false) $argSplit .= '|';
|
||||||
|
$strs = explode('(', $str);
|
||||||
|
|
||||||
|
foreach($strs as $key => $val) {
|
||||||
|
if(strpos($val, ')') === false) continue;
|
||||||
|
list($a, $b) = explode(')', $val, 2);
|
||||||
|
if(strpos($a, ',') !== false) $a = str_replace(array(', ', ','), $argSplit, $a);
|
||||||
|
$strs[$key] = "$a)$b";
|
||||||
|
}
|
||||||
|
|
||||||
|
$str = implode('(', $strs);
|
||||||
|
$methods = explode(',', $str);
|
||||||
|
|
||||||
|
foreach($methods as $key => $method) {
|
||||||
|
if(strpos($method, $argSplit) === false) continue;
|
||||||
|
$methods[$key] = str_replace($argSplit, ', ', $method);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$result = array();
|
||||||
|
|
||||||
|
foreach($methods as $method) {
|
||||||
|
$method = trim($method);
|
||||||
|
$hookID = $this->addHook($object, $method, $toObject, $toMethod, $options);
|
||||||
|
$result[] = $hookID;
|
||||||
|
}
|
||||||
|
|
||||||
|
$result = implode(',', $result);
|
||||||
|
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides the implementation for calling hooks in ProcessWire
|
* Provides the implementation for calling hooks in ProcessWire
|
||||||
@@ -926,11 +1004,14 @@ class WireHooks {
|
|||||||
* }
|
* }
|
||||||
*
|
*
|
||||||
* @param Wire $object
|
* @param Wire $object
|
||||||
* @param string|null $hookID
|
* @param string|array|null $hookID Can be single hook ID, array of hook IDs, or CSV string of hook IDs
|
||||||
* @return Wire
|
* @return Wire
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public function removeHook(Wire $object, $hookID) {
|
public function removeHook(Wire $object, $hookID) {
|
||||||
|
if(is_array($hookID) || strpos($hookID, ',')) {
|
||||||
|
return $this->removeHooks($object, $hookID);
|
||||||
|
}
|
||||||
if(!empty($hookID) && strpos($hookID, ':')) {
|
if(!empty($hookID) && strpos($hookID, ':')) {
|
||||||
list($hookClass, $priority, $method) = explode(':', $hookID);
|
list($hookClass, $priority, $method) = explode(':', $hookID);
|
||||||
if(empty($hookClass)) {
|
if(empty($hookClass)) {
|
||||||
@@ -947,6 +1028,23 @@ class WireHooks {
|
|||||||
return $object;
|
return $object;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Given a hook ID or multiple hook IDs (in array or CSV string) remove the hooks
|
||||||
|
*
|
||||||
|
* @param Wire $object
|
||||||
|
* @param array|string $hookIDs
|
||||||
|
* @return Wire
|
||||||
|
* @since 3.0.137
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
protected function removeHooks(Wire $object, $hookIDs) {
|
||||||
|
if(!is_array($hookIDs)) $hookIDs = explode(',', $hookIDs);
|
||||||
|
foreach($hookIDs as $hookID) {
|
||||||
|
$this->removeHook($object, $hookID);
|
||||||
|
}
|
||||||
|
return $object;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the "all local hooks" cache
|
* Return the "all local hooks" cache
|
||||||
*
|
*
|
||||||
|
Reference in New Issue
Block a user