Author: David Grudl
Inheritance: extends ReflectionClass
 /**
  * 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;
 }
Exemple #2
0
	/**
	 * Call to undefined method.
	 * @param  object
	 * @param  string  method name
	 * @param  array   arguments
	 * @return mixed
	 * @throws MemberAccessException
	 */
	public static function call($_this, $name, $args)
	{
		$class = new Reflection\ClassType($_this);

		if ($name === '') {
			throw new MemberAccessException("Call to class '$class->name' method without name.");
		}

		// event functionality
		if ($class->hasEventProperty($name)) {
			if (is_array($list = $_this->$name) || $list instanceof \Traversable) {
				foreach ($list as $handler) {
					callback($handler)->invokeArgs($args);
				}
			}
			return NULL;
		}

		// extension methods
		if ($cb = $class->getExtensionMethod($name)) {
			array_unshift($args, $_this);
			return $cb->invokeArgs($args);
		}

		throw new MemberAccessException("Call to undefined method $class->name::$name().");
	}
 /**
  * if the object contains an explicit type marker, this method attempts to convert it to its typed counterpart
  * if the typed class is already available, then simply creates a new instance of it. If not,
  * attempts to load the file from the available service folders.
  * If then the class is still not available, the object is not converted
  * note: This is not a recursive function. Rather the recusrion is handled by Amfphp_Core_Amf_Util::applyFunctionToContainedObjects.
  * must be public so that Amfphp_Core_Amf_Util::applyFunctionToContainedObjects can call it
  *
  * Part of AMFPHP
  * @author Silex Labs
  *
  * @param mixed $obj
  * @throws \Goodshape\InvalidStateException
  * @return mixed
  */
 private function convertToTyped($obj)
 {
     if (!is_object($obj)) {
         return $obj;
     }
     $explicitTypeField = Deserializer::FIELD_EXPLICIT_TYPE;
     if (isset($obj->{$explicitTypeField})) {
         $customClassName = $obj->{$explicitTypeField};
         foreach ($this->customClassesNamespaces as $namespace) {
             $fqcn = $namespace . '\\' . $customClassName;
             if (class_exists($fqcn)) {
                 //class is available. Use it!
                 $classReflection = new ClassType($fqcn);
                 $typedObj = $classReflection->newInstanceWithoutConstructor();
                 foreach ($obj as $key => $data) {
                     // loop over each element to copy it into typed object
                     if ($key != $explicitTypeField) {
                         $typedObj->{$key} = $data;
                     }
                 }
                 return $typedObj;
             }
         }
         throw new InvalidStateException("Class {$customClassName} was not found in any of provided namespaces.");
     }
     return $obj;
 }
Exemple #4
0
 /**
  * {@inheritdoc}
  */
 public function isAllowed($role, $resource, $privilege)
 {
     if ($role instanceof IRole) {
         $role = $role->getRoleId();
     }
     if (!$resource instanceof PresenterResource) {
         throw new \Ark8\Security\Exceptions\SkipException(sprintf('Resource must be instance of %s, %s given.', PresenterResource::class, gettype($resource)));
     }
     $request = $resource->getRequest();
     $presenterName = $request->getPresenterName();
     list($signal, $signalReceiver) = $this->getSignal($request);
     if (!$signal) {
         throw new \Ark8\Security\Exceptions\SkipException(sprintf('No signal sent.'));
     }
     $refClass = new PresenterComponentReflection($class = $this->presenterFactory->getPresenterClass($presenterName));
     while ($name = array_shift($signalReceiver)) {
         $name = 'createComponent' . ucfirst($name);
         if (!$refClass->hasMethod($name)) {
             throw new \Nette\InvalidStateException(sprintf('Method %s::%s is not implemented.', $refClass->getName(), $name));
         }
         $refMethod = $refClass->getMethod($name);
         if (!$refMethod->hasAnnotation('return')) {
             throw new \Nette\InvalidStateException(sprintf('Method %s::%s must have fully qualified return annotation.', $refClass->getName(), $name));
         }
         $refClass = new ClassType($refMethod->getAnnotation('return'));
     }
     if (!$refClass->hasMethod($name = Presenter::formatSignalMethod($signal))) {
         throw new \Ark8\Security\Exceptions\SkipException(sprintf('Method %s::%s is not implemented.', $refClass->getName(), $name));
     }
     $refMethod = $refClass->getMethod($name);
     if (!$refMethod->hasAnnotation($privilege)) {
         throw new \Ark8\Security\Exceptions\SkipException(sprintf('Method %s::%s does not have annotation %s.', $refClass->getName(), $name, $privilege));
     }
     return in_array($role, preg_split('#\\s+#', trim((string) $refMethod->getAnnotation($privilege))));
 }
