diff options
Diffstat (limited to 'includes/libs/ObjectFactory.php')
-rw-r--r-- | includes/libs/ObjectFactory.php | 49 |
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 ); + } } |