/** * @param \Nette\DI\Container $dic * @throws MemberAccessException * @throws MissingServiceException * @throws InvalidStateException * @throws UnexpectedValueException */ public function injectProperties(Nette\DI\Container $dic) { if (!$this instanceof Nette\Application\UI\PresenterComponent && !$this instanceof Nette\Application\UI\Component) { throw new MemberAccessException('Trait ' . __TRAIT__ . ' can be used only in descendants of PresenterComponent.'); } $this->autowirePropertiesLocator = $dic; $storage = $dic->hasService('autowired.cacheStorage') ? $dic->getService('autowired.cacheStorage') : $dic->getByType('Nette\\Caching\\IStorage'); $cache = new Nette\Caching\Cache($storage, 'Kdyby.Autowired.AutowireProperties'); $containerFileName = ClassType::from($this->autowirePropertiesLocator)->getFileName(); $cacheKey = [$presenterClass = get_class($this), $containerFileName]; if (is_array($this->autowireProperties = $cache->load($cacheKey))) { foreach ($this->autowireProperties as $propName => $tmp) { unset($this->{$propName}); } return; } $this->autowireProperties = []; $ignore = class_parents('Nette\\Application\\UI\\Presenter') + ['ui' => 'Nette\\Application\\UI\\Presenter']; $rc = new ClassType($this); foreach ($rc->getProperties() as $prop) { if (!$this->validateProperty($prop, $ignore)) { continue; } $this->resolveProperty($prop); } $files = array_map(function ($class) { return ClassType::from($class)->getFileName(); }, array_diff(array_values(class_parents($presenterClass) + ['me' => $presenterClass]), $ignore)); $files[] = $containerFileName; $cache->save($cacheKey, $this->autowireProperties, [$cache::FILES => $files]); }
/** * @param Config $config * @throws LogicException * @return array */ public function getDataToArray(Config $config) { $this->setPosId($config->getPosId()); if ($this instanceof NewPaymentRequest) { $this->setPosAuthKey($config->getPosAuthKey()); } $reflection = new ClassType($this); $parameters = array(); $errors = array(); foreach ($reflection->getProperties() as $property) { if ($property->hasAnnotation('var') && $property->getAnnotation('var') == 'bool') { $getterPrefix = 'is'; } else { $getterPrefix = 'get'; } $propertyGetter = $getterPrefix . ucfirst($property->getName()); $value = $this->{$propertyGetter}(); if ($value !== NULL) { $parameters[Strings::camelToUnderdash($property->getName())] = $value; } if ($property->hasAnnotation('required') && $value === NULL) { $errors[] = $property->getName(); } } if (count($errors) > 0) { throw new LogicException('Empty required properties: ' . implode(', ', $errors)); } $parameters['sig'] = $this->getSig($config->getKey1()); return $parameters; }
/** * Returns array of classes persistent parameters. They have public visibility and are non-static. * This default implementation detects persistent parameters by annotation @persistent. * * @return array */ public static function getPersistentParams() { /*5.2*$arg = func_get_arg(0);*/ $rc = new Nette\Reflection\ClassType(get_called_class()); $params = array(); foreach ($rc->getProperties(\ReflectionProperty::IS_PUBLIC) as $rp) { if (!$rp->isStatic() && $rp->hasAnnotation('persistent')) { $params[] = $rp->getName(); } } return $params; }
/** * Generate form from entity * * @return $this */ private function createForm() { $properties = $this->entityReflection->getProperties(); /** @var Property $property */ foreach ($properties as $property) { $rule = $this->getPropertyRule($property->getName()); if ($rule !== NULL) { $this->replaceFormControl($rule); } } return $this; }
/** * Annotation-boosted component factory * * @param string * @return Nette\ComponentModel\IComponent */ protected function createComponent($name) { /** * Default method name */ $ucname = ucfirst($name); $method = 'createComponent' . $ucname; if (method_exists($this, $method)) { return parent::createComponent($name); } /** * Find particular property with annotation @component */ $reflection = new Reflection\ClassType($this); $properties = $reflection->getProperties(); foreach ($properties as $property) { $annotations = $property->getAnnotations(); if (isset($annotations['component'])) { $script = new PresenterComponentScript($annotations); if ($script->component !== $name) { continue; } $property = $property->getName(); $args = []; foreach ($script->args as $arg) { $args[] = $this->{$arg}; } $reflection = new \ReflectionClass(get_class($this)); $property_reflection = $reflection->getProperty($property); $property_reflection->setAccessible(TRUE); $property_value = $property_reflection->getValue($this); if (!is_callable([$property_value, $script->factory_method])) { throw new PresenterComponentException(sprintf('Presenter property [<%s>, %s] is not callable', is_null($this->{$property}) ? 'NULL' : $property, $script->factory_method)); } $component = call_user_func_array([$property_value, $script->factory_method], $args); foreach ($script->callbacks as $callback) { $component->{$callback['event']}[] = [$this, $callback['callback']]; } return $component; } } return parent::createComponent($name); }
/** * Generates list of properties with annotation @inject. * @return array */ public static function getInjectProperties(Nette\Reflection\ClassType $class) { $res = array(); foreach ($class->getProperties(\ReflectionProperty::IS_PUBLIC) as $property) { $type = $property->getAnnotation('var'); if (!$property->getAnnotation('inject')) { continue; } elseif (!$type) { throw new Nette\InvalidStateException("Property {$property} has not @var annotation."); } elseif (!class_exists($type) && !interface_exists($type)) { if ($type[0] !== '\\') { $type = $property->getDeclaringClass()->getNamespaceName() . '\\' . $type; } if (!class_exists($type) && !interface_exists($type)) { throw new Nette\InvalidStateException("Please use a fully qualified name of class/interface in @var annotation at {$property} property. Class '{$type}' cannot be found."); } } $res[$property->getName()] = $type; } return $res; }
/** * Generates list of properties with annotation @inject. * @return array */ public static function getInjectProperties(Nette\Reflection\ClassType $class) { $res = array(); foreach ($class->getProperties(\ReflectionProperty::IS_PUBLIC) as $property) { $type = $property->getAnnotation('var'); if (!$property->getAnnotation('inject')) { continue; } elseif (!$type) { throw new Nette\InvalidStateException("Property {$property} has not @var annotation."); } $type = Nette\Reflection\AnnotationsParser::expandClassName($type, $property->getDeclaringClass()); if (!class_exists($type) && !interface_exists($type)) { throw new Nette\InvalidStateException("Class or interface '{$type}' used in @var annotation at {$property} not found."); } $res[$property->getName()] = $type; } return $res; }
protected function bindEventProperties(Nette\DI\ServiceDefinition $def, Nette\Reflection\ClassType $class) { foreach ($class->getProperties(Nette\Reflection\Property::IS_PUBLIC) as $property) { if (!preg_match('#^on[A-Z]#', $name = $property->getName())) { continue; } if ($property->hasAnnotation('persistent') || $property->hasAnnotation('inject')) { // definitely not an event continue; } $def->addSetup('$' . $name, array(new Nette\DI\Statement($this->prefix('@manager') . '::createEvent', array(array($class->getName(), $name), new Code\PhpLiteral('$service->' . $name))))); } }
/** * Generates list of properties with annotation @inject. * @return array */ public static function getInjectProperties(Nette\Reflection\ClassType $class, $container = NULL) { $res = array(); foreach ($class->getProperties(\ReflectionProperty::IS_PUBLIC) as $property) { $type = $property->getAnnotation('var'); if (!$property->getAnnotation('inject')) { continue; } elseif (!$type) { throw new Nette\InvalidStateException("Property {$property} has no @var annotation."); } elseif (!class_exists($type) && !interface_exists($type)) { if ($type[0] !== '\\') { $type = $property->getDeclaringClass()->getNamespaceName() . '\\' . $type; } if (!class_exists($type) && !interface_exists($type)) { throw new Nette\InvalidStateException("Please use a fully qualified name of class/interface in @var annotation at {$property} property. Class '{$type}' cannot be found."); } } if ($container && !$container->getByType($type, FALSE)) { throw new ServiceCreationException("Service of type {$type} used in @var annotation at {$property} not found. Did you register it in configuration file?"); } $res[$property->getName()] = $type; } return $res; }
/** * Generates list of properties with annotation @inject. * @return array */ public static function getInjectProperties(Nette\Reflection\ClassType $class, $container = NULL) { $res = array(); foreach ($class->getProperties(\ReflectionProperty::IS_PUBLIC) as $property) { $type = $property->getAnnotation('var'); if (!$property->getAnnotation('inject')) { continue; } elseif (!$type) { throw new Nette\InvalidStateException("Property $property has no @var annotation."); } $type = Nette\Reflection\AnnotationsParser::expandClassName($type, self::getDeclaringClass($property)); if (!class_exists($type) && !interface_exists($type)) { throw new Nette\InvalidStateException("Class or interface '$type' used in @var annotation at $property not found. Check annotation and 'use' statements."); } elseif ($container && !$container->getByType($type, FALSE)) { throw new ServiceCreationException("Service of type {$type} used in @var annotation at $property not found. Did you register it in configuration file?"); } $res[$property->getName()] = $type; } return $res; }
protected function bindEventProperties(Nette\DI\ServiceDefinition $def, Nette\Reflection\ClassType $class) { foreach ($class->getProperties(Nette\Reflection\Property::IS_PUBLIC) as $property) { if (!preg_match('#^on[A-Z]#', $name = $property->getName())) { continue; } if ($property->hasAnnotation('persistent') || $property->hasAnnotation('inject')) { // definitely not an event continue; } $def->addSetup('$' . $name, [new Nette\DI\Statement($this->prefix('@manager') . '::createEvent', [[$class->getName(), $name], new Code\PhpLiteral('$service->' . $name), NULL, $property->hasAnnotation('globalDispatchFirst') ? (bool) $property->getAnnotation('globalDispatchFirst') : $this->loadedConfig['globalDispatchFirst']])]); } }