Example #1
0
 /**
  * @param string $dir Directory to search in
  * @return array Array of listener class names
  */
 protected function searchListeners($dir)
 {
     $files = (new Finder())->files()->in($dir)->path($this->searchPathPattern)->name('*Listener.php');
     $listeners = [];
     foreach ($files as $file) {
         $listeners[] = key(AnnotationsParser::parsePhp(\file_get_contents($file->getRealpath())));
     }
     return $listeners;
 }
Example #2
0
 /**
  * Create ProcessSet from given files, optionally filtering by given $groups and $excludeGroups
  *
  * @param Finder $files
  * @param array $groups Groups to be run
  * @param array $excludeGroups Groups to be excluded
  * @param string $filter filter test cases by name
  * @return ProcessSet
  */
 public function createFromFiles(Finder $files, array $groups = null, array $excludeGroups = null, $filter = null)
 {
     $files->sortByName();
     $processSet = $this->getProcessSet();
     if ($groups || $excludeGroups || $filter) {
         $this->output->writeln('Filtering testcases:');
     }
     if ($groups) {
         $this->output->writeln(sprintf(' - by group(s): %s', implode(', ', $groups)));
     }
     if ($excludeGroups) {
         $this->output->writeln(sprintf(' - excluding group(s): %s', implode(', ', $excludeGroups)));
     }
     if ($filter) {
         $this->output->writeln(sprintf(' - by testcase/test name: %s', $filter));
     }
     $testCasesNum = 0;
     foreach ($files as $file) {
         $fileName = $file->getRealpath();
         // Parse classes from the testcase file
         $classes = AnnotationsParser::parsePhp(\file_get_contents($fileName));
         // Get annotations for the first class in testcase (one file = one class)
         $annotations = AnnotationsParser::getAll(new \ReflectionClass(key($classes)));
         // Filter out test-cases having any of excluded groups
         if ($excludeGroups && array_key_exists('group', $annotations) && count($excludingGroups = array_intersect($excludeGroups, $annotations['group']))) {
             if ($this->output->isDebug()) {
                 $this->output->writeln(sprintf('Excluding testcase file %s with group %s', $fileName, implode(', ', $excludingGroups)));
             }
             continue;
         }
         // Filter out test-cases without any matching group
         if ($groups) {
             if (!array_key_exists('group', $annotations) || !count($matchingGroups = array_intersect($groups, $annotations['group']))) {
                 continue;
             }
             if ($this->output->isDebug()) {
                 $this->output->writeln(sprintf('Found testcase file #%d in group %s: %s', ++$testCasesNum, implode(', ', $matchingGroups), $fileName));
             }
         } else {
             if ($this->output->isDebug()) {
                 $this->output->writeln(sprintf('Found testcase file #%d: %s', ++$testCasesNum, $fileName));
             }
         }
         $phpunitArgs = ['--log-junit=logs/' . Strings::webalize(key($classes), null, $lower = false) . '.xml', '--configuration=' . realpath(__DIR__ . '/../phpunit.xml')];
         if ($filter) {
             $phpunitArgs[] = '--filter=' . $filter;
         }
         // If ANSI output is enabled, turn on colors in PHPUnit
         if ($this->output->isDecorated()) {
             $phpunitArgs[] = '--colors=always';
         }
         $processSet->add($this->buildProcess($fileName, $phpunitArgs), key($classes), $delayAfter = !empty($annotations['delayAfter']) ? current($annotations['delayAfter']) : '', $delayMinutes = !empty($annotations['delayMinutes']) ? current($annotations['delayMinutes']) : null);
     }
     return $processSet;
 }
 /**
  * Registers repositories from annotations
  */
 private function registerAnnotations()
 {
     $ref = Nette\Reflection\ClassType::from($this);
     $annotations = $ref->getAnnotations();
     if (isset($annotations['property-read'])) {
         $c = get_called_class();
         $namespace = substr($c, 0, strrpos($c, '\\'));
         foreach ($annotations['property-read'] as $value) {
             if (preg_match('#^([\\\\\\w]+Repository)\\s+\\$(\\w+)$#', $value, $m)) {
                 $class = '\\' . Reflection\AnnotationsParser::expandClassName($m[1], $ref);
                 $this->register($m[2], $class);
                 $this->aliases[$m[2]] = $class;
             }
         }
     }
 }
