1: <?php
2:
3: 4: 5: 6: 7: 8: 9: 10:
11:
12: namespace Nette;
13:
14: use Nette,
15: Nette\Config\Config;
16:
17:
18:
19: 20: 21: 22: 23:
24: class Configurator extends Object
25: {
26:
27: public $defaultConfigFile = '%appDir%/config.neon';
28:
29:
30: public $defaultServices = array(
31: 'Nette\\Application\\Application' => array(__CLASS__, 'createApplication'),
32: 'Nette\\Web\\HttpContext' => 'Nette\Web\HttpContext',
33: 'Nette\\Web\\IHttpRequest' => array(__CLASS__, 'createHttpRequest'),
34: 'Nette\\Web\\IHttpResponse' => 'Nette\Web\HttpResponse',
35: 'Nette\\Web\\IUser' => 'Nette\Web\User',
36: 'Nette\\Caching\\ICacheStorage' => array(__CLASS__, 'createCacheStorage'),
37: 'Nette\\Caching\\ICacheJournal' => array(__CLASS__, 'createCacheJournal'),
38: 'Nette\\Mail\\IMailer' => array(__CLASS__, 'createMailer'),
39: 'Nette\\Web\\Session' => 'Nette\Web\Session',
40: 'Nette\\Loaders\\RobotLoader' => array(__CLASS__, 'createRobotLoader'),
41: );
42:
43:
44:
45: 46: 47: 48: 49:
50: public function detect($name)
51: {
52: switch ($name) {
53: case 'environment':
54: 55: if ($this->detect('console')) {
56: return Environment::CONSOLE;
57:
58: } else {
59: return Environment::getMode('production') ? Environment::PRODUCTION : Environment::DEVELOPMENT;
60: }
61:
62: case 'production':
63: 64: if (PHP_SAPI === 'cli') {
65: return FALSE;
66:
67: } elseif (isset($_SERVER['SERVER_ADDR']) || isset($_SERVER['LOCAL_ADDR'])) {
68: $addrs = array();
69: if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) { 70: $addrs = preg_split('#,\s*#', $_SERVER['HTTP_X_FORWARDED_FOR']);
71: }
72: if (isset($_SERVER['REMOTE_ADDR'])) {
73: $addrs[] = $_SERVER['REMOTE_ADDR'];
74: }
75: $addrs[] = isset($_SERVER['SERVER_ADDR']) ? $_SERVER['SERVER_ADDR'] : $_SERVER['LOCAL_ADDR'];
76: foreach ($addrs as $addr) {
77: $oct = explode('.', $addr);
78: 79: 80: 81: 82: 83: if ($addr !== '::1' && (count($oct) !== 4 || ($oct[0] !== '10' && $oct[0] !== '127' && ($oct[0] !== '172' || $oct[1] < 16 || $oct[1] > 31)
84: && ($oct[0] !== '169' || $oct[1] !== '254') && ($oct[0] !== '192' || $oct[1] !== '168')))) {
85: return TRUE;
86: }
87: }
88: return FALSE;
89:
90: } else {
91: return TRUE;
92: }
93:
94: case 'console':
95: return PHP_SAPI === 'cli';
96:
97: default:
98: 99: return NULL;
100: }
101: }
102:
103:
104:
105: 106: 107: 108: 109:
110: public function loadConfig($file)
111: {
112: $name = Environment::getName();
113:
114: if ($file instanceof Config) {
115: $config = $file;
116: $file = NULL;
117:
118: } else {
119: if ($file === NULL) {
120: $file = $this->defaultConfigFile;
121: }
122: $file = Environment::expand($file);
123: if (!is_file($file)) {
124: $file = preg_replace('#\.neon$#', '.ini', $file); 125: }
126: $config = Config::fromFile($file, $name);
127: }
128:
129: 130: if ($config->variable instanceof Config) {
131: foreach ($config->variable as $key => $value) {
132: Environment::setVariable($key, $value);
133: }
134: }
135:
136: 137: $iterator = new \RecursiveIteratorIterator($config);
138: foreach ($iterator as $key => $value) {
139: $tmp = $iterator->getDepth() ? $iterator->getSubIterator($iterator->getDepth() - 1)->current() : $config;
140: $tmp[$key] = Environment::expand($value);
141: }
142:
143: 144: $runServices = array();
145: $context = Environment::getContext();
146: if ($config->service instanceof Config) {
147: foreach ($config->service as $key => $value) {
148: $key = strtr($key, '-', '\\'); 149: if (is_string($value)) {
150: $context->removeService($key);
151: $context->addService($key, $value);
152: } else {
153: $factory = $value->factory ? $value->factory : (isset($this->defaultServices[$key]) ? $this->defaultServices[$key] : NULL);
154: if ($factory) {
155: $context->removeService($key);
156: $context->addService($key, $factory, isset($value->singleton) ? $value->singleton : TRUE, (array) $value->option);
157: } else {
158: throw new \InvalidStateException("Factory method is not specified for service $key.");
159: }
160: if ($value->run) {
161: $runServices[] = $key;
162: }
163: }
164: }
165: }
166:
167: 168: if (!$config->php) { 169: $config->php = $config->set;
170: unset($config->set);
171: }
172:
173: if ($config->php instanceof Config) {
174: if (PATH_SEPARATOR !== ';' && isset($config->php->include_path)) {
175: $config->php->include_path = str_replace(';', PATH_SEPARATOR, $config->php->include_path);
176: }
177:
178: foreach (clone $config->php as $key => $value) { 179: if ($value instanceof Config) {
180: unset($config->php->$key);
181: foreach ($value as $k => $v) {
182: $config->php->{"$key.$k"} = $v;
183: }
184: }
185: }
186:
187: foreach ($config->php as $key => $value) {
188: $key = strtr($key, '-', '.'); 189:
190: if (!is_scalar($value)) {
191: throw new \InvalidStateException("Configuration value for directive '$key' is not scalar.");
192: }
193:
194: if ($key === 'date.timezone') { 195: date_default_timezone_set($value);
196: }
197:
198: if (function_exists('ini_set')) {
199: ini_set($key, $value);
200: } else {
201: switch ($key) {
202: case 'include_path':
203: set_include_path($value);
204: break;
205: case 'iconv.internal_encoding':
206: iconv_set_encoding('internal_encoding', $value);
207: break;
208: case 'mbstring.internal_encoding':
209: mb_internal_encoding($value);
210: break;
211: case 'date.timezone':
212: date_default_timezone_set($value);
213: break;
214: case 'error_reporting':
215: error_reporting($value);
216: break;
217: case 'ignore_user_abort':
218: ignore_user_abort($value);
219: break;
220: case 'max_execution_time':
221: set_time_limit($value);
222: break;
223: default:
224: if (ini_get($key) != $value) { 225: throw new \NotSupportedException('Required function ini_set() is disabled.');
226: }
227: }
228: }
229: }
230: }
231:
232: 233: if ($config->const instanceof Config) {
234: foreach ($config->const as $key => $value) {
235: define($key, $value);
236: }
237: }
238:
239: 240: if (isset($config->mode)) {
241: foreach($config->mode as $mode => $state) {
242: Environment::setMode($mode, $state);
243: }
244: }
245:
246: 247: foreach ($runServices as $name) {
248: $context->getService($name);
249: }
250:
251: return $config;
252: }
253:
254:
255:
256:
257:
258:
259:
260: 261: 262: 263:
264: public function createContext()
265: {
266: $context = new Context;
267: foreach ($this->defaultServices as $name => $service) {
268: $context->addService($name, $service);
269: }
270: return $context;
271: }
272:
273:
274:
275: 276: 277:
278: public static function createApplication(array $options = NULL)
279: {
280: if (Environment::getVariable('baseUri', NULL) === NULL) {
281: Environment::setVariable('baseUri', Environment::getHttpRequest()->getUri()->getBaseUri());
282: }
283:
284: $context = clone Environment::getContext();
285: $context->addService('Nette\\Application\\IRouter', 'Nette\Application\MultiRouter');
286:
287: if (!$context->hasService('Nette\\Application\\IPresenterFactory')) {
288: $context->addService('Nette\\Application\\IPresenterFactory', function() use ($context) {
289: return new Nette\Application\PresenterFactory(Environment::getVariable('appDir'), $context);
290: });
291: }
292:
293: $class = isset($options['class']) ? $options['class'] : 'Nette\Application\Application';
294: $application = new $class;
295: $application->setContext($context);
296: $application->catchExceptions = Environment::isProduction();
297: return $application;
298: }
299:
300:
301:
302: 303: 304:
305: public static function createHttpRequest()
306: {
307: $factory = new Nette\Web\HttpRequestFactory;
308: $factory->setEncoding('UTF-8');
309: return $factory->createHttpRequest();
310: }
311:
312:
313:
314: 315: 316:
317: public static function createCacheStorage()
318: {
319: $dir = Environment::getVariable('tempDir') . '/cache';
320: umask(0000);
321: @mkdir($dir, 0777); 322: return new Nette\Caching\FileStorage($dir, Environment::getService('Nette\\Caching\\ICacheJournal'));
323: }
324:
325:
326:
327: 328: 329:
330: public static function createCacheJournal()
331: {
332: return new Nette\Caching\FileJournal(Environment::getVariable('tempDir'));
333: }
334:
335:
336:
337: 338: 339:
340: public static function createMailer(array $options = NULL)
341: {
342: if (isset($options['smtp'])) {
343: return new Nette\Mail\SmtpMailer($options);
344: } else {
345: return new Nette\Mail\SendmailMailer;
346: }
347: }
348:
349:
350:
351: 352: 353:
354: public static function createRobotLoader(array $options = NULL)
355: {
356: $loader = new Nette\Loaders\RobotLoader;
357: $loader->autoRebuild = isset($options['autoRebuild']) ? $options['autoRebuild'] : !Environment::isProduction();
358: $loader->setCacheStorage(Environment::getService('Nette\\Caching\\ICacheStorage'));
359: if (isset($options['directory'])) {
360: $loader->addDirectory($options['directory']);
361: } else {
362: foreach (array('appDir', 'libsDir') as $var) {
363: if ($dir = Environment::getVariable($var, NULL)) {
364: $loader->addDirectory($dir);
365: }
366: }
367: }
368: $loader->register();
369: return $loader;
370: }
371:
372: }
373: