getClassName($className); return sprintf( self::FACTORY_TEMPLATE, str_replace('\\' . $class, '', $className), $className, $class, $class, $class, $this->createArgumentString($className) ); } /** * @param $className * @return string */ private function getClassName($className) { $class = substr($className, strrpos($className, '\\') + 1); return $class; } /** * @param string $className * @return array */ private function getConstructorParameters($className) { $reflectionClass = new ReflectionClass($className); if (! $reflectionClass || ! $reflectionClass->getConstructor()) { return []; } $constructorParameters = $reflectionClass->getConstructor()->getParameters(); if (empty($constructorParameters)) { return []; } $constructorParameters = array_filter( $constructorParameters, function (ReflectionParameter $argument) { if ($argument->isOptional()) { return false; } if (null === $argument->getClass()) { throw new InvalidArgumentException(sprintf( 'Cannot identify type for constructor argument "%s"; ' . 'no type hint, or non-class/interface type hint', $argument->getName() )); } return true; } ); if (empty($constructorParameters)) { return []; } return array_map(function (ReflectionParameter $parameter) { return $parameter->getClass()->getName(); }, $constructorParameters); } /** * @param string $className * @return string */ private function createArgumentString($className) { $arguments = array_map(function ($dependency) { return sprintf('$container->get(\\%s::class)', $dependency); }, $this->getConstructorParameters($className)); switch (count($arguments)) { case 0: return ''; case 1: return array_shift($arguments); default: $argumentPad = str_repeat(' ', 12); $closePad = str_repeat(' ', 8); return sprintf( "\n%s%s\n%s", $argumentPad, implode(",\n" . $argumentPad, $arguments), $closePad ); } } }