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