Exemple #5
0
 /**
  * @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;
 }
 /**
  * @return array
  */
 protected function prepareRepositories()
 {
     $builder = $this->getContainerBuilder();
     $repositories = [];
     foreach ($builder->findByType(Repository::class) as $repositoryName => $definition) {
         $repositoryClass = $definition->getClass();
         $reflection = new ClassType($repositoryClass);
         $name = $reflection->getAnnotation('entity2');
         if ($name === NULL) {
             $name = $this->createEntityName($repositoryClass);
         }
         $repositories[$name] = $repositoryClass;
         $mapperClass = Strings::replace($repositoryClass, '~Repository$~', 'Mapper');
         $mapperName = $builder->getByType($mapperClass);
         if ($mapperName === NULL) {
             $mapperName = Strings::replace($repositoryName, '~Repository$~', 'Mapper');
             $builder->addDefinition($mapperName)->setClass($mapperClass)->setArguments(['cache' => '@' . $this->prefix('cache')]);
         } else {
             $builder->getDefinition($mapperName)->setArguments(['cache' => '@' . $this->prefix('cache')]);
         }
         $definition->setArguments(['mapper' => '@' . $mapperName, 'dependencyProvider' => '@' . $this->prefix('dependencyProvider')]);
         $definition->addSetup('setModel', ['@' . $this->prefix('model')]);
     }
     return $repositories;
 }
 /**
  * @param \Nette\DI\Container $dic
  * @throws MemberAccessException
  * @internal
  */
 public function injectComponentFactories(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->autowireComponentFactoriesLocator = $dic;
     $storage = $dic->hasService('autowired.cacheStorage') ? $dic->getService('autowired.cacheStorage') : $dic->getByType('Nette\\Caching\\IStorage');
     $cache = new Nette\Caching\Cache($storage, 'Kdyby.Autowired.AutowireComponentFactories');
     if ($cache->load($presenterClass = get_class($this)) !== NULL) {
         return;
     }
     $ignore = class_parents('Nette\\Application\\UI\\Presenter') + ['ui' => 'Nette\\Application\\UI\\Presenter'];
     $rc = new ClassType($this);
     foreach ($rc->getMethods() as $method) {
         if (in_array($method->getDeclaringClass()->getName(), $ignore, TRUE) || !Strings::startsWith($method->getName(), 'createComponent')) {
             continue;
         }
         foreach ($method->getParameters() as $parameter) {
             if (!($class = $parameter->getClassName())) {
                 // has object type hint
                 continue;
             }
             if (!$this->findByTypeForFactory($class) && !$parameter->allowsNull()) {
                 throw new MissingServiceException("No service of type {$class} found. Make sure the type hint in {$method} is written correctly and service of this type is registered.");
             }
         }
     }
     $files = array_map(function ($class) {
         return ClassType::from($class)->getFileName();
     }, array_diff(array_values(class_parents($presenterClass) + ['me' => $presenterClass]), $ignore));
     $files[] = ClassType::from($this->autowireComponentFactoriesLocator)->getFileName();
     $cache->save($presenterClass, TRUE, [$cache::FILES => $files]);
 }
Exemple #8
0
 /**
  * @return array
  */
 public function getTypesWithin()
 {
     if ($this->typesWithing !== NULL) {
         return $this->typesWithing;
     }
     return $this->typesWithing = class_parents($class = $this->originalType->getName()) + class_implements($class) + [$class => $class];
 }
