summaryrefslogtreecommitdiff
path: root/includes/libs/ObjectFactory.php
diff options
context:
space:
mode:
Diffstat (limited to 'includes/libs/ObjectFactory.php')
-rw-r--r--includes/libs/ObjectFactory.php49
1 files changed, 38 insertions, 11 deletions
diff --git a/includes/libs/ObjectFactory.php b/includes/libs/ObjectFactory.php
index ec8c36a1..1cb544b8 100644
--- a/includes/libs/ObjectFactory.php
+++ b/includes/libs/ObjectFactory.php
@@ -49,6 +49,13 @@ class ObjectFactory {
* constructor/callable. This behavior can be suppressed by adding
* closure_expansion => false to the specification.
*
+ * The specification may also contain a 'calls' key that describes method
+ * calls to make on the newly created object before returning it. This
+ * pattern is often known as "setter injection". The value of this key is
+ * expected to be an associative array with method names as keys and
+ * argument lists as values. The argument list will be expanded (or not)
+ * in the same way as the 'args' key for the main object.
+ *
* @param array $spec Object specification
* @return object
* @throws InvalidArgumentException when object specification does not
@@ -58,18 +65,11 @@ class ObjectFactory {
*/
public static function getObjectFromSpec( $spec ) {
$args = isset( $spec['args'] ) ? $spec['args'] : array();
+ $expandArgs = !isset( $spec['closure_expansion'] ) ||
+ $spec['closure_expansion'] === true;
- if ( !isset( $spec['closure_expansion'] ) ||
- $spec['closure_expansion'] === true
- ) {
- $args = array_map( function ( $value ) {
- if ( is_object( $value ) && $value instanceof Closure ) {
- // If an argument is a Closure, call it.
- return $value();
- } else {
- return $value;
- }
- }, $args );
+ if ( $expandArgs ) {
+ $args = static::expandClosures( $args );
}
if ( isset( $spec['class'] ) ) {
@@ -88,6 +88,33 @@ class ObjectFactory {
);
}
+ if ( isset( $spec['calls'] ) && is_array( $spec['calls'] ) ) {
+ // Call additional methods on the newly created object
+ foreach ( $spec['calls'] as $method => $margs ) {
+ if ( $expandArgs ) {
+ $margs = static::expandClosures( $margs );
+ }
+ call_user_func_array( array( $obj, $method ), $margs );
+ }
+ }
+
return $obj;
}
+
+ /**
+ * Iterate a list and call any closures it contains.
+ *
+ * @param array $list List of things
+ * @return array List with any Closures replaced with their output
+ */
+ protected static function expandClosures( $list ) {
+ return array_map( function ( $value ) {
+ if ( is_object( $value ) && $value instanceof Closure ) {
+ // If $value is a Closure, call it.
+ return $value();
+ } else {
+ return $value;
+ }
+ }, $list );
+ }
}