/** * Generates and checks presenter class name. * * @param string presenter name * @return string class name * @throws Application\InvalidPresenterException */ public function getPresenterClass(&$name) { if (isset($this->cache[$name])) { return $this->cache[$name]; } if (!is_string($name) || !Nette\Utils\Strings::match($name, '#^[a-zA-Z\\x7f-\\xff][a-zA-Z0-9\\x7f-\\xff:]*\\z#')) { throw new Application\InvalidPresenterException("Presenter name must be alphanumeric string, '{$name}' is invalid."); } $classes = $this->formatPresenterClasses($name); if (!$classes) { throw new Application\InvalidPresenterException("Cannot load presenter '{$name}', no applicable mapping found."); } $class = $this->findValidClass($classes); if (!$class) { throw new Application\InvalidPresenterException("Cannot load presenter '{$name}', none of following classes were found: " . implode(', ', $classes)); } $reflection = new Nette\Reflection\ClassType($class); $class = $reflection->getName(); if (!$reflection->implementsInterface('Nette\\Application\\IPresenter')) { throw new Application\InvalidPresenterException("Cannot load presenter '{$name}', class '{$class}' is not Nette\\Application\\IPresenter implementor."); } if ($reflection->isAbstract()) { throw new Application\InvalidPresenterException("Cannot load presenter '{$name}', class '{$class}' is abstract."); } return $this->cache[$name] = $class; }
/** * Generates and checks presenter class name. * @param string presenter name * @return string class name * @throws InvalidPresenterException */ public function getPresenterClass(&$name) { if (isset($this->cache[$name])) { list($class, $name) = $this->cache[$name]; return $class; } if (!is_string($name) || !Nette\Utils\Strings::match($name, '#^[a-zA-Z\\x7f-\\xff][a-zA-Z0-9\\x7f-\\xff:]*\\z#')) { throw new InvalidPresenterException("Presenter name must be alphanumeric string, '{$name}' is invalid."); } $class = $this->formatPresenterClass($name); if (!class_exists($class)) { // internal autoloading $file = $this->formatPresenterFile($name); if (is_file($file) && is_readable($file)) { Nette\Utils\LimitedScope::load($file, TRUE); } if (!class_exists($class)) { throw new InvalidPresenterException("Cannot load presenter '{$name}', class '{$class}' was not found in '{$file}'."); } } $reflection = new Nette\Reflection\ClassType($class); $class = $reflection->getName(); if (!$reflection->implementsInterface('Nette\\Application\\IPresenter')) { throw new InvalidPresenterException("Cannot load presenter '{$name}', class '{$class}' is not Nette\\Application\\IPresenter implementor."); } if ($reflection->isAbstract()) { throw new InvalidPresenterException("Cannot load presenter '{$name}', class '{$class}' is abstract."); } // canonicalize presenter name $realName = $this->unformatPresenterClass($class); if ($name !== $realName) { if ($this->caseSensitive) { throw new InvalidPresenterException("Cannot load presenter '{$name}', case mismatch. Real name is '{$realName}'."); } else { $this->cache[$name] = array($class, $realName); $name = $realName; } } else { $this->cache[$name] = array($class, $realName); } return $class; }
private function loadDefinitions(ContainerBuilder $builder) { $classes = $this->robotLoader->getIndexedClasses(); $markerInterface = new ClassType(IServiceMarker::class); foreach ($classes as $key => $val) { if (Strings::endsWith($key, 'Service')) { $reflection = new ClassType($key); $serviceName = '_auto.' . str_replace("\\", "_", $key); if (!$reflection->isAbstract() && $reflection->isSubclassOf($markerInterface)) { $builder->addDefinition($serviceName)->setClass($key); } } } }
/** * Parse class and returns names and target classes of annotated properties * @param $className * @return mixed * @throws RestException */ public function getAnnotatedProperties($className) { if (!isset($this->classProperties[$className])) { $this->classProperties[$className] = array(); $ref = new ClassType($className); if ($ref->isAbstract() or $ref->isInterface()) { throw new RestException("Class can not be either abstract nor interface"); } $ann = $ref->getAnnotations(); $parents = class_parents($className); $parents[$className] = $className; if ($className != DataHash::class and (!$parents or !in_array(DataHash::class, $parents))) { throw RestException::notInheritedForm($className, DataHash::class); } $this->parseProperties($ref, $ann, 'property'); $this->parseProperties($ref, $ann, 'property-read'); } return $this->classProperties[$className]; }
/** * @param array $dirs * @param array $interfaces * @return array */ private function findByInterfaces(array $dirs, array $interfaces) { $loader = $this->createLoader(); $loader->addDirectory($dirs); $loader->rebuild(); $loader->register(); $classes = []; foreach (array_keys($loader->getIndexedClasses()) as $class) { // Skip not existing class if (!class_exists($class, TRUE)) { continue; } // Detect by reflection $ct = new ClassType($class); // Skip abstract if ($ct->isAbstract()) { continue; } // Does class implement one of given interface foreach ($interfaces as $interface) { if ($ct->implementsInterface($interface)) { $classes[] = $ct->getName(); } } } return $classes; }