Example #4
0
 /**
  * @param ServiceDefinition
  * @return string|null
  */
 protected static function detectClass(ServiceDefinition $def)
 {
     if ($def->getClass()) {
         return $def->getClass();
     } elseif ($interface = $def->getImplement()) {
         $rc = Reflection\ClassType::from($interface);
         $method = $rc->hasMethod('create') ? 'create' : ($rc->hasMethod('get') ? 'get' : NULL);
         if ($method === NULL) {
             return NULL;
         }
         if (!($returnType = $rc->getMethod($method)->getAnnotation('return'))) {
             return NULL;
         }
         return Reflection\AnnotationsParser::expandClassName(preg_replace('#[|\\s].*#', '', $returnType), $rc);
     }
     return NULL;
 }
Example #5
0
 protected function getRepositoryList($modelClass)
 {
     $modelReflection = new ClassType($modelClass);
     $builder = $this->getContainerBuilder();
     $builder->addDependency($modelReflection->getFileName());
     $repositories = [];
     foreach ($modelReflection->getAnnotations() as $key => $annotations) {
         if ($key !== 'property-read') {
             continue;
         }
         foreach ($annotations as $annotation) {
             list($class, $name) = preg_split('#\\s+#', $annotation);
             $class = AnnotationsParser::expandClassName($class, $modelReflection);
             if (!class_exists($class)) {
                 throw new RuntimeException("Repository '{$class}' does not exist.");
             }
             $repositories[ltrim($name, '$')] = $class;
         }
     }
     return $repositories;
 }
