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

  • Callback
  • Configurator
  • Environment
  • Framework
  • FreezableObject
  • Object

Interfaces

  • IFreezable

Exceptions

  • ArgumentOutOfRangeException
  • DeprecatedException
  • DirectoryNotFoundException
  • FileNotFoundException
  • InvalidArgumentException
  • InvalidStateException
  • IOException
  • MemberAccessException
  • NotImplementedException
  • NotSupportedException
  • OutOfRangeException
  • StaticClassException
  • UnexpectedValueException
  • 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;
  9: 
 10: use Nette;
 11: use Nette\DI;
 12: use Tracy;
 13: 
 14: 
 15: /**
 16:  * Initial system DI container generator.
 17:  */
 18: class Configurator extends Object
 19: {
 20:     const AUTO = TRUE,
 21:         NONE = FALSE;
 22: 
 23:     const COOKIE_SECRET = 'nette-debug';
 24: 
 25:     /** @var callable[]  function (Configurator $sender, DI\Compiler $compiler); Occurs after the compiler is created */
 26:     public $onCompile;
 27: 
 28:     /** @var array */
 29:     public $defaultExtensions = array(
 30:         'php' => 'Nette\DI\Extensions\PhpExtension',
 31:         'constants' => 'Nette\DI\Extensions\ConstantsExtension',
 32:         'extensions' => 'Nette\DI\Extensions\ExtensionsExtension',
 33:         'application' => array('Nette\Bridges\ApplicationDI\ApplicationExtension', array('%debugMode%', array('%appDir%'), '%tempDir%/cache')),
 34:         'decorator' => 'Nette\DI\Extensions\DecoratorExtension',
 35:         'cache' => array('Nette\Bridges\CacheDI\CacheExtension', array('%tempDir%')),
 36:         'database' => array('Nette\Bridges\DatabaseDI\DatabaseExtension', array('%debugMode%')),
 37:         'di' => array('Nette\DI\Extensions\DIExtension', array('%debugMode%')),
 38:         'forms' => 'Nette\Bridges\FormsDI\FormsExtension',
 39:         'http' => 'Nette\Bridges\HttpDI\HttpExtension',
 40:         'latte' => array('Nette\Bridges\ApplicationDI\LatteExtension', array('%tempDir%/cache/latte', '%debugMode%')),
 41:         'mail' => 'Nette\Bridges\MailDI\MailExtension',
 42:         'reflection' => array('Nette\Bridges\ReflectionDI\ReflectionExtension', array('%debugMode%')),
 43:         'routing' => array('Nette\Bridges\ApplicationDI\RoutingExtension', array('%debugMode%')),
 44:         'security' => array('Nette\Bridges\SecurityDI\SecurityExtension', array('%debugMode%')),
 45:         'session' => array('Nette\Bridges\HttpDI\SessionExtension', array('%debugMode%')),
 46:         'tracy' => array('Tracy\Bridges\Nette\TracyExtension', array('%debugMode%')),
 47:         'inject' => 'Nette\DI\Extensions\InjectExtension',
 48:     );
 49: 
 50:     /** @var string[] of classes which shouldn't be autowired */
 51:     public $autowireExcludedClasses = array(
 52:         'stdClass',
 53:     );
 54: 
 55:     /** @var array */
 56:     protected $parameters;
 57: 
 58:     /** @var array */
 59:     protected $services = array();
 60: 
 61:     /** @var array [file|array, section] */
 62:     protected $files = array();
 63: 
 64: 
 65:     public function __construct()
 66:     {
 67:         $this->parameters = $this->getDefaultParameters();
 68:     }
 69: 
 70: 
 71:     /**
 72:      * Set parameter %debugMode%.
 73:      * @param  bool|string|array
 74:      * @return self
 75:      */
 76:     public function setDebugMode($value)
 77:     {
 78:         if (is_string($value) || is_array($value)) {
 79:             $value = static::detectDebugMode($value);
 80:         } elseif (!is_bool($value)) {
 81:             throw new Nette\InvalidArgumentException(sprintf('Value must be either a string, array, or boolean, %s given.', gettype($value)));
 82:         }
 83:         $this->parameters['debugMode'] = $value;
 84:         $this->parameters['productionMode'] = !$this->parameters['debugMode']; // compatibility
 85:         $this->parameters['environment'] = $this->parameters['debugMode'] ? 'development' : 'production';
 86:         return $this;
 87:     }
 88: 
 89: 
 90:     /**
 91:      * @return bool
 92:      */
 93:     public function isDebugMode()
 94:     {
 95:         return $this->parameters['debugMode'];
 96:     }
 97: 
 98: 
 99:     /**
100:      * Sets path to temporary directory.
101:      * @return self
102:      */
103:     public function setTempDirectory($path)
104:     {
105:         $this->parameters['tempDir'] = $path;
106:         return $this;
107:     }
108: 
109: 
110:     /**
111:      * Adds new parameters. The %params% will be expanded.
112:      * @return self
113:      */
114:     public function addParameters(array $params)
115:     {
116:         $this->parameters = DI\Config\Helpers::merge($params, $this->parameters);
117:         return $this;
118:     }
119: 
120: 
121:     /**
122:      * Add instances of services.
123:      * @return self
124:      */
125:     public function addServices(array $services)
126:     {
127:         $this->services = $services + $this->services;
128:         return $this;
129:     }
130: 
131: 
132:     /**
133:      * @return array
134:      */
135:     protected function getDefaultParameters()
136:     {
137:         $trace = debug_backtrace(PHP_VERSION_ID >= 50306 ? DEBUG_BACKTRACE_IGNORE_ARGS : FALSE);
138:         $last = end($trace);
139:         $debugMode = static::detectDebugMode();
140:         return array(
141:             'appDir' => isset($trace[1]['file']) ? dirname($trace[1]['file']) : NULL,
142:             'wwwDir' => isset($last['file']) ? dirname($last['file']) : NULL,
143:             'debugMode' => $debugMode,
144:             'productionMode' => !$debugMode,
145:             'environment' => $debugMode ? 'development' : 'production',
146:             'consoleMode' => PHP_SAPI === 'cli',
147:             'container' => array(
148:                 'class' => NULL,
149:                 'parent' => NULL,
150:             ),
151:         );
152:     }
153: 
154: 
155:     /**
156:      * @param  string        error log directory
157:      * @param  string        administrator email
158:      * @return void
159:      */
160:     public function enableDebugger($logDirectory = NULL, $email = NULL)
161:     {
162:         Tracy\Debugger::$strictMode = TRUE;
163:         Tracy\Debugger::enable(!$this->parameters['debugMode'], $logDirectory, $email);
164:         Nette\Bridges\Framework\TracyBridge::initialize();
165:     }
166: 
167: 
168:     /**
169:      * @return Nette\Loaders\RobotLoader
170:      * @throws Nette\NotSupportedException if RobotLoader is not available
171:      */
172:     public function createRobotLoader()
173:     {
174:         if (!class_exists('Nette\Loaders\RobotLoader')) {
175:             throw new Nette\NotSupportedException('RobotLoader not found, do you have `nette/robot-loader` package installed?');
176:         }
177: 
178:         $loader = new Nette\Loaders\RobotLoader;
179:         $loader->setCacheStorage(new Nette\Caching\Storages\FileStorage($this->getCacheDirectory()));
180:         $loader->autoRebuild = $this->parameters['debugMode'];
181:         return $loader;
182:     }
183: 
184: 
185:     /**
186:      * Adds configuration file.
187:      * @return self
188:      */
189:     public function addConfig($file, $section = NULL)
190:     {
191:         if ($section === NULL && is_string($file) && $this->parameters['debugMode']) { // back compatibility
192:             try {
193:                 $loader = new DI\Config\Loader;
194:                 $loader->load($file, $this->parameters['environment']);
195:                 trigger_error("Config file '$file' has sections, call addConfig() with second parameter Configurator::AUTO.", E_USER_WARNING);
196:                 $section = $this->parameters['environment'];
197:             } catch (\Exception $e) {
198:             }
199:         }
200:         $this->files[] = array($file, $section === self::AUTO ? $this->parameters['environment'] : $section);
201:         return $this;
202:     }
203: 
204: 
205:     /**
206:      * Returns system DI container.
207:      * @return DI\Container
208:      */
209:     public function createContainer()
210:     {
211:         $loader = new DI\ContainerLoader(
212:             $this->getCacheDirectory() . '/Nette.Configurator',
213:             $this->parameters['debugMode']
214:         );
215:         $class = $loader->load(
216:             array($this->parameters, $this->files, PHP_VERSION_ID - PHP_RELEASE_VERSION),
217:             array($this, 'generateContainer')
218:         );
219: 
220:         $container = new $class;
221:         foreach ($this->services as $name => $service) {
222:             $container->addService($name, $service);
223:         }
224:         $container->initialize();
225:         if (class_exists('Nette\Environment')) {
226:             Nette\Environment::setContext($container); // back compatibility
227:         }
228:         return $container;
229:     }
230: 
231: 
232:     /**
233:      * @return string
234:      * @internal
235:      */
236:     public function generateContainer(DI\Compiler $compiler)
237:     {
238:         $loader = $this->createLoader();
239:         $compiler->addConfig(array('parameters' => $this->parameters));
240:         $fileInfo = array();
241:         foreach ($this->files as $info) {
242:             if (is_scalar($info[0])) {
243:                 $fileInfo[] = "// source: $info[0] $info[1]";
244:                 $info[0] = $loader->load($info[0], $info[1]);
245:             }
246:             $compiler->addConfig($this->fixCompatibility($info[0]));
247:         }
248:         $compiler->addDependencies($loader->getDependencies());
249: 
250:         $builder = $compiler->getContainerBuilder();
251:         $builder->addExcludedClasses($this->autowireExcludedClasses);
252: 
253:         foreach ($this->defaultExtensions as $name => $extension) {
254:             list($class, $args) = is_string($extension) ? array($extension, array()) : $extension;
255:             if (class_exists($class)) {
256:                 $rc = new \ReflectionClass($class);
257:                 $args = DI\Helpers::expand($args, $this->parameters, TRUE);
258:                 $compiler->addExtension($name, $args ? $rc->newInstanceArgs($args) : $rc->newInstance());
259:             }
260:         }
261: 
262:         $this->onCompile($this, $compiler);
263: 
264:         $classes = $compiler->compile();
265: 
266:         if (!empty($builder->parameters['container']['parent'])) {
267:             $classes[0]->setExtends($builder->parameters['container']['parent']);
268:         }
269: 
270:         return implode("\n", $fileInfo) . "\n\n" . implode("\n\n\n", $classes)
271:             . (($tmp = $builder->parameters['container']['class']) ? "\nclass $tmp extends {$builder->getClassName()} {}\n" : '');
272:     }
273: 
274: 
275:     /**
276:      * @return DI\Config\Loader
277:      */
278:     protected function createLoader()
279:     {
280:         return new DI\Config\Loader;
281:     }
282: 
283: 
284:     protected function getCacheDirectory()
285:     {
286:         if (empty($this->parameters['tempDir'])) {
287:             throw new Nette\InvalidStateException('Set path to temporary directory using setTempDirectory().');
288:         }
289:         $dir = $this->parameters['tempDir'] . '/cache';
290:         if (!is_dir($dir)) {
291:             @mkdir($dir); // @ - directory may already exist
292:         }
293:         return $dir;
294:     }
295: 
296: 
297:     /**
298:      * Back compatibility with < v2.3
299:      * @return array
300:      */
301:     protected function fixCompatibility($config)
302:     {
303:         if (isset($config['nette']['security']['frames'])) {
304:             $config['nette']['http']['frames'] = $config['nette']['security']['frames'];
305:             unset($config['nette']['security']['frames']);
306:         }
307:         foreach (array('application', 'cache', 'database', 'di' => 'container', 'forms', 'http',
308:             'latte', 'mail' => 'mailer', 'routing', 'security', 'session', 'tracy' => 'debugger') as $new => $old) {
309:             if (isset($config['nette'][$old])) {
310:                 $new = is_int($new) ? $old : $new;
311:                 if (isset($config[$new])) {
312:                     throw new Nette\DeprecatedException("You can use (deprecated) section 'nette.$old' or new section '$new', but not both of them.");
313:                 }
314:                 $config[$new] = $config['nette'][$old];
315:                 unset($config['nette'][$old]);
316:             }
317:         }
318:         if (isset($config['nette']['xhtml'])) {
319:             trigger_error("Configuration option 'nette.xhtml' is deprecated, use section 'latte.xhtml' instead.", E_USER_DEPRECATED);
320:             $config['latte']['xhtml'] = $config['nette']['xhtml'];
321:             unset($config['nette']['xhtml']);
322:         }
323: 
324:         if (empty($config['nette'])) {
325:             unset($config['nette']);
326:         }
327:         return $config;
328:     }
329: 
330: 
331:     /********************* tools ****************d*g**/
332: 
333: 
334:     /**
335:      * Detects debug mode by IP address.
336:      * @param  string|array  IP addresses or computer names whitelist detection
337:      * @return bool
338:      */
339:     public static function detectDebugMode($list = NULL)
340:     {
341:         $addr = isset($_SERVER['REMOTE_ADDR'])
342:             ? $_SERVER['REMOTE_ADDR']
343:             : php_uname('n');
344:         $secret = isset($_COOKIE[self::COOKIE_SECRET]) && is_string($_COOKIE[self::COOKIE_SECRET])
345:             ? $_COOKIE[self::COOKIE_SECRET]
346:             : NULL;
347:         $list = is_string($list)
348:             ? preg_split('#[,\s]+#', $list)
349:             : (array) $list;
350:         if (!isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
351:             $list[] = '127.0.0.1';
352:             $list[] = '::1';
353:         }
354:         return in_array($addr, $list, TRUE) || in_array("$secret@$addr", $list, TRUE);
355:     }
356: 
357: }
358: 
Nette 2.3-20161221 API API documentation generated by ApiGen 2.8.0