1: <?php
2:
3: 4: 5: 6:
7:
8: namespace Nette;
9:
10: use Nette;
11: use Nette\DI;
12: use Tracy;
13:
14:
15: 16: 17: 18: 19: 20: 21: 22:
23: class Configurator extends Object
24: {
25: const AUTO = TRUE;
26:
27:
28: const DEVELOPMENT = 'development',
29: PRODUCTION = 'production',
30: NONE = FALSE;
31:
32: const COOKIE_SECRET = 'nette-debug';
33:
34:
35: public $onCompile;
36:
37:
38: public $defaultExtensions = array(
39: 'php' => 'Nette\DI\Extensions\PhpExtension',
40: 'constants' => 'Nette\DI\Extensions\ConstantsExtension',
41: 'nette' => 'Nette\Bridges\Framework\NetteExtension',
42: 'database' => 'Nette\Bridges\DatabaseDI\DatabaseExtension',
43: 'extensions' => 'Nette\DI\Extensions\ExtensionsExtension',
44: );
45:
46:
47: protected $parameters;
48:
49:
50: protected $files = array();
51:
52:
53: public function __construct()
54: {
55: $this->parameters = $this->getDefaultParameters();
56: }
57:
58:
59: 60: 61: 62: 63:
64: public function setDebugMode($value)
65: {
66: if (is_string($value) || is_array($value)) {
67: $value = static::detectDebugMode($value);
68: } elseif (!is_bool($value)) {
69: throw new Nette\InvalidArgumentException(sprintf('Value must be either a string, array, or boolean, %s given.', gettype($value)));
70: }
71: $this->parameters['debugMode'] = $value;
72: $this->parameters['productionMode'] = !$this->parameters['debugMode'];
73: return $this;
74: }
75:
76:
77: 78: 79:
80: public function isDebugMode()
81: {
82: return $this->parameters['debugMode'];
83: }
84:
85:
86: 87: 88: 89:
90: public function setTempDirectory($path)
91: {
92: $this->parameters['tempDir'] = $path;
93: return $this;
94: }
95:
96:
97: 98: 99: 100:
101: public function addParameters(array $params)
102: {
103: $this->parameters = DI\Config\Helpers::merge($params, $this->parameters);
104: return $this;
105: }
106:
107:
108: 109: 110:
111: protected function getDefaultParameters()
112: {
113: $trace = debug_backtrace(PHP_VERSION_ID >= 50306 ? DEBUG_BACKTRACE_IGNORE_ARGS : FALSE);
114: $debugMode = static::detectDebugMode();
115: return array(
116: 'appDir' => isset($trace[1]['file']) ? dirname($trace[1]['file']) : NULL,
117: 'wwwDir' => isset($_SERVER['SCRIPT_FILENAME'])
118: ? dirname(realpath($_SERVER['SCRIPT_FILENAME']))
119: : NULL,
120: 'debugMode' => $debugMode,
121: 'productionMode' => !$debugMode,
122: 'environment' => $debugMode ? 'development' : 'production',
123: 'consoleMode' => PHP_SAPI === 'cli',
124: 'container' => array(
125: 'class' => 'SystemContainer',
126: 'parent' => 'Nette\DI\Container',
127: ),
128: );
129: }
130:
131:
132: 133: 134: 135: 136:
137: public function enableDebugger($logDirectory = NULL, $email = NULL)
138: {
139: Tracy\Debugger::$strictMode = TRUE;
140: Tracy\Debugger::enable(!$this->parameters['debugMode'], $logDirectory, $email);
141: Nette\Bridges\Framework\TracyBridge::initialize();
142: }
143:
144:
145: 146: 147: 148:
149: public function createRobotLoader()
150: {
151: if (!class_exists('Nette\Loaders\RobotLoader')) {
152: throw new Nette\NotSupportedException('RobotLoader not found, do you have `nette/robot-loader` package installed?');
153: }
154:
155: $loader = new Nette\Loaders\RobotLoader;
156: $loader->setCacheStorage(new Nette\Caching\Storages\FileStorage($this->getCacheDirectory()));
157: $loader->autoRebuild = $this->parameters['debugMode'];
158: return $loader;
159: }
160:
161:
162: 163: 164: 165:
166: public function addConfig($file, $section = NULL)
167: {
168: if ($section === NULL && is_string($file) && $this->parameters['debugMode']) {
169: try {
170: $loader = new DI\Config\Loader;
171: $loader->load($file, $this->parameters['environment']);
172: trigger_error("Config file '$file' has sections, call addConfig() with second parameter Configurator::AUTO.", E_USER_WARNING);
173: $section = $this->parameters['environment'];
174: } catch (\Exception $e) {
175: }
176: }
177: $this->files[] = array($file, $section === self::AUTO ? $this->parameters['environment'] : $section);
178: return $this;
179: }
180:
181:
182: 183: 184: 185:
186: public function createContainer()
187: {
188: $container = $this->createContainerFactory()->create();
189: $container->initialize();
190: if (class_exists('Nette\Environment')) {
191: Nette\Environment::setContext($container);
192: }
193: return $container;
194: }
195:
196:
197: 198: 199:
200: protected function createContainerFactory()
201: {
202: $factory = new DI\ContainerFactory(NULL);
203: $factory->autoRebuild = $this->parameters['debugMode'] ? TRUE : 'compat';
204: $factory->class = $this->parameters['container']['class'];
205: $factory->config = array('parameters' => $this->parameters);
206: $factory->configFiles = $this->files;
207: $factory->tempDirectory = $this->getCacheDirectory() . '/Nette.Configurator';
208: if (!is_dir($factory->tempDirectory)) {
209: @mkdir($factory->tempDirectory);
210: }
211:
212: $me = $this;
213: $factory->onCompile[] = function (DI\ContainerFactory $factory, DI\Compiler $compiler, $config) use ($me) {
214: foreach ($me->defaultExtensions as $name => $class) {
215: if (class_exists($class)) {
216: $compiler->addExtension($name, new $class);
217: }
218: }
219: $factory->parentClass = $config['parameters']['container']['parent'];
220: $me->onCompile($me, $compiler);
221: };
222: return $factory;
223: }
224:
225:
226: protected function getCacheDirectory()
227: {
228: if (empty($this->parameters['tempDir'])) {
229: throw new Nette\InvalidStateException('Set path to temporary directory using setTempDirectory().');
230: }
231: $dir = $this->parameters['tempDir'] . '/cache';
232: if (!is_dir($dir)) {
233: @mkdir($dir);
234: }
235: return $dir;
236: }
237:
238:
239:
240:
241:
242: 243: 244: 245: 246:
247: public static function detectDebugMode($list = NULL)
248: {
249: $addr = isset($_SERVER['REMOTE_ADDR'])
250: ? $_SERVER['REMOTE_ADDR']
251: : php_uname('n');
252: $secret = isset($_COOKIE[self::COOKIE_SECRET]) && is_string($_COOKIE[self::COOKIE_SECRET])
253: ? $_COOKIE[self::COOKIE_SECRET]
254: : NULL;
255: $list = is_string($list)
256: ? preg_split('#[,\s]+#', $list)
257: : (array) $list;
258: if (!isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
259: $list[] = '127.0.0.1';
260: $list[] = '::1';
261: }
262: return in_array($addr, $list, TRUE) || in_array("$secret@$addr", $list, TRUE);
263: }
264:
265: }
266: