1: <?php
2:
3: 4: 5: 6: 7: 8: 9: 10: 11:
12:
13:
14:
15: 16: 17: 18: 19: 20: 21: 22: 23:
24: class NConfigurator extends NObject
25: {
26:
27: const DEVELOPMENT = 'development',
28: PRODUCTION = 'production',
29: AUTO = NULL,
30: NONE = FALSE;
31:
32:
33: public $onCompile;
34:
35:
36: protected $parameters;
37:
38:
39: protected $files = array();
40:
41:
42:
43: public function __construct()
44: {
45: $this->parameters = $this->getDefaultParameters();
46: }
47:
48:
49:
50: 51: 52: 53: 54:
55: public function setProductionMode($value = TRUE)
56: {
57: $this->parameters['productionMode'] = is_bool($value) ? $value : self::detectProductionMode($value);
58: return $this;
59: }
60:
61:
62:
63: 64: 65:
66: public function isProductionMode()
67: {
68: return $this->parameters['productionMode'];
69: }
70:
71:
72:
73: 74: 75: 76:
77: public function setTempDirectory($path)
78: {
79: $this->parameters['tempDir'] = $path;
80: if (($cacheDir = $this->getCacheDirectory()) && !is_dir($cacheDir)) {
81: mkdir($cacheDir, 0777);
82: }
83: return $this;
84: }
85:
86:
87:
88: 89: 90: 91:
92: public function addParameters(array $params)
93: {
94: $this->parameters = NConfigHelpers::merge($params, $this->parameters);
95: return $this;
96: }
97:
98:
99:
100: 101: 102:
103: protected function getDefaultParameters()
104: {
105: $trace = PHP_VERSION_ID < 50205 ? debug_backtrace() :debug_backtrace(FALSE);
106: return array(
107: 'appDir' => isset($trace[1]['file']) ? dirname($trace[1]['file']) : NULL,
108: 'wwwDir' => isset($_SERVER['SCRIPT_FILENAME']) ? dirname($_SERVER['SCRIPT_FILENAME']) : NULL,
109: 'productionMode' => self::detectProductionMode(),
110: 'environment' => self::detectProductionMode() ? self::PRODUCTION : self::DEVELOPMENT,
111: 'consoleMode' => PHP_SAPI === 'cli',
112: 'container' => array(
113: 'class' => 'SystemContainer',
114: 'parent' => 'NDIContainer',
115: )
116: );
117: }
118:
119:
120:
121: 122: 123: 124: 125:
126: public function enableDebugger($logDirectory = NULL, $email = NULL)
127: {
128: NDebugger::$strictMode = TRUE;
129: NDebugger::enable($this->parameters['productionMode'], $logDirectory, $email);
130: }
131:
132:
133:
134: 135: 136:
137: public function createRobotLoader()
138: {
139: if (!($cacheDir = $this->getCacheDirectory())) {
140: throw new InvalidStateException("Set path to temporary directory using setTempDirectory().");
141: }
142: $loader = new NRobotLoader;
143: $loader->setCacheStorage(new NFileStorage($cacheDir));
144: $loader->autoRebuild = !$this->parameters['productionMode'];
145: return $loader;
146: }
147:
148:
149:
150: 151: 152: 153:
154: public function addConfig($file, $section = self::AUTO)
155: {
156: $this->files[] = array($file, $section === self::AUTO ? $this->parameters['environment'] : $section);
157: return $this;
158: }
159:
160:
161:
162:
163: public function loadConfig($file, $section = NULL)
164: {
165: trigger_error(__METHOD__ . '() is deprecated; use addConfig(file, [section])->createContainer() instead.', E_USER_WARNING);
166: return $this->addConfig($file, $section)->createContainer();
167: }
168:
169:
170:
171: 172: 173: 174:
175: public function createContainer()
176: {
177: if ($cacheDir = $this->getCacheDirectory()) {
178: $cache = new NCache(new NPhpFileStorage($cacheDir), 'Nette.Configurator');
179: $cacheKey = array($this->parameters, $this->files);
180: $cached = $cache->load($cacheKey);
181: if (!$cached) {
182: $code = $this->buildContainer($dependencies);
183: $cache->save($cacheKey, $code, array(
184: NCache::FILES => $this->parameters['productionMode'] ? NULL : $dependencies,
185: ));
186: $cached = $cache->load($cacheKey);
187: }
188: NLimitedScope::load($cached['file'], TRUE);
189:
190: } elseif ($this->files) {
191: throw new InvalidStateException("Set path to temporary directory using setTempDirectory().");
192:
193: } else {
194: NLimitedScope::evaluate($this->buildContainer());
195: }
196:
197: $container = new $this->parameters['container']['class'];
198: $container->initialize();
199: NEnvironment::setContext($container);
200: return $container;
201: }
202:
203:
204:
205: 206: 207: 208:
209: protected function buildContainer(& $dependencies = NULL)
210: {
211: $loader = $this->createLoader();
212: $config = array();
213: $code = "<?php\n";
214: foreach ($this->files as $tmp) {
215: list($file, $section) = $tmp;
216: $config = NConfigHelpers::merge($loader->load($file, $section), $config);
217: $code .= "// source: $file $section\n";
218: }
219: $code .= "\n";
220:
221: $this->checkCompatibility($config);
222:
223: if (!isset($config['parameters'])) {
224: $config['parameters'] = array();
225: }
226: $config['parameters'] = NConfigHelpers::merge($config['parameters'], $this->parameters);
227:
228: $compiler = $this->createCompiler();
229: $this->onCompile($this, $compiler);
230:
231: $code .= $compiler->compile(
232: $config,
233: $this->parameters['container']['class'],
234: $config['parameters']['container']['parent']
235: );
236: $dependencies = array_merge($loader->getDependencies(), $compiler->getContainerBuilder()->getDependencies());
237: return $code;
238: }
239:
240:
241:
242: protected function checkCompatibility(array $config)
243: {
244: foreach (array('service' => 'services', 'variable' => 'parameters', 'variables' => 'parameters', 'mode' => 'parameters', 'const' => 'constants') as $old => $new) {
245: if (isset($config[$old])) {
246: throw new DeprecatedException("Section '$old' in configuration file is deprecated; use '$new' instead.");
247: }
248: }
249: if (isset($config['services'])) {
250: foreach ($config['services'] as $key => $def) {
251: foreach (array('option' => 'arguments', 'methods' => 'setup') as $old => $new) {
252: if (is_array($def) && isset($def[$old])) {
253: throw new DeprecatedException("Section '$old' in service definition is deprecated; refactor it into '$new'.");
254: }
255: }
256: }
257: }
258: }
259:
260:
261:
262: 263: 264:
265: protected function createCompiler()
266: {
267: $compiler = new NConfigCompiler;
268: $compiler->addExtension('php', new NPhpExtension)
269: ->addExtension('constants', new NConstantsExtension)
270: ->addExtension('nette', new NNetteExtension);
271: return $compiler;
272: }
273:
274:
275:
276: 277: 278:
279: protected function createLoader()
280: {
281: return new NConfigLoader;
282: }
283:
284:
285:
286: protected function getCacheDirectory()
287: {
288: return empty($this->parameters['tempDir']) ? NULL : $this->parameters['tempDir'] . '/cache';
289: }
290:
291:
292:
293:
294:
295:
296:
297: 298: 299: 300: 301:
302: public static function detectProductionMode($list = NULL)
303: {
304: $list = is_string($list) ? preg_split('#[,\s]+#', $list) : $list;
305: $list[] = '127.0.0.1';
306: $list[] = '::1';
307: return !in_array(isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : php_uname('n'), $list, TRUE);
308: }
309:
310: }
311: