private function injectByProperties(Presenter $presenter) { if (class_exists(InjectExtension::class)) { /** @noinspection PhpInternalEntityUsedInspection */ $properties = InjectExtension::getInjectProperties(get_class($presenter)); // Nette 2.3+ } else { $properties = Helpers::getInjectProperties(new ClassType($presenter)); // Nette 2.2 } foreach ($properties as $property => $type) { if (isset($this->dependencies['@' . $property])) { $presenter->{$property} = $this->dependencies['@' . $property]; } elseif (isset($this->dependencies[$property])) { $presenter->{$property} = $this->dependencies[$property]; } } }
private function updateDefinition($def) { $injects = array(); $properties = DI\Helpers::getInjectProperties(new \ReflectionClass($def->getClass()), $this->getContainerBuilder()); foreach ($properties as $property => $type) { $injects[] = new DI\Statement('$' . $property, array('@\\' . ltrim($type, '\\'))); } foreach (get_class_methods($def->getClass()) as $method) { if (substr($method, 0, 6) === 'inject') { $injects[] = new DI\Statement($method); } } $setups = $def->getSetup(); foreach ($injects as $inject) { foreach ($setups as $key => $setup) { if ($setup->getEntity() === $inject->getEntity()) { $inject = $setup; unset($setups[$key]); } } array_unshift($setups, $inject); } $def->setSetup($setups); }
/** * Calls all methods starting with with "inject" using autowiring. * @param object * @return void */ public function callInjects($service) { if (!is_object($service)) { throw new Nette\InvalidArgumentException(sprintf('Service must be object, %s given.', gettype($service))); } foreach (array_reverse(get_class_methods($service)) as $method) { if (substr($method, 0, 6) === 'inject') { $this->callMethod(array($service, $method)); } } foreach (Helpers::getInjectProperties(Nette\Reflection\ClassType::from($service), $this) as $property => $type) { $service->{$property} = $this->getByType($type); } }
/** * Generates body of service method. * @return string */ private function generateService($name) { $this->currentService = NULL; $def = $this->definitions[$name]; $serviceRef = $this->getServiceName($def->factory->entity); $factory = $serviceRef && !$def->factory->arguments && !$def->setup && $def->implementType !== 'create' ? new Statement(array('@' . ContainerBuilder::THIS_CONTAINER, 'getService'), array($serviceRef)) : $def->factory; $code = '$service = ' . $this->formatStatement($factory) . ";\n"; $this->currentService = $name; if ($def->class && $def->class !== $def->factory->entity && !$serviceRef) { $code .= PhpHelpers::formatArgs("if (!\$service instanceof {$def->class}) {\n" . "\tthrow new Nette\\UnexpectedValueException(?);\n}\n", array("Unable to create service '{$name}', value returned by factory is not {$def->class} type.")); } $setups = (array) $def->setup; if ($def->inject && $def->class) { $injects = array(); foreach (Helpers::getInjectProperties(Reflection\ClassType::from($def->class)) as $property => $type) { $injects[] = new Statement('$' . $property, array('@\\' . ltrim($type, '\\'))); } foreach (get_class_methods($def->class) as $method) { if (substr($method, 0, 6) === 'inject') { $injects[] = new Statement($method); } } foreach ($injects as $inject) { foreach ($setups as $key => $setup) { if ($setup->entity === $inject->entity) { $inject = $setup; unset($setups[$key]); } } array_unshift($setups, $inject); } } foreach ($setups as $setup) { if (is_string($setup->entity) && strpbrk($setup->entity, ':@?') === FALSE) { // auto-prepend @self $setup->entity = array('@self', $setup->entity); } $code .= $this->formatStatement($setup) . ";\n"; } $code .= 'return $service;'; if (!$def->implement) { return $code; } $factoryClass = $this->generatedClasses[] = new Nette\PhpGenerator\ClassType(); $factoryClass->setName(str_replace(array('\\', '.'), '_', "{$this->generatedClasses[0]->name}_{$def->implement}Impl_{$name}"))->addImplement($def->implement)->setFinal(TRUE); $factoryClass->addProperty('container')->setVisibility('private'); $factoryClass->addMethod('__construct')->addBody('$this->container = $container;')->addParameter('container')->setTypeHint('Nette\\DI\\Container'); $factoryClass->addMethod($def->implementType)->setParameters($this->convertParameters($def->parameters))->setBody(str_replace('$this', '$this->container', $code)); return "return new {$factoryClass->name}(\$this);"; }