Example #6
0
 protected function getRepositoryList($modelClass)
 {
     $modelReflection = new ClassType($modelClass);
     $builder = $this->getContainerBuilder();
     $builder->addDependency($modelReflection->getFileName());
     $repositories = [];
     foreach ($modelReflection->getAnnotations() as $key => $annotations) {
         if ($key !== 'property-read') {
             continue;
         }
         foreach ($annotations as $annotation) {
             list($class, $name) = preg_split('#\\s+#', $annotation);
             $class = AnnotationsParser::expandClassName($class, $modelReflection);
             if (!class_exists($class)) {
                 throw new RuntimeException("Class repository '{$class}' does not exist.");
             }
             $repositories[] = ['name' => ltrim($name, '$'), 'serviceName' => $this->prefix('repositories.' . ltrim($name, '$')), 'class' => $class, 'entities' => call_user_func([$class, 'getEntityClassNames'])];
         }
     }
     return $repositories;
 }
    public function beforeCompile()
    {
        $builder = $this->getContainerBuilder();
        $config = $this->getConfig($this->defaults);
        foreach ($builder->getDefinitions() as $def) {
            /** @var $def ServiceDefinition */
            $class = $def->class ?: ($def->factory ? $def->factory->entity : NULL);
            if (!$class || !class_exists($class)) {
                continue;
            }
            $classes = class_parents($class) + array('@self' => $class);
            foreach ($classes as $class) {
                $rc = ClassType::from($class);
                foreach ($rc->getProperties() as $rp) {
                    if (!$rp->hasAnnotation($config['annotationName'])) {
                        continue;
                    }
                    $fullPropName = $rp->getDeclaringClass()->getName() . '::$' . $rp->getName();
                    if ($rp->isStatic()) {
                        trigger_error('Injects are not supported on static properties, found on ' . $fullPropName . '.', E_USER_WARNING);
                        continue;
                    }
                    $var = (string) $rp->getAnnotation('var');
                    if (!$var) {
                        throw new CompileException('@var annotation on ' . $fullPropName . ' is missing or empty.');
                    }
                    $m = Strings::match(trim($var), '~
							(?<name>\\\\?[a-z][a-z0-9_]*(?:\\\\[a-z][a-z0-9_]*)*)   # class name
							(?<multiple>(?:\\[\\])?)   # array of types
							\\z
						~Aix');
                    if (!$m) {
                        throw new CompileException('@var annotation on ' . $fullPropName . ' contains invalid value.');
                    }
                    $type = AnnotationsParser::expandClassName($m['name'], $rp->getDeclaringClass());
                    $def->addSetup(__NAMESPACE__ . '\\Helpers::writeProperty(?, ?, ?, ' . (!empty($m['multiple']) ? __NAMESPACE__ . '\\Helpers::findServicesOfType(?, $this)' : '$this->getByType(?)') . ')', array('@self', $rp->getDeclaringClass()->getName(), $rp->getName(), $type));
                }
            }
        }
    }
Example #8
0
 public function startTest(\PHPUnit_Framework_Test $test)
 {
     if ($test instanceof \PHPUnit_Framework_Warning) {
         return;
     }
     if (!$test instanceof AbstractTestCase) {
         throw new \InvalidArgumentException('Test case must be descendant of Lmc\\Steward\\Test\\AbstractTestCase');
     }
     $config = ConfigProvider::getInstance();
     // Initialize NullWebDriver if self::NO_BROWSER_ANNOTATION is used on testcase class or test method
     $testCaseAnnotations = AnnotationsParser::getAll(new \ReflectionClass($test));
     $testAnnotations = AnnotationsParser::getAll(new \ReflectionMethod($test, $test->getName(false)));
     if (isset($testCaseAnnotations[self::NO_BROWSER_ANNOTATION]) || isset($testAnnotations[self::NO_BROWSER_ANNOTATION])) {
         $test->wd = new NullWebDriver();
         $test->log('Initializing Null WebDriver for "%s::%s" (@%s annotation used %s)', get_class($test), $test->getName(), self::NO_BROWSER_ANNOTATION, isset($testCaseAnnotations[self::NO_BROWSER_ANNOTATION]) ? 'on class' : 'on method');
         return;
     }
     // Initialize real WebDriver otherwise
     $test->log('Initializing "%s" WebDriver for "%s::%s"', $config->browserName, get_class($test), $test->getName());
     $capabilities = new \DesiredCapabilities([\WebDriverCapabilityType::BROWSER_NAME => $config->browserName, \WebDriverCapabilityType::PLATFORM => \WebDriverPlatform::ANY]);
     $this->createWebDriver($test, $config->serverUrl . '/wd/hub', $this->setupCustomCapabilities($capabilities, $config->browserName), $connectTimeoutMs = 2 * 60 * 1000, $requestTimeoutMs = 60 * 60 * 1000);
 }
Example #9
0
	/**
	 * Expands class name into FQN.
	 * @param  string
	 * @return string  fully qualified class name
	 * @throws Nette\InvalidArgumentException
	 */
	public static function expandClassName($name, \ReflectionClass $reflector)
	{
		if (empty($name)) {
			throw new Nette\InvalidArgumentException('Class name must not be empty.');

		} elseif ($name === 'self') {
			return $reflector->getName();

		} elseif ($name[0] === '\\') { // already fully qualified
			return ltrim($name, '\\');
		}

		$filename = $reflector->getFileName();
		$parsed = static::getCache()->load($filename, function (& $dp) use ($filename) {
			if (AnnotationsParser::$autoRefresh) {
				$dp[Nette\Caching\Cache::FILES] = $filename;
			}
			return AnnotationsParser::parsePhp(file_get_contents($filename));
		});
		$uses = array_change_key_case((array) $tmp = & $parsed[$reflector->getName()]['use']);
		$parts = explode('\\', $name, 2);
		$parts[0] = strtolower($parts[0]);
		if (isset($uses[$parts[0]])) {
			$parts[0] = $uses[$parts[0]];
			return implode('\\', $parts);

		} elseif ($reflector->inNamespace()) {
			return $reflector->getNamespaceName() . '\\' . $name;

		} else {
			return $name;
		}
	}
Example #10
0
 private function processKeyword($value, ReflectionClass $reflectionClass)
 {
     if (strcasecmp($value, 'true') === 0) {
         return TRUE;
     } elseif (strcasecmp($value, 'false') === 0) {
         return FALSE;
     } elseif (strcasecmp($value, 'null') === 0) {
         return NULL;
     } elseif (is_numeric($value)) {
         return $value * 1;
     } elseif (preg_match('#^[a-z0-9_\\\\]+::[a-z0-9_]+(\\*)?$#i', $value)) {
         list($className, $const) = explode('::', $value, 2);
         if ($className === 'self' || $className === 'static') {
             $reflection = $reflectionClass;
         } else {
             $className = AnnotationsParser::expandClassName($className, $reflectionClass);
             $reflection = new ReflectionClass($className);
         }
         $enum = [];
         $constants = $reflection->getConstants();
         if (strpos($const, '*') !== FALSE) {
             $prefix = rtrim($const, '*');
             $prefixLength = strlen($prefix);
             $count = 0;
             foreach ($constants as $name => $value) {
                 if (substr($name, 0, $prefixLength) === $prefix) {
                     $enum[$value] = $value;
                     $count += 1;
                 }
             }
             if ($count === 0) {
                 throw new InvalidModifierDefinitionException("No constant matches {$reflection->name}::{$const} pattern.");
             }
         } else {
             if (!array_key_exists($const, $constants)) {
                 throw new InvalidModifierDefinitionException("Constant {$reflection->name}::{$const} does not exist.");
             }
             $value = $reflection->getConstant($const);
             $enum[$value] = $value;
         }
         return array_values($enum);
     } else {
         return $value;
     }
 }
Example #11
0
 protected function makeFQN($name)
 {
     return AnnotationsParser::expandClassName($name, $this->currentReflection);
 }
Example #12
0
 private function resolveAnnotationClass(\Reflector $prop, $annotationValue, $annotationName)
 {
     /** @var Property|Method $prop */
     if (!($type = ltrim($annotationValue, '\\'))) {
         throw new InvalidStateException("Missing annotation @{$annotationName} with typehint on {$prop}.", $prop);
     }
     if (!class_exists($type) && !interface_exists($type)) {
         if (substr(func_get_arg(1), 0, 1) === '\\') {
             throw new MissingClassException("Class \"{$type}\" was not found, please check the typehint on {$prop} in annotation @{$annotationName}.", $prop);
         }
         $expandedType = NULL;
         if (method_exists('Nette\\Reflection\\AnnotationsParser', 'expandClassName')) {
             $expandedType = Nette\Reflection\AnnotationsParser::expandClassName($annotationValue, $prop instanceof \ReflectionProperty ? Nette\Reflection\Helpers::getDeclaringClass($prop) : $prop->getDeclaringClass());
         }
         if ($expandedType && (class_exists($expandedType) || interface_exists($expandedType))) {
             $type = $expandedType;
         } elseif (!class_exists($type = $prop->getDeclaringClass()->getNamespaceName() . '\\' . $type) && !interface_exists($type)) {
             throw new MissingClassException("Neither class \"" . func_get_arg(1) . "\" or \"{$type}\" was found, please check the typehint on {$prop} in annotation @{$annotationName}.", $prop);
         }
     }
     return ClassType::from($type)->getName();
 }
Example #13
0
 /**
  * Generates $dependencies, $classes and normalizes class names.
  * @return array
  */
 public function prepareClassList()
 {
     $this->classes = FALSE;
     // prepare generated factories
     foreach ($this->definitions as $name => $def) {
         if (!$def->implement) {
             continue;
         }
         if (!interface_exists($def->implement)) {
             throw new ServiceCreationException("Interface {$def->implement} has not been found.");
         }
         $rc = Reflection\ClassType::from($def->implement);
         $method = $rc->hasMethod('create') ? $rc->getMethod('create') : ($rc->hasMethod('get') ? $rc->getMethod('get') : NULL);
         if (count($rc->getMethods()) !== 1 || !$method || $method->isStatic()) {
             throw new ServiceCreationException("Interface {$def->implement} must have just one non-static method create() or get().");
         }
         $def->implement = $rc->getName();
         $def->implementType = $rc->hasMethod('create') ? 'create' : 'get';
         if (!$def->class && empty($def->factory->entity)) {
             $returnType = $method->getAnnotation('return');
             if (!$returnType) {
                 throw new ServiceCreationException("Method {$method} has not @return annotation.");
             }
             $returnType = Reflection\AnnotationsParser::expandClassName($returnType, $rc);
             if (!class_exists($returnType)) {
                 throw new ServiceCreationException("Please check a @return annotation of the {$method} method. Class '{$returnType}' cannot be found.");
             }
             $def->setClass($returnType);
         }
         if ($method->getName() === 'get') {
             if ($method->getParameters()) {
                 throw new ServiceCreationException("Method {$method} must have no arguments.");
             }
             if (empty($def->factory->entity)) {
                 $def->setFactory('@\\' . ltrim($def->class, '\\'));
             } elseif (!$this->getServiceName($def->factory->entity)) {
                 throw new ServiceCreationException("Invalid factory in service '{$name}' definition.");
             }
         }
         if (!$def->parameters) {
             foreach ($method->getParameters() as $param) {
                 $paramDef = ($param->isArray() ? 'array' : $param->getClassName()) . ' ' . $param->getName();
                 if ($param->isOptional()) {
                     $def->parameters[$paramDef] = $param->getDefaultValue();
                 } else {
                     $def->parameters[] = $paramDef;
                 }
             }
         }
     }
     // complete class-factory pairs
     foreach ($this->definitions as $name => $def) {
         if (!$def->factory) {
             if (!$def->class) {
                 throw new ServiceCreationException("Class and factory are missing in service '{$name}' definition.");
             }
             $def->factory = new Statement($def->class);
         }
     }
     // check if services are instantiable
     foreach ($this->definitions as $name => $def) {
         $factory = $def->factory->entity = $this->normalizeEntity($def->factory->entity);
         if (is_string($factory) && preg_match('#^[\\w\\\\]+\\z#', $factory) && $factory !== self::THIS_SERVICE) {
             if (!class_exists($factory) || !Reflection\ClassType::from($factory)->isInstantiable()) {
                 throw new ServiceCreationException("Class {$factory} used in service '{$name}' has not been found or is not instantiable.");
             }
         }
     }
     // complete classes
     foreach ($this->definitions as $name => $def) {
         $this->resolveClass($name);
         if (!$def->class) {
             continue;
         } elseif (!class_exists($def->class) && !interface_exists($def->class)) {
             throw new ServiceCreationException("Class or interface {$def->class} used in service '{$name}' has not been found.");
         } else {
             $def->class = Reflection\ClassType::from($def->class)->getName();
         }
     }
     //  build auto-wiring list
     $this->classes = array();
     foreach ($this->definitions as $name => $def) {
         $class = $def->implement ?: $def->class;
         if ($def->autowired && $class) {
             foreach (class_parents($class) + class_implements($class) + array($class) as $parent) {
                 $this->classes[strtolower($parent)][] = (string) $name;
             }
         }
     }
     foreach ($this->classes as $class => $foo) {
         $this->addDependency(Reflection\ClassType::from($class)->getFileName());
     }
 }
Example #14
0
 /** @return string */
 protected final function getEntityClass()
 {
     if ($this->entity === NULL) {
         $ref = static::getReflection();
         if (($annotation = $ref->getAnnotation('entity')) === NULL) {
             throw new Exception\InvalidStateException('Entity class not set.');
         }
         $this->entity = AnnotationsParser::expandClassName($annotation, $ref);
     }
     return $this->entity;
 }
 /**
  * @param MetaData $metaData
  * @param string $string
  * @param string $mode ::READWRITE|MetaData::READ|MetaData::WRITE
  * @param string $class
  * @param ReflectionClass $r
  */
 private function addProperty(MetaData $metaData, $string, $mode, $class, ReflectionClass $r)
 {
     if ($mode === MetaData::READWRITE) {
         if (preg_match('#^(-read|-write)?\\s?(.*)$#si', $string, $match)) {
             $mode = $match[1];
             $mode = ((!$mode or $mode === '-read') ? MetaData::READ : 0) | ((!$mode or $mode === '-write') ? MetaData::WRITE : 0);
             $string = $match[2];
         }
     }
     if (preg_match('#^([a-z0-9_\\[\\]\\|\\\\]+)\\s+\\$([a-z0-9_]+)($|\\s(.*)$)#si', $string, $match)) {
         $property = $match[2];
         $type = $match[1];
         $string = $match[3];
     } else {
         if (preg_match('#^\\$([a-z0-9_]+)\\s+([a-z0-9_\\|\\\\]+)($|\\s(.*)$)#si', $string, $match)) {
             $property = $match[1];
             $type = $match[2];
             $string = $match[3];
         } else {
             if (preg_match('#^\\$([a-z0-9_]+)($|\\s(.*)$)#si', $string, $match)) {
                 $property = $match[1];
                 $type = 'mixed';
                 $string = $match[2];
             } else {
                 $tmp = $mode === MetaData::READ ? '-read' : '';
                 throw new AnnotationMetaDataException("Invalid annotation format '@property{$tmp} {$string}' in {$class}");
             }
         }
     }
     if (strpos(strToLower($string), '{ignore}') !== FALSE) {
         return;
     }
     $propertyName = $property;
     // Support for simplified FQN '@property Foo' instead of '@property \App\Foo'
     $parts = explode('|', $type);
     foreach ($parts as &$part) {
         $fqn = NetteAnnotationsParser::expandClassName($part, $r);
         if (class_exists($fqn)) {
             $part = $fqn;
         }
         if ($part === Orm\OneToMany::class) {
             // Support for '@property OtM|Foo[]' instead of '@property Orm\OneToMany'
             $parts = [Orm\OneToMany::class];
             break;
         } else {
             if ($part === Orm\ManyToMany::class) {
                 // Support for '@property MtM|Foo[]' instead of '@property Orm\ManyToMany'
                 $parts = [Orm\ManyToMany::class];
                 break;
             } else {
                 if (substr($part, -2) === '[]') {
                     $part = 'array';
                 }
             }
         }
     }
     $type = implode('|', $parts);
     $property = $metaData->addProperty($propertyName, $type, $mode, $class);
     $this->property = [$propertyName, $property];
     $string = preg_replace_callback('#\\{\\s*([^\\s\\}\\{]+)(?:\\s+([^\\}\\{]*))?\\s*\\}#si', [$this, 'callOnMacro'], $string);
     $this->property = NULL;
     if (preg_match('#\\{|\\}#', $string)) {
         $string = trim($string);
         throw new AnnotationMetaDataException("Invalid annotation format, extra curly bracket '{$string}' in {$class}::\${$propertyName}");
     }
 }
Example #16
0
 /**
  * Returns an annotation value.
  *
  * @param  string
  *
  * @return IAnnotation
  */
 public function getAnnotation($name)
 {
     $res = AnnotationsParser::getAll($this);
     return isset($res[$name]) ? end($res[$name]) : null;
 }
Example #17
0
 /**
  * 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;
 }
 /**
  * Scan discoverable paths and get actions
  *
  * @return array
  */
 public function mapClasses()
 {
     $paths = $this->config->getDiscovererPaths();
     $files = $classMap = [];
     foreach ($paths as $path) {
         $files = array_merge($files, $this->loadDir($path));
     }
     foreach ($files as $file) {
         $fileContent = file_get_contents($file);
         $classes = array_keys(AnnotationsParser::parsePhp($fileContent));
         Config::includeFile($file);
         foreach ($classes as $className) {
             $class = new \ReflectionClass($className);
             if (!$class->isInstantiable()) {
                 continue;
             }
             $classAnnotations = AnnotationsParser::getAll($class);
             if (!isset($classAnnotations['ExtDirect'])) {
                 continue;
             }
             $methods = $this->getMethods($class);
             $classAlias = null;
             if (isset($classAnnotations['ExtDirect\\Alias'])) {
                 if (is_array($classAnnotations['ExtDirect\\Alias']) && is_string($classAnnotations['ExtDirect\\Alias'][0])) {
                     $classAlias = $classAnnotations['ExtDirect\\Alias'][0];
                 }
             }
             $actionName = $classAlias ?: $className;
             $classMap[$actionName]['action'] = $actionName;
             $classMap[$actionName]['class'] = $className;
             $classMap[$actionName]['file'] = $file;
             $classMap[$actionName]['methods'] = $methods;
         }
     }
     return $classMap;
 }
Example #19
0
 /**
  * Returns array of properties needed to be injected.
  * Keys of array are property names, values are service types.
  *
  * Name must match with InjectionCompilerExtension::IIS_GET_INJECTION_PROPS_METHOD
  *
  * @return array
  */
 public static function InjectableTrait_getInjectionByTypeProperties()
 {
     $injectionProperties = [];
     $properties = static::InjectableTrait_getReflection()->getProperties();
     foreach ($properties as $property) {
         if ($property->hasAnnotation(AService::INJECT_SERVICE_ANNOTATION)) {
             $serviceName = $property->getAnnotation(AService::INJECT_SERVICE_ANNOTATION);
             $type = $property->getAnnotation(AService::TYPE_ANNOTATION);
             if (($serviceName === true || strlen($serviceName) === 0) && $type !== null) {
                 $type = AnnotationsParser::expandClassName($type, $property->getDeclaringClass());
                 $injectionProperties[$property->name] = $type;
             }
         }
     }
     return $injectionProperties;
 }
Example #20
0
isset($res[$name])?end($res[$name]):NULL;}function
getAnnotations(){return
AnnotationsParser::getAll($this);}function
Example #21
0
 /**
  * @param  string $class
  * @return void
  */
 private static function loadAnnotationProperties($class)
 {
     if (!isset(self::$annProps[$class])) {
         self::$annProps[$class] = [];
         $ref = $class::getReflection();
         foreach ($ref->getAnnotations() as $ann => $values) {
             if ($ann === 'property' || $ann === 'property-read') {
                 foreach ($values as $tmp) {
                     $matches = NStrings::match($tmp, '#^[ \\t]*(?P<type>\\\\?[a-zA-Z_\\x7f-\\xff][a-zA-Z0-9_\\x7f-\\xff]*(?:\\\\[a-zA-Z_\\x7f-\\xff][a-zA-Z0-9_\\x7f-\\xff]*)*(?:\\|\\\\?[a-zA-Z_\\x7f-\\xff][a-zA-Z0-9_\\x7f-\\xff]*(?:\\\\[a-zA-Z_\\x7f-\\xff][a-zA-Z0-9_\\x7f-\\xff]*)*)?)[ \\t]+(?P<property>\\$[a-zA-Z_\\x7f-\\xff][a-zA-Z0-9_\\x7f-\\xff]*)(?:[ \\t]+->[ \\t]+(?P<column>[a-zA-Z0-9_-]+))?[ \\t]*(?P<description>.*)\\z#');
                     if ($matches === NULL) {
                         throw new YetORM\Exception\InvalidStateException('Invalid property definition - "@' . $ann . ' ' . $tmp . '" does not match "@property[-read] <type> $<property> [-> <column>][ <description>]" pattern.');
                     }
                     $nullable = FALSE;
                     $type = $matches['type'];
                     $types = explode('|', $type, 2);
                     if (count($types) === 2) {
                         if (strcasecmp($types[0], 'NULL') === 0) {
                             $nullable = TRUE;
                             $type = $types[1];
                         }
                         if (strcasecmp($types[1], 'NULL') === 0) {
                             if ($nullable) {
                                 throw new YetORM\Exception\InvalidStateException('Invalid property type (double NULL).');
                             }
                             $nullable = TRUE;
                             $type = $types[0];
                         }
                         if (!$nullable) {
                             throw new YetORM\Exception\InvalidStateException('Invalid property type (multiple non-NULL types detected).');
                         }
                     }
                     if ($type === 'bool') {
                         $type = 'boolean';
                     } elseif ($type === 'int') {
                         $type = 'integer';
                     }
                     if (!EntityProperty::isNativeType($type)) {
                         $type = AnnotationsParser::expandClassName($type, $ref);
                     }
                     $readonly = $ann === 'property-read';
                     $name = substr($matches['property'], 1);
                     $column = strlen($matches['column']) ? $matches['column'] : $name;
                     $description = strlen($matches['description']) ? $matches['description'] : NULL;
                     self::$annProps[$class][$name] = new AnnotationProperty($ref, $name, $readonly, $type, $column, $nullable, $description);
                 }
             }
         }
     }
 }