Exemple #9
0
	/**
	 * @param string
	 * @param string
	 * @return array
	 */
	public static function parseAnnotations($class, $method = NULL)
	{
		if (strpos($class, '::') !== FALSE && !$method) {
			list($class, $method) = explode('::', $class);
		}

		$ref = new Reflection\Method($class, $method);
		$cRef = new Reflection\ClassType($class);
		$anntations = (array)$ref->getAnnotation('allowed');

		$role = isset($anntations['role']) ? $anntations['role']
			: ($ref->hasAnnotation('role') ? $ref->getAnnotation('role') : NULL);

		$resource = isset($anntations['resource']) ? $anntations['resource']
			: ($ref->hasAnnotation('resource')
			? $ref->getAnnotation('resource')
				: ($cRef->hasAnnotation('resource') ? $cRef->getAnnotation('resource') : NULL));

		$privilege = isset($anntations['privilege']) ? $anntations['privilege']
			: ($ref->hasAnnotation('privilege') ? $ref->getAnnotation('privilege') : NULL);

		return array(
			static::ROLE => $role,
			static::RESOURCE => $resource,
			static::PRIVILEGE => $privilege,
		);
	}
 protected function setupTemplate($view = "default", $filename = null)
 {
     $controlReflection = new Nette\Reflection\ClassType(get_class($this));
     $controlDir = dirname($controlReflection->getFileName());
     $filename = $filename ? $controlDir . DIRECTORY_SEPARATOR . $filename : $controlDir . DIRECTORY_SEPARATOR . "{$view}.latte";
     $this->template->setFile($filename);
     return $this->template;
 }
 /**
  * Returns all classes implementing specified interface
  *
  * @param string interface name
  * @return array of fully qualified class names (with namespace)
  */
 public function getAllClassesImplementing($interfaceName)
 {
     $cacheKey = array();
     $cacheKey[] = 'implementing';
     $cacheKey[] = $interfaceName;
     return $this->getAllClassesHelper($cacheKey, function ($className) use($interfaceName) {
         $class = new Nette\Reflection\ClassType($className);
         return $class->implementsInterface($interfaceName) && $interfaceName != $className;
     });
 }
Exemple #12
0
 /**
  * @param array $values
  */
 public function createNew($arguments = array())
 {
     $class = $this->getEntityName();
     if (!$arguments) {
         $entity = new $class();
     } else {
         $reflection = new Nette\Reflection\ClassType($class);
         $entity = $reflection->newInstanceArgs($arguments);
     }
     return $entity;
 }
 public function startup()
 {
     parent::startup();
     $classReflection = new Nette\Reflection\ClassType('Helpers');
     $methods = $classReflection->getMethods();
     foreach ($methods as $method) {
         $this->template->registerHelper($method->getName(), 'Helpers::' . $method->getName());
     }
     $this->template->kategorie = $this->kategorie->getMenu();
     $this->template->aktuality = $this->clanky->getClanky(5, 0, "aktuality", null, true);
 }
 /**
  * @return array
  */
 public final function getSubscribedEvents()
 {
     $list = [];
     $ref = new ClassType($this);
     foreach ($ref->getMethods() as $method) {
         if ($method->getAnnotation('subscribe')) {
             $list[] = $method->name;
         }
     }
     return $list;
 }
 /**
  * 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;
 }
Exemple #16
0
 /**
  * Allowing to emit static events through public variable
  *
  * @param string name
  * @param array of args
  * @return mixed
  */
 public static function __callStatic($name, $args)
 {
     $class = new Nette\Reflection\ClassType(get_called_class());
     $properties = $class->getStaticProperties();
     if (isset($properties[$name])) {
         if (is_array($list = $properties[$name]) || $list instanceof \Traversable) {
             foreach ($list as $handler) {
                 callback($handler)->invokeArgs($args);
             }
         }
         return NULL;
     }
     return parent::__callStatic($name, $args);
 }
 private function walkClassHierarchy(ClassType $classType, &$expressions)
 {
     $parentClass = $classType->getParentClass();
     if ($parentClass) {
         $this->walkClassHierarchy($parentClass, $expressions);
     }
     $annotation = $classType->getAnnotation('Security');
     if ($annotation) {
         if (!is_string($annotation)) {
             throw new \InvalidArgumentException('Security annotation must be simple string with expression.');
         }
         $expressions[] = new Expression($annotation);
     }
 }
