/** * @return object */ public function __call($name, $args) { if (substr($name, 0, 6) === 'create') { return call_user_func_array(array($this->container, Container::getMethodName($this->namespace . substr($name, 6), false)), $args); } throw new Nette\NotSupportedException(); }
public function prepareFilters(Template $template) { $this->latte = $this->latteFactory->invoke(); foreach ($this->macroFactories as $factory) { $this->container->{Container::getMethodName($factory, FALSE)}($this->latte->getCompiler()); } $template->registerFilter($this->latte); }
public function create($type, $data) { if (!isset($this->services[$type])) { throw new Nette\InvalidArgumentException(); } $service = $this->services[$type]; $method = Container::getMethodName($service, FALSE); return $this->container->{$method}($data); }
public function afterCompile(Nette\PhpGenerator\ClassType $class) { if (!empty($this->config['cache'])) { $method = $class->getMethod(Nette\DI\Container::getMethodName($this->prefix('router'))); try { $router = serialize(eval($method->getBody())); } catch (\Exception $e) { throw new Nette\DI\ServiceCreationException('Unable to cache router due to error: ' . $e->getMessage(), 0, $e); } $method->setBody('return unserialize(?);', [$router]); } }
public function afterCompile(Nette\PhpGenerator\ClassType $class) { if (!empty($this->config['cache'])) { $method = $class->getMethod(Nette\DI\Container::getMethodName($this->prefix('router'))); try { $router = eval($method->getBody()); if ($router instanceof Nette\Application\Routers\RouteList) { $router->warmupCache(); } $s = serialize($router); } catch (\Throwable $e) { throw new Nette\DI\ServiceCreationException('Unable to cache router due to error: ' . $e->getMessage(), 0, $e); } catch (\Exception $e) { throw new Nette\DI\ServiceCreationException('Unable to cache router due to error: ' . $e->getMessage(), 0, $e); } $method->setBody('return unserialize(?);', array($s)); } }
public function processServices() { $this->parseServices($this->container, $this->config); foreach ($this->extensions as $name => $extension) { $this->container->addDefinition($name)->setClass('Nette\\DI\\NestedAccessor', array('@container', $name))->setAutowired(FALSE); if (isset($this->config[$name])) { $this->parseServices($this->container, $this->config[$name], $name); } } foreach ($this->container->getDefinitions() as $name => $def) { $factory = $name . 'Factory'; if (!$def->shared && !$def->internal && !$this->container->hasDefinition($factory)) { $this->container->addDefinition($factory)->setClass('Nette\\Callback', array('@container', Nette\DI\Container::getMethodName($name, FALSE)))->setAutowired(FALSE)->tags = $def->tags; } } }
/** * Formats PHP code for class instantiating, function calling or property setting in PHP. * @return string * @internal */ public function formatStatement(Statement $statement) { $entity = $this->normalizeEntity($statement->getEntity()); $arguments = $statement->arguments; if (is_string($entity) && Strings::contains($entity, '?')) { // PHP literal return $this->formatPhp($entity, $arguments); } elseif ($service = $this->getServiceName($entity)) { // factory calling $params = []; foreach ($this->definitions[$service]->parameters as $k => $v) { $params[] = preg_replace('#\\w+\\z#', '\\$$0', is_int($k) ? $v : $k) . (is_int($k) ? '' : ' = ' . PhpHelpers::dump($v)); } $rm = new \ReflectionFunction(create_function(implode(', ', $params), '')); $arguments = Helpers::autowireArguments($rm, $arguments, $this); return $this->formatPhp('$this->?(?*)', [Container::getMethodName($service), $arguments]); } elseif ($entity === 'not') { // operator return $this->formatPhp('!?', [$arguments[0]]); } elseif (is_string($entity)) { // class name if ($constructor = (new ReflectionClass($entity))->getConstructor()) { $this->addDependency((string) $constructor->getFileName()); $arguments = Helpers::autowireArguments($constructor, $arguments, $this); } elseif ($arguments) { throw new ServiceCreationException("Unable to pass arguments, class {$entity} has no constructor."); } return $this->formatPhp("new {$entity}" . ($arguments ? '(?*)' : ''), [$arguments]); } elseif (!Nette\Utils\Arrays::isList($entity) || count($entity) !== 2) { throw new ServiceCreationException(sprintf('Expected class, method or property, %s given.', PhpHelpers::dump($entity))); } elseif (!preg_match('#^\\$?' . PhpHelpers::PHP_IDENT . '\\z#', $entity[1])) { throw new ServiceCreationException("Expected function, method or property name, '{$entity['1']}' given."); } elseif ($entity[0] === '') { // globalFunc return $this->formatPhp("{$entity['1']}(?*)", [$arguments]); } elseif ($entity[0] instanceof Statement) { $inner = $this->formatPhp('?', [$entity[0]]); if (substr($inner, 0, 4) === 'new ') { $inner = "({$inner})"; } return $this->formatPhp("{$inner}->?(?*)", [$entity[1], $arguments]); } elseif (Strings::contains($entity[1], '$')) { // property setter Validators::assert($arguments, 'list:1', "setup arguments for '" . Nette\Utils\Callback::toString($entity) . "'"); if ($this->getServiceName($entity[0])) { return $this->formatPhp('?->? = ?', [$entity[0], substr($entity[1], 1), $arguments[0]]); } else { return $this->formatPhp($entity[0] . '::$? = ?', [substr($entity[1], 1), $arguments[0]]); } } elseif ($service = $this->getServiceName($entity[0])) { // service method $class = $this->definitions[$service]->getImplement(); if (!$class || !method_exists($class, $entity[1])) { $class = $this->definitions[$service]->getClass(); } if ($class) { $arguments = $this->autowireArguments($class, $entity[1], $arguments); } return $this->formatPhp('?->?(?*)', [$entity[0], $entity[1], $arguments]); } else { // static method $arguments = $this->autowireArguments($entity[0], $entity[1], $arguments); return $this->formatPhp("{$entity['0']}::{$entity['1']}(?*)", [$arguments]); } }
/** * Does the service exist? * @param string service name * @return bool */ public function hasService($name) { return isset($this->registry[$name]) || isset($this->factories[$name]) || method_exists($this, $method = Container::getMethodName($name)) && $this->getReflection()->getMethod($method)->getName() === $method; }
/** * Formats PHP code for class instantiating, function calling or property setting in PHP. * @return string * @internal */ public function formatStatement(Statement $statement, $self = NULL) { $entity = $this->normalizeEntity($statement->entity); $arguments = $statement->arguments; if (is_string($entity) && Strings::contains($entity, '?')) { // PHP literal return $this->formatPhp($entity, $arguments, $self); } elseif ($service = $this->getServiceName($entity)) { // factory calling or service retrieving if ($this->definitions[$service]->shared) { if ($arguments) { throw new ServiceCreationException("Unable to call service '{$entity}'."); } return $this->formatPhp('$this->getService(?)', array($service)); } $params = array(); foreach ($this->definitions[$service]->parameters as $k => $v) { $params[] = preg_replace('#\\w+$#', '\\$$0', is_int($k) ? $v : $k) . (is_int($k) ? '' : ' = ' . PhpHelpers::dump($v)); } $rm = new Nette\Reflection\GlobalFunction(create_function(implode(', ', $params), '')); $arguments = Helpers::autowireArguments($rm, $arguments, $this); return $this->formatPhp('$this->?(?*)', array(Container::getMethodName($service, FALSE), $arguments), $self); } elseif ($entity === 'not') { // operator return $this->formatPhp('!?', array($arguments[0])); } elseif (is_string($entity)) { // class name if ($constructor = Nette\Reflection\ClassType::from($entity)->getConstructor()) { $this->addDependency($constructor->getFileName()); $arguments = Helpers::autowireArguments($constructor, $arguments, $this); } elseif ($arguments) { throw new ServiceCreationException("Unable to pass arguments, class {$entity} has no constructor."); } return $this->formatPhp("new {$entity}" . ($arguments ? '(?*)' : ''), array($arguments), $self); } elseif (!Validators::isList($entity) || count($entity) !== 2) { throw new Nette\InvalidStateException("Expected class, method or property, " . PhpHelpers::dump($entity) . " given."); } elseif ($entity[0] === '') { // globalFunc return $this->formatPhp("{$entity['1']}(?*)", array($arguments), $self); } elseif (Strings::contains($entity[1], '$')) { // property setter Validators::assert($arguments, 'list:1', "setup arguments for '" . Nette\Callback::create($entity) . "'"); if ($this->getServiceName($entity[0], $self)) { return $this->formatPhp('?->? = ?', array($entity[0], substr($entity[1], 1), $arguments[0]), $self); } else { return $this->formatPhp($entity[0] . '::$? = ?', array(substr($entity[1], 1), $arguments[0]), $self); } } elseif ($service = $this->getServiceName($entity[0], $self)) { // service method if ($this->definitions[$service]->class) { $arguments = $this->autowireArguments($this->definitions[$service]->class, $entity[1], $arguments); } return $this->formatPhp('?->?(?*)', array($entity[0], $entity[1], $arguments), $self); } else { // static method $arguments = $this->autowireArguments($entity[0], $entity[1], $arguments); return $this->formatPhp("{$entity['0']}::{$entity['1']}(?*)", array($arguments), $self); } }
/** * Creates new instance of the service. * @param string service name * @return object * @throws MissingServiceException */ public function createService($name, array $args = array()) { $method = Container::getMethodName($name); if (isset($this->creating[$name])) { throw new Nette\InvalidStateException(sprintf('Circular reference detected for services: %s.', implode(', ', array_keys($this->creating)))); } elseif (!method_exists($this, $method) || $this->getReflection()->getMethod($method)->getName() !== $method) { throw new MissingServiceException("Service '{$name}' not found."); } $this->creating[$name] = TRUE; try { $service = call_user_func_array(array($this, $method), $args); } catch (\Exception $e) { unset($this->creating[$name]); throw $e; } unset($this->creating[$name]); if (!is_object($service)) { throw new Nette\UnexpectedValueException("Unable to create service '{$name}', value returned by method {$method}() is not object."); } return $service; }
protected function processRepositoryFactoryEntities(Code\ClassType $class) { if (empty($this->postCompileRepositoriesQueue)) { return; } $dic = self::evalAndInstantiateContainer($class); foreach ($this->postCompileRepositoriesQueue as $manager => $items) { $config = $this->managerConfigs[$manager]; /** @var Kdyby\Doctrine\EntityManager $entityManager */ $entityManager = $dic->getService($this->configuredManagers[$manager]); /** @var Doctrine\ORM\Mapping\ClassMetadata $entityMetadata */ $metadataFactory = $entityManager->getMetadataFactory(); $allMetadata = []; foreach ($metadataFactory->getAllMetadata() as $entityMetadata) { if ($config['defaultRepositoryClassName'] === $entityMetadata->customRepositoryClassName || empty($entityMetadata->customRepositoryClassName)) { continue; } $allMetadata[ltrim($entityMetadata->customRepositoryClassName, '\\')] = $entityMetadata; } foreach ($items as $item) { if (!isset($allMetadata[$item[0]])) { throw new Nette\Utils\AssertionException(sprintf('Repository class %s have been found in DIC, but no entity has it assigned and it has no entity configured', $item[0])); } $entityMetadata = $allMetadata[$item[0]]; $serviceMethod = Nette\DI\Container::getMethodName($item[1]); $method = $class->getMethod($serviceMethod); $methodBody = $method->getBody(); $method->setBody(str_replace('"%entityName%"', Code\Helpers::format('?', $entityMetadata->getName()), $methodBody)); } } }
/** * Gets the service object by name. * * @param string * * @return object */ public function getService($name) { if (isset($this->registry[$name])) { return $this->registry[$name]; } elseif (isset($this->creating[$name])) { throw new Nette\InvalidStateException("Circular reference detected for services: " . implode(', ', array_keys($this->creating)) . "."); } if (isset($this->factories[$name])) { list($factory) = $this->factories[$name]; if (is_string($factory)) { if (!class_exists($factory)) { throw new Nette\InvalidStateException("Cannot instantiate service, class '{$factory}' not found."); } try { $this->creating[$name] = true; $service = new $factory(); } catch (\Exception $e) { } } elseif (!$factory->isCallable()) { throw new Nette\InvalidStateException("Unable to create service '{$name}', factory '{$factory}' is not callable."); } else { $this->creating[$name] = true; try { $service = $factory($this); } catch (\Exception $e) { } } } elseif (method_exists($this, $factory = Container::getMethodName($name)) && $this->getReflection()->getMethod($factory)->getName() === $factory) { $this->creating[$name] = true; try { $service = $this->{$factory}(); } catch (\Exception $e) { } } else { throw new MissingServiceException("Service '{$name}' not found."); } unset($this->creating[$name]); if (isset($e)) { throw $e; } elseif (!is_object($service)) { throw new Nette\UnexpectedValueException("Unable to create service '{$name}', value returned by factory '{$factory}' is not object."); } return $this->registry[$name] = $service; }
__construct(Container$container,$namespace){$this->container=$container;$this->namespace=$namespace.'.';$this->parameters=&$container->parameters[$namespace];}function __call($name,$args){if(substr($name,0,6)==='create'){return call_user_func_array(array($this->container,Container::getMethodName($this->namespace.substr($name,6),FALSE)),$args);}throw new Nette\NotSupportedException;}function&__get($name){$service=$this->container->getService($this->namespace.$name);return$service;}function
/** * Formats PHP code for class instantiating, function calling or property setting in PHP. * @return string */ private function formatStatement(Statement $statement) { $entity = $statement->getEntity(); $arguments = $statement->arguments; if (is_string($entity) && Strings::contains($entity, '?')) { // PHP literal return $this->formatPhp($entity, $arguments); } elseif ($service = $this->builder->getServiceName($entity)) { // factory calling return $this->formatPhp('$this->?(?*)', [Container::getMethodName($service), $arguments]); } elseif ($entity === 'not') { // operator return $this->formatPhp('!?', [$arguments[0]]); } elseif (is_string($entity)) { // class name return $this->formatPhp("new {$entity}" . ($arguments ? '(?*)' : ''), [$arguments]); } elseif ($entity[0] === '') { // globalFunc return $this->formatPhp("{$entity['1']}(?*)", [$arguments]); } elseif ($entity[0] instanceof Statement) { $inner = $this->formatPhp('?', [$entity[0]]); if (substr($inner, 0, 4) === 'new ') { $inner = "({$inner})"; } return $this->formatPhp("{$inner}->?(?*)", [$entity[1], $arguments]); } elseif ($entity[1][0] === '$') { // property getter, setter or appender $name = substr($entity[1], 1); if ($append = substr($name, -2) === '[]') { $name = substr($name, 0, -2); } if ($this->builder->getServiceName($entity[0])) { $prop = $this->formatPhp('?->?', [$entity[0], $name]); } else { $prop = $this->formatPhp($entity[0] . '::$?', [$name]); } return $arguments ? $this->formatPhp($prop . ($append ? '[]' : '') . ' = ?', [$arguments[0]]) : $prop; } elseif ($service = $this->builder->getServiceName($entity[0])) { // service method return $this->formatPhp('?->?(?*)', [$entity[0], $entity[1], $arguments]); } else { // static method return $this->formatPhp("{$entity['0']}::{$entity['1']}(?*)", [$arguments]); } }
/** * Formats PHP code for class instantiating, function calling or property setting in PHP. * @return string * @internal */ public function formatStatement(Statement $statement) { $entity = $this->normalizeEntity($statement->entity); $arguments = $statement->arguments; if (is_string($entity) && Strings::contains($entity, '?')) { // PHP literal return $this->formatPhp($entity, $arguments); } elseif ($service = $this->getServiceName($entity)) { // factory calling $params = array(); foreach ($this->definitions[$service]->parameters as $k => $v) { $params[] = preg_replace('#\w+\z#', '\$$0', (is_int($k) ? $v : $k)) . (is_int($k) ? '' : ' = ' . PhpHelpers::dump($v)); } $rm = new Reflection\GlobalFunction(create_function(implode(', ', $params), '')); $arguments = Helpers::autowireArguments($rm, $arguments, $this); return $this->formatPhp('$this->?(?*)', array(Container::getMethodName($service), $arguments)); } elseif ($entity === 'not') { // operator return $this->formatPhp('!?', array($arguments[0])); } elseif (is_string($entity)) { // class name if ($constructor = Reflection\ClassType::from($entity)->getConstructor()) { $this->addDependency($constructor->getFileName()); $arguments = Helpers::autowireArguments($constructor, $arguments, $this); } elseif ($arguments) { throw new ServiceCreationException("Unable to pass arguments, class $entity has no constructor."); } return $this->formatPhp("new $entity" . ($arguments ? '(?*)' : ''), array($arguments)); } elseif (!Nette\Utils\Arrays::isList($entity) || count($entity) !== 2) { throw new ServiceCreationException(sprintf('Expected class, method or property, %s given.', PhpHelpers::dump($entity))); } elseif ($entity[0] === '') { // globalFunc return $this->formatPhp("$entity[1](?*)", array($arguments)); } elseif (Strings::contains($entity[1], '$')) { // property setter Validators::assert($arguments, 'list:1', "setup arguments for '" . Nette\Utils\Callback::toString($entity) . "'"); if ($this->getServiceName($entity[0])) { return $this->formatPhp('?->? = ?', array($entity[0], substr($entity[1], 1), $arguments[0])); } else { return $this->formatPhp($entity[0] . '::$? = ?', array(substr($entity[1], 1), $arguments[0])); } } elseif ($service = $this->getServiceName($entity[0])) { // service method $class = $this->definitions[$service]->implement; if (!$class || !method_exists($class, $entity[1])) { $class = $this->definitions[$service]->class; } if ($class) { $arguments = $this->autowireArguments($class, $entity[1], $arguments); } return $this->formatPhp('?->?(?*)', array($entity[0], $entity[1], $arguments)); } else { // static method $arguments = $this->autowireArguments($entity[0], $entity[1], $arguments); return $this->formatPhp("$entity[0]::$entity[1](?*)", array($arguments)); } }