Example #22
0
 /**
  * Returns all annotations.
  * @return IAnnotation[][]
  */
 public function getAnnotations()
 {
     return AnnotationsParser::getAll($this);
 }
Example #23
0
 private function resolveClass($name, $recursive = array())
 {
     if (isset($recursive[$name])) {
         throw new ServiceCreationException('Circular reference detected for services: ' . implode(', ', array_keys($recursive)) . '.');
     }
     $recursive[$name] = TRUE;
     $def = $this->definitions[$name];
     $factory = $def->factory->entity;
     if ($def->class) {
         return $def->class;
     } elseif (is_array($factory)) {
         // method calling
         if ($service = $this->getServiceName($factory[0])) {
             if (Strings::contains($service, '\\')) {
                 // @\Class
                 $factory[0] = $service;
             } else {
                 $factory[0] = $this->resolveClass($service, $recursive);
                 if (!$factory[0]) {
                     return;
                 }
                 if ($this->definitions[$service]->implement && $factory[1] === 'create') {
                     return $def->class = $factory[0];
                 }
             }
         }
         if (!is_callable($factory)) {
             throw new ServiceCreationException("Factory '" . Nette\Utils\Callback::toString($factory) . "' is not callable.");
         }
         try {
             $reflection = Nette\Utils\Callback::toReflection($factory);
         } catch (\ReflectionException $e) {
             throw new ServiceCreationException("Missing factory '" . Nette\Utils\Callback::toString($factory) . "'.");
         }
         $def->class = preg_replace('#[|\\s].*#', '', $reflection->getAnnotation('return'));
         if ($def->class && $reflection instanceof \ReflectionMethod) {
             $def->class = Reflection\AnnotationsParser::expandClassName($def->class, $reflection->getDeclaringClass());
         }
     } elseif ($service = $this->getServiceName($factory)) {
         // alias or factory
         if (!$def->implement) {
             $def->autowired = FALSE;
         }
         if (Strings::contains($service, '\\')) {
             // @\Class
             return $def->class = $service;
         }
         if ($this->definitions[$service]->implement) {
             $def->autowired = FALSE;
         }
         return $def->class = $this->definitions[$service]->implement ?: $this->resolveClass($service, $recursive);
     } else {
         return $def->class = $factory;
         // class name
     }
 }