Exemple #18
0
 public function setValues($values)
 {
     $values = (array) $values;
     $refl = new ClassType($this->getClassName());
     foreach ($values as $key => $value) {
         if ($refl->hasProperty($key)) {
             $setterName = 'set' . ucfirst($key);
             if ($refl->hasMethod($setterName)) {
                 $this->{$setterName}($value);
             } else {
                 $this->{$key} = $value;
             }
         }
     }
 }
 public function beforeCompile()
 {
     $builder = $this->getContainerBuilder();
     $definitions = $builder->getDefinitions();
     $templateFactory = $builder->getDefinition("templateFactory");
     foreach ($definitions as $definition) {
         if (!$definition->factory || !class_exists($definition->factory->entity)) {
             continue;
         }
         $classReflection = new Nette\Reflection\ClassType($definition->factory->entity);
         if ($classReflection->implementsInterface("HotelQuickly\\Factory\\IControlFactory")) {
             $definition->addSetup("setTemplateFactory", array($templateFactory));
         }
     }
 }
 /**
  * @param string
  * @param callable
  * @param string
  */
 public function addImporter($id, $factory, $class)
 {
     if (isset($this->factories[$id])) {
         throw new \NetteAddons\InvalidStateException("Importer '{$id}' is already registered");
     }
     if (!is_callable($factory)) {
         throw new \NetteAddons\InvalidArgumentException('Factory is not callable.');
     }
     $classRef = new ClassType($class);
     if (!$classRef->implementsInterface('NetteAddons\\Model\\IAddonImporter')) {
         throw new \NetteAddons\InvalidArgumentException("Class '{$class}' does not implement IAddonImporter.");
     }
     $this->factories[$id] = $factory;
     $this->classes[$id] = $class;
 }
Exemple #21
0
 public static function build($className)
 {
     $reflection = \Nette\Reflection\ClassType::from($className);
     $annotations = $reflection->getAnnotations();
     $ret = array('entityClass' => $className);
     foreach ($annotations as $key => $value) {
         if ($key == "Entity") {
             $entity = $value[0];
             if (isset($entity->repositoryClass)) {
                 $ret['repositoryClass'] = (string) $entity->repositoryClass;
             } elseif (isset($entity->validatorClass)) {
                 $ret['validatorClass'] = (string) $entity->validatorClass;
             }
         } elseif ($key == "Table") {
             $table = $value[0];
             $ret['table'] = (string) $table->name;
             $ret['mainIndex'] = isset($table->mainIndex) ? (string) $table->mainIndex : NULL;
             $ret['topicIndex'] = isset($table->topicIndex) ? (string) $table->topicIndex : NULL;
         } elseif ($key == "Column") {
             foreach ($value as $column) {
                 $name = $column->name;
                 unset($column->name);
                 $ret['columns'][$name] = (array) $column;
             }
         } elseif (in_array($key, array("AssociationHasOne", "AssociationHasMany"))) {
             foreach ($value as $association) {
                 $name = $association->name;
                 unset($association->name);
                 $ret['associations'][$name] = (array) $association;
             }
         }
     }
     return $ret;
 }
Exemple #22
0
 private function setupServices()
 {
     $builder = $this->getContainerBuilder();
     $config = $this->validateConfig($this->defaults);
     $gopay = $builder->getDefinition($this->prefix('gopay'));
     $services = ['payment' => PaymentService::class, 'recurrentPayment' => RecurrentPaymentService::class, 'preAuthorizedPayment' => PreAuthorizedPaymentService::class];
     foreach ($services as $serviceName => $serviceClass) {
         $def = $builder->addDefinition($this->prefix("service.{$serviceName}"))->setClass($serviceClass, [$gopay]);
         if (is_bool($config['payments']['changeChannel'])) {
             $def->addSetup('allowChangeChannel', [$config['payments']['changeChannel']]);
         }
         if (isset($config['payments']['channels'])) {
             $constants = ClassType::from(Gopay::class);
             foreach ($config['payments']['channels'] as $code => $channel) {
                 $constChannel = 'METHOD_' . strtoupper($code);
                 if ($constants->hasConstant($constChannel)) {
                     $code = $constants->getConstant($constChannel);
                 }
                 if (is_array($channel)) {
                     $channel['code'] = $code;
                     $def->addSetup('addChannel', $channel);
                 } else {
                     if (is_scalar($channel)) {
                         $def->addSetup('addChannel', [$code, $channel]);
                     }
                 }
             }
         }
     }
 }
Exemple #23
0
 /**
  * @param $class
  */
 public function getSchema($class)
 {
     if (!isset($this->_annotationSchema[$class])) {
         $schema = array();
         $ref = ClassType::from($class);
         if ($ref->hasAnnotation('secured')) {
             foreach ($ref->getMethods() as $method) {
                 $name = $method->getName();
                 if (substr($name, 0, 6) !== 'action' && substr($name, 0, 6) !== 'handle') {
                     continue;
                 }
                 if ($method->hasAnnotation('secured')) {
                     $secured = $method->getAnnotation('secured');
                     $name = $method->getName();
                     $schema[$name] = array();
                     $schema[$name]['resource'] = $this->getSchemaOfResource($method, $secured);
                     $schema[$name]['privilege'] = $this->getSchemaOfPrivilege($method, $secured);
                     $schema[$name]['roles'] = $this->getSchemaOfRoles($method, $secured);
                     $schema[$name]['users'] = $this->getSchemaOfUsers($method, $secured);
                 }
             }
         }
         $this->_annotationSchema[$class] = $schema;
     }
     return $this->_annotationSchema[$class];
 }
	public function testSignalAllow()
	{
		$this->presenter->setSignalMock("test2");
		$this->presenter->checkRequirements(ClassType::from(__NAMESPACE__ . '\BackendPresenter\PresenterMock'));

		$this->assertFalse($this->presenter->isAllowedMock('handleTest1'));
		$this->assertTrue($this->presenter->isAllowedMock('handleTest2'));
	}
