Namespaces

  • Latte
    • Loaders
    • Macros
    • Runtime
  • Nette
    • Application
      • Responses
      • Routers
      • UI
    • Bridges
      • ApplicationDI
      • ApplicationLatte
      • ApplicationTracy
      • CacheDI
      • CacheLatte
      • DatabaseDI
      • DatabaseTracy
      • DITracy
      • FormsDI
      • FormsLatte
      • Framework
      • HttpDI
      • HttpTracy
      • MailDI
      • ReflectionDI
      • SecurityDI
      • SecurityTracy
    • Caching
      • Storages
    • ComponentModel
    • Database
      • Conventions
      • Drivers
      • Reflection
      • Table
    • DI
      • Config
        • Adapters
      • Extensions
    • Forms
      • Controls
      • Rendering
    • Http
    • Iterators
    • Loaders
    • Localization
    • Mail
    • Neon
    • PhpGenerator
    • Reflection
    • Security
    • Utils
  • none
  • Tracy
    • Bridges
      • Nette

Classes

  • Application
  • LinkGenerator
  • PresenterFactory
  • Request

Interfaces

  • IPresenter
  • IPresenterFactory
  • IResponse
  • IRouter

Exceptions

  • AbortException
  • ApplicationException
  • BadRequestException
  • ForbiddenRequestException
  • InvalidPresenterException
  • Overview
  • Namespace
  • Class
  • Tree
  • Deprecated
  • Other releases
  • Nette homepage
  1: <?php
  2: 
  3: /**
  4:  * This file is part of the Nette Framework (https://nette.org)
  5:  * Copyright (c) 2004 David Grudl (https://davidgrudl.com)
  6:  */
  7: 
  8: namespace Nette\Application;
  9: 
 10: use Nette;
 11: 
 12: 
 13: /**
 14:  * Default presenter loader.
 15:  */
 16: class PresenterFactory extends Nette\Object implements IPresenterFactory
 17: {
 18:     /** @deprecated */
 19:     public $caseSensitive = TRUE;
 20: 
 21:     /** @var array[] of module => splited mask */
 22:     private $mapping = array(
 23:         '*' => array('', '*Module\\', '*Presenter'),
 24:         'Nette' => array('NetteModule\\', '*\\', '*Presenter'),
 25:     );
 26: 
 27:     /** @var array */
 28:     private $cache = array();
 29: 
 30:     /** @var callable */
 31:     private $factory;
 32: 
 33: 
 34:     /**
 35:      * @param  callable  function (string $class): IPresenter
 36:      */
 37:     public function __construct($factory = NULL)
 38:     {
 39:         $this->factory = $factory ?: function ($class) { return new $class; };
 40:     }
 41: 
 42: 
 43:     /**
 44:      * Creates new presenter instance.
 45:      * @param  string  presenter name
 46:      * @return IPresenter
 47:      */
 48:     public function createPresenter($name)
 49:     {
 50:         return call_user_func($this->factory, $this->getPresenterClass($name));
 51:     }
 52: 
 53: 
 54:     /**
 55:      * Generates and checks presenter class name.
 56:      * @param  string  presenter name
 57:      * @return string  class name
 58:      * @throws InvalidPresenterException
 59:      */
 60:     public function getPresenterClass(& $name)
 61:     {
 62:         if (isset($this->cache[$name])) {
 63:             return $this->cache[$name];
 64:         }
 65: 
 66:         if (!is_string($name) || !Nette\Utils\Strings::match($name, '#^[a-zA-Z\x7f-\xff][a-zA-Z0-9\x7f-\xff:]*\z#')) {
 67:             throw new InvalidPresenterException("Presenter name must be alphanumeric string, '$name' is invalid.");
 68:         }
 69: 
 70:         $class = $this->formatPresenterClass($name);
 71:         if (!class_exists($class)) {
 72:             throw new InvalidPresenterException("Cannot load presenter '$name', class '$class' was not found.");
 73:         }
 74: 
 75:         $reflection = new \ReflectionClass($class);
 76:         $class = $reflection->getName();
 77: 
 78:         if (!$reflection->implementsInterface('Nette\Application\IPresenter')) {
 79:             throw new InvalidPresenterException("Cannot load presenter '$name', class '$class' is not Nette\\Application\\IPresenter implementor.");
 80:         } elseif ($reflection->isAbstract()) {
 81:             throw new InvalidPresenterException("Cannot load presenter '$name', class '$class' is abstract.");
 82:         }
 83: 
 84:         $this->cache[$name] = $class;
 85: 
 86:         if ($name !== ($realName = $this->unformatPresenterClass($class))) {
 87:             trigger_error("Case mismatch on presenter name '$name', correct name is '$realName'.", E_USER_WARNING);
 88:             $name = $realName;
 89:         }
 90: 
 91:         return $class;
 92:     }
 93: 
 94: 
 95:     /**
 96:      * Sets mapping as pairs [module => mask]
 97:      * @return self
 98:      */
 99:     public function setMapping(array $mapping)
100:     {
101:         foreach ($mapping as $module => $mask) {
102:             if (is_string($mask)) {
103:                 if (!preg_match('#^\\\\?([\w\\\\]*\\\\)?(\w*\*\w*?\\\\)?([\w\\\\]*\*\w*)\z#', $mask, $m)) {
104:                     throw new Nette\InvalidStateException("Invalid mapping mask '$mask'.");
105:                 }
106:                 $this->mapping[$module] = array($m[1], $m[2] ?: '*Module\\', $m[3]);
107:             } elseif (is_array($mask) && count($mask) === 3) {
108:                 $this->mapping[$module] = array($mask[0] ? $mask[0] . '\\' : '', $mask[1] . '\\', $mask[2]);
109:             } else {
110:                 throw new Nette\InvalidStateException("Invalid mapping mask for module $module.");
111:             }
112:         }
113:         return $this;
114:     }
115: 
116: 
117:     /**
118:      * Formats presenter class name from its name.
119:      * @param  string
120:      * @return string
121:      * @internal
122:      */
123:     public function formatPresenterClass($presenter)
124:     {
125:         $parts = explode(':', $presenter);
126:         $mapping = isset($parts[1], $this->mapping[$parts[0]])
127:             ? $this->mapping[array_shift($parts)]
128:             : $this->mapping['*'];
129: 
130:         while ($part = array_shift($parts)) {
131:             $mapping[0] .= str_replace('*', $part, $mapping[$parts ? 1 : 2]);
132:         }
133:         return $mapping[0];
134:     }
135: 
136: 
137:     /**
138:      * Formats presenter name from class name.
139:      * @param  string
140:      * @return string
141:      * @internal
142:      */
143:     public function unformatPresenterClass($class)
144:     {
145:         foreach ($this->mapping as $module => $mapping) {
146:             $mapping = str_replace(array('\\', '*'), array('\\\\', '(\w+)'), $mapping);
147:             if (preg_match("#^\\\\?$mapping[0]((?:$mapping[1])*)$mapping[2]\\z#i", $class, $matches)) {
148:                 return ($module === '*' ? '' : $module . ':')
149:                     . preg_replace("#$mapping[1]#iA", '$1:', $matches[1]) . $matches[3];
150:             }
151:         }
152:     }
153: 
154: }
155: 
Nette 2.3-20161221 API API documentation generated by ApiGen 2.8.0