/** * @inheritDoc */ public function applyInflections($object) { foreach ($this->inflections as $type => $methods) { if (!$object instanceof $type) { continue; } foreach ($methods as $method => $inflection) { // $inflection may be array of arguments to pass to the method // OR prepared closure to call with the provided object context. if (!is_callable($inflection)) { // Reflect and resolve method arguments. $callback = $this->argumentResolver->resolveArguments($this->argumentResolver->reflectCallable([$type, $method])); // Replace method arguments with provided ones (if any). $arguments = $callback($inflection); // Wrap calling method with closure to avoid reflecting / resolving each time inflection applied. $this->inflections[$type][$method] = $inflection = function () use($method, $arguments) { $this->{$method}(...$arguments); }; } // We have callable inflection ready, so we simply swap the context to provided object and call it. $inflection->call($object); } } return $object; }
/** * Create callable factory with resolved arguments from callable. * * @param callable $callable Normalized callable. * @return Closure */ private function createServiceFactoryFromCallable($callable) : Closure { $reflection = $this->argumentResolver->reflectCallable($callable); // Wrap reflected function arguments with closure. $resolve = $this->argumentResolver->resolveArguments($reflection); if (is_array($callable)) { list($object, $method) = $callable; if (!$reflection->isStatic() && is_string($object)) { $object = $this->get($object); } // Wrap with Closure to save reflection resolve results. return function (array $arguments = []) use($object, $method, $resolve) { return [$object, $method](...$resolve($arguments)); }; } // We have Closure or "functionName" string. return function (array $arguments = []) use($callable, $resolve) { return $callable(...$resolve($arguments)); }; }