Exemple #25
0
 public function __construct($type)
 {
     if (strpos($type, '*') !== FALSE) {
         $this->pattern = str_replace('\\*', '.*', preg_quote($type));
     } else {
         $this->type = Nette\Reflection\ClassType::from($type)->getName();
     }
 }
 /**
  * Sets a variable in this session section.
  * @param  string  name
  * @param  mixed   value
  * @return void
  */
 public function __set($name, $value)
 {
     $this->start();
     $this->data[$name] = $value;
     if (is_object($value)) {
         $this->meta[$name]['V'] = Nette\Reflection\ClassType::from($value)->getAnnotation('serializationVersion');
     }
 }
 /**
  * Parses class annotation and build metadata object
  * 
  * @param Nette\Reflection\ClassType $reflection 
  * @throws vBuilder\InvalidAnnotationException if any annotation is missing or bad formed
  */
 public function __construct(Nette\Reflection\ClassType $reflection)
 {
     // Nazev tabulky
     $annotations = $reflection->getAnnotations();
     if (isset($annotations['Table']) && isset($annotations['Table'][0]['name'])) {
         $this->tableName = $annotations['Table'][0]['name'];
     }
     // Entitni chovani
     if (isset($annotations['Behavior'])) {
         foreach ($annotations['Behavior'] as $curr) {
             if (!is_array($curr) && !$curr instanceof \Traversable) {
                 $this->behaviors[$curr] = array();
                 continue;
             }
             $curr = (array) $curr;
             $this->behaviors[array_shift($curr)] = $curr;
         }
     }
     // Sloupecky
     if (isset($annotations['Column'])) {
         foreach ($annotations['Column'] as $curr) {
             // Prazdne definice
             if ($curr === true) {
                 continue;
             }
             if (!is_array($curr) && !$curr instanceof \Traversable) {
                 $this->fields[$curr] = array();
                 continue;
             }
             $curr = (array) $curr;
             $name = array_shift($curr);
             $this->fields[$name] = array();
             foreach ($curr as $k => $v) {
                 if (is_numeric($k)) {
                     $this->fields[$name][$v] = true;
                 } else {
                     $this->fields[$name][$k] = $v;
                 }
             }
             if (isset($this->fields[$name]['id']) || isset($this->fields[$name]['pk'])) {
                 $this->idFields[] = $name;
             }
         }
     }
 }
Exemple #28
0
 public function loadConfiguration()
 {
     $builder = $this->getContainerBuilder();
     $latte = $builder->hasDefinition('nette.latteFactory') ? $builder->getDefinition('nette.latteFactory') : $builder->getDefinition('nette.latte');
     $latte->addSetup('Lohini\\Latte\\Macros\\CoreMacros::install(?->getCompiler())', ['@self']);
     foreach (\Nette\Reflection\ClassType::from('Lohini\\Latte\\Filters')->getMethods() as $method) {
         $latte->addSetup('addFilter', [$method->name, ['Lohini\\Latte\\Filters', $method->name]]);
     }
 }
Exemple #29
0
 public function init()
 {
     if ($this->presenterMap !== NULL) {
         return;
     }
     $this->presenterMap = $this->nameMap = array();
     foreach ($this->findClasses() as $className) {
         $class = new ClassType($className);
         $presenter = ltrim($class->getAnnotation('Presenter'), ':');
         $name = $class->getAnnotation('Name');
         if ($presenter) {
             $this->presenterMap[substr($presenter, -1) === ':' ? $presenter . 'default' : $presenter] = $className;
         }
         if ($name) {
             $this->nameMap[$className] = $name;
         }
     }
 }
 /**
  * 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)) {
             call_user_func(function () use($file) {
                 require $file;
             });
         }
         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;
 }