Example #24
0
 private function resolveClass($name, $recursive = array())
 {
     if (isset($recursive[$name])) {
         throw new ServiceCreationException(sprintf('Circular reference detected for services: %s.', implode(', ', array_keys($recursive))));
     }
     $recursive[$name] = TRUE;
     $def = $this->definitions[$name];
     $factory = $def->factory->entity;
     if ($def->class) {
         return $def->class;
     } elseif (is_array($factory)) {
         // method calling
         if ($service = $this->getServiceName($factory[0])) {
             if (Strings::contains($service, '\\')) {
                 // @\Class
                 $factory[0] = $service;
             } else {
                 $factory[0] = $this->resolveClass($service, $recursive);
                 if (!$factory[0]) {
                     return;
                 }
                 if ($this->definitions[$service]->implement && $factory[1] === 'create') {
                     return $def->class = $factory[0];
                 }
             }
         }
         try {
             $reflection = Nette\Utils\Callback::toReflection($factory);
         } catch (\ReflectionException $e) {
         }
         if (isset($e) || !is_callable($factory)) {
             throw new ServiceCreationException(sprintf("Factory '%s' used in service '%s' is not callable.", Nette\Utils\Callback::toString($factory), $name));
         }
         $def->class = preg_replace('#[|\\s].*#', '', $reflection->getAnnotation('return'));
         if ($def->class && $reflection instanceof \ReflectionMethod) {
             $def->class = Reflection\AnnotationsParser::expandClassName($tmp = $def->class, $reflection->getDeclaringClass());
             if ($tmp !== $def->class && $tmp[0] !== '\\' && class_exists($tmp)) {
                 $def->class = $tmp;
                 trigger_error("You should use @return \\{$tmp}' in {$reflection}.", E_USER_WARNING);
             }
         }
     } elseif ($service = $this->getServiceName($factory)) {
         // alias or factory
         if (!$def->implement) {
             $def->autowired = FALSE;
         }
         if (Strings::contains($service, '\\')) {
             // @\Class
             return $def->class = $service;
         }
         if ($this->definitions[$service]->implement) {
             $def->autowired = FALSE;
         }
         return $def->class = $this->definitions[$service]->implement ?: $this->resolveClass($service, $recursive);
     } else {
         return $def->class = $factory;
         // class name
     }
 }
Example #25
0
	/**
	 * 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;
	}