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

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