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
    • Diagnostics
    • Forms
      • Controls
      • Rendering
    • Http
    • Iterators
    • Latte
    • Loaders
    • Localization
    • Mail
    • Neon
    • PhpGenerator
    • Reflection
    • Security
    • Templating
    • Utils
  • NetteModule
  • none
  • Tracy
    • Bridges
      • Nette

Classes

  • ApplicationExtension
  • LatteExtension
  • RoutingExtension
  • Overview
  • Namespace
  • Class
  • Tree
  • Deprecated
  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\Bridges\ApplicationDI;
  9: 
 10: use Nette;
 11: use Nette\Application\UI;
 12: 
 13: 
 14: /**
 15:  * Application extension for Nette DI.
 16:  */
 17: class ApplicationExtension extends Nette\DI\CompilerExtension
 18: {
 19:     public $defaults = array(
 20:         'debugger' => TRUE,
 21:         'errorPresenter' => 'Nette:Error',
 22:         'catchExceptions' => NULL,
 23:         'mapping' => NULL,
 24:         'scanDirs' => array(),
 25:         'scanComposer' => NULL,
 26:         'scanFilter' => 'Presenter',
 27:         'silentLinks' => FALSE,
 28:     );
 29: 
 30:     /** @var bool */
 31:     private $debugMode;
 32: 
 33:     /** @var int */
 34:     private $invalidLinkMode;
 35: 
 36:     /** @var string */
 37:     private $tempFile;
 38: 
 39: 
 40:     public function __construct($debugMode = FALSE, array $scanDirs = NULL, $tempDir = NULL)
 41:     {
 42:         $this->defaults['scanDirs'] = (array) $scanDirs;
 43:         $this->defaults['scanComposer'] = class_exists('Composer\Autoload\ClassLoader');
 44:         $this->defaults['catchExceptions'] = !$debugMode;
 45:         $this->debugMode = $debugMode;
 46:         $this->tempFile = $tempDir ? $tempDir . '/' . urlencode(__CLASS__) : NULL;
 47:     }
 48: 
 49: 
 50:     public function loadConfiguration()
 51:     {
 52:         $config = $this->validateConfig($this->defaults);
 53:         $container = $this->getContainerBuilder();
 54:         $container->addExcludedClasses(array('Nette\Application\UI\Control'));
 55: 
 56:         $this->invalidLinkMode = $this->debugMode
 57:             ? UI\Presenter::INVALID_LINK_TEXTUAL | ($config['silentLinks'] ? 0 : UI\Presenter::INVALID_LINK_WARNING)
 58:             : UI\Presenter::INVALID_LINK_WARNING;
 59: 
 60:         $application = $container->addDefinition($this->prefix('application'))
 61:             ->setClass('Nette\Application\Application')
 62:             ->addSetup('$catchExceptions', array($config['catchExceptions']))
 63:             ->addSetup('$errorPresenter', array($config['errorPresenter']));
 64: 
 65:         if ($config['debugger']) {
 66:             $application->addSetup('Nette\Bridges\ApplicationTracy\RoutingPanel::initializePanel');
 67:         }
 68: 
 69:         $touch = $this->debugMode && $config['scanDirs'] ? $this->tempFile : NULL;
 70:         $presenterFactory = $container->addDefinition($this->prefix('presenterFactory'))
 71:             ->setClass('Nette\Application\IPresenterFactory')
 72:             ->setFactory('Nette\Application\PresenterFactory', array(new Nette\DI\Statement(
 73:                 'Nette\Bridges\ApplicationDI\PresenterFactoryCallback', array(1 => $this->invalidLinkMode, $touch)
 74:             )));
 75: 
 76:         if ($config['mapping']) {
 77:             $presenterFactory->addSetup('setMapping', array($config['mapping']));
 78:         }
 79: 
 80:         $container->addDefinition($this->prefix('linkGenerator'))
 81:             ->setFactory('Nette\Application\LinkGenerator', array(
 82:                 1 => new Nette\DI\Statement('@Nette\Http\IRequest::getUrl'),
 83:             ));
 84: 
 85:         if ($this->name === 'application') {
 86:             $container->addAlias('application', $this->prefix('application'));
 87:             $container->addAlias('nette.presenterFactory', $this->prefix('presenterFactory'));
 88:         }
 89:     }
 90: 
 91: 
 92:     public function beforeCompile()
 93:     {
 94:         $container = $this->getContainerBuilder();
 95:         $all = array();
 96: 
 97:         foreach ($container->findByType('Nette\Application\IPresenter') as $def) {
 98:             $all[$def->getClass()] = $def;
 99:         }
100: 
101:         $counter = 0;
102:         foreach ($this->findPresenters() as $class) {
103:             if (empty($all[$class])) {
104:                 $all[$class] = $container->addDefinition($this->prefix(++$counter))->setClass($class);
105:             }
106:         }
107: 
108:         foreach ($all as $def) {
109:             $def->setInject(TRUE)->setAutowired(FALSE)->addTag('nette.presenter', $def->getClass());
110:             if (is_subclass_of($def->getClass(), 'Nette\Application\UI\Presenter')) {
111:                 $def->addSetup('$invalidLinkMode', array($this->invalidLinkMode));
112:             }
113:         }
114:     }
115: 
116: 
117:     /** @return string[] */
118:     private function findPresenters()
119:     {
120:         $config = $this->getConfig();
121:         $classes = array();
122: 
123:         if ($config['scanDirs']) {
124:             if (!class_exists('Nette\Loaders\RobotLoader')) {
125:                 throw new Nette\NotSupportedException("RobotLoader is required to find presenters, install package `nette/robot-loader` or disable option {$this->prefix('scanDirs')}: false");
126:             }
127:             $robot = new Nette\Loaders\RobotLoader;
128:             $robot->setCacheStorage(new Nette\Caching\Storages\DevNullStorage);
129:             $robot->addDirectory($config['scanDirs']);
130:             $robot->acceptFiles = '*' . $config['scanFilter'] . '*.php';
131:             $robot->rebuild();
132:             $classes = array_keys($robot->getIndexedClasses());
133:             $this->getContainerBuilder()->addDependency($this->tempFile);
134:         }
135: 
136:         if ($config['scanComposer']) {
137:             $rc = new \ReflectionClass('Composer\Autoload\ClassLoader');
138:             $classFile = dirname($rc->getFileName()) . '/autoload_classmap.php';
139:             if (is_file($classFile)) {
140:                 $this->getContainerBuilder()->addDependency($classFile);
141:                 $classes = array_merge($classes, array_keys(call_user_func(function ($path) {
142:                     return require $path;
143:                 }, $classFile)));
144:             }
145:         }
146: 
147:         $presenters = array();
148:         foreach (array_unique($classes) as $class) {
149:             if (strpos($class, $config['scanFilter']) !== FALSE && class_exists($class)
150:                 && ($rc = new \ReflectionClass($class)) && $rc->implementsInterface('Nette\Application\IPresenter')
151:                 && !$rc->isAbstract()
152:             ) {
153:                 $presenters[] = $rc->getName();
154:             }
155:         }
156:         return $presenters;
157:     }
158: 
159: }
160: 
Nette 2.3.8 API API documentation generated by ApiGen 2.8.0