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: ) {
86: return TRUE;
87: }
88: }
89: return FALSE;
90:
91: } else {
92: return TRUE;
93: }
94:
95: case 'console':
96: return PHP_SAPI === 'cli';
97:
98: default:
99: 100: return NULL;
101: }
102: }
103:
104:
105:
106: 107: 108: 109: 110:
111: public function loadConfig($file)
112: {
113: $name = Environment::getName();
114:
115: if ($file instanceof Config) {
116: $config = $file;
117: $file = NULL;
118:
119: } else {
120: if ($file === NULL) {
121: $file = $this->defaultConfigFile;
122: }
123: $file = Environment::expand($file);
124: if (!is_file($file)) {
125: $file = preg_replace('#\.neon$#', '.ini', $file); 126: }
127: $config = Config::fromFile($file, $name);
128: }
129:
130: 131: if ($config->variable instanceof Config) {
132: foreach ($config->variable as $key => $value) {
133: Environment::setVariable($key, $value);
134: }
135: }
136:
137: 138: $iterator = new \RecursiveIteratorIterator($config);
139: foreach ($iterator as $key => $value) {
140: $tmp = $iterator->getDepth() ? $iterator->getSubIterator($iterator->getDepth() - 1)->current() : $config;
141: $tmp[$key] = Environment::expand($value);
142: }
143:
144: 145: $runServices = array();
146: $context = Environment::getContext();
147: if ($config->service instanceof Config) {
148: foreach ($config->service as $key => $value) {
149: $key = strtr($key, '-', '\\'); 150: if (is_string($value)) {
151: $context->removeService($key);
152: $context->addService($key, $value);
153: } else {
154: if ($value->factory || isset($this->defaultServices[$key])) {
155: $context->removeService($key);
156: $context->addService(
157: $key,
158: $value->factory ? $value->factory : $this->defaultServices[$key],
159: isset($value->singleton) ? $value->singleton : TRUE,
160: (array) $value->option
161: );
162: } else {
163: throw new \InvalidStateException("Factory method is not specified for service $key.");
164: }
165: if ($value->run) {
166: $runServices[] = $key;
167: }
168: }
169: }
170: }
171:
172: 173: if (!$config->php) { 174: $config->php = $config->set;
175: unset($config->set);
176: }
177:
178: if ($config->php instanceof Config) {
179: if (PATH_SEPARATOR !== ';' && isset($config->php->include_path)) {
180: $config->php->include_path = str_replace(';', PATH_SEPARATOR, $config->php->include_path);
181: }
182:
183: foreach (clone $config->php as $key => $value) { 184: if ($value instanceof Config) {
185: unset($config->php->$key);
186: foreach ($value as $k => $v) {
187: $config->php->{"$key.$k"} = $v;
188: }
189: }
190: }
191:
192: foreach ($config->php as $key => $value) {
193: $key = strtr($key, '-', '.'); 194:
195: if (!is_scalar($value)) {
196: throw new \InvalidStateException("Configuration value for directive '$key' is not scalar.");
197: }
198:
199: if ($key === 'date.timezone') { 200: date_default_timezone_set($value);
201: }
202:
203: if (function_exists('ini_set')) {
204: ini_set($key, $value);
205: } else {
206: switch ($key) {
207: case 'include_path':
208: set_include_path($value);
209: break;
210: case 'iconv.internal_encoding':
211: iconv_set_encoding('internal_encoding', $value);
212: break;
213: case 'mbstring.internal_encoding':
214: mb_internal_encoding($value);
215: break;
216: case 'date.timezone':
217: date_default_timezone_set($value);
218: break;
219: case 'error_reporting':
220: error_reporting($value);
221: break;
222: case 'ignore_user_abort':
223: ignore_user_abort($value);
224: break;
225: case 'max_execution_time':
226: set_time_limit($value);
227: break;
228: default:
229: if (ini_get($key) != $value) { 230: throw new \NotSupportedException('Required function ini_set() is disabled.');
231: }
232: }
233: }
234: }
235: }
236:
237: 238: if ($config->const instanceof Config) {
239: foreach ($config->const as $key => $value) {
240: define($key, $value);
241: }
242: }
243:
244: 245: if (isset($config->mode)) {
246: foreach ($config->mode as $mode => $state) {
247: Environment::setMode($mode, $state);
248: }
249: }
250:
251: 252: foreach ($runServices as $name) {
253: $context->getService($name);
254: }
255:
256: return $config;
257: }
258:
259:
260:
261:
262:
263:
264:
265: 266: 267: 268:
269: public function createContext()
270: {
271: $context = new Context;
272: foreach ($this->defaultServices as $name => $service) {
273: $context->addService($name, $service);
274: }
275: return $context;
276: }
277:
278:
279:
280: 281: 282:
283: public static function createApplication(array $options = NULL)
284: {
285: if (Environment::getVariable('baseUri', NULL) === NULL) {
286: Environment::setVariable('baseUri', Environment::getHttpRequest()->getUri()->getBaseUri());
287: }
288:
289: $context = clone Environment::getContext();
290: $context->addService('Nette\\Application\\IRouter', 'Nette\Application\MultiRouter');
291:
292: if (!$context->hasService('Nette\\Application\\IPresenterFactory')) {
293: $context->addService('Nette\\Application\\IPresenterFactory', function() use ($context) {
294: return new Nette\Application\PresenterFactory(Environment::getVariable('appDir'), $context);
295: });
296: }
297:
298: $class = isset($options['class']) ? $options['class'] : 'Nette\Application\Application';
299: $application = new $class;
300: $application->setContext($context);
301: $application->catchExceptions = Environment::isProduction();
302: return $application;
303: }
304:
305:
306:
307: 308: 309:
310: public static function createHttpRequest()
311: {
312: $factory = new Nette\Web\HttpRequestFactory;
313: $factory->setEncoding('UTF-8');
314: return $factory->createHttpRequest();
315: }
316:
317:
318:
319: 320: 321:
322: public static function createCacheStorage()
323: {
324: $dir = Environment::getVariable('tempDir') . '/cache';
325: umask(0000);
326: @mkdir($dir, 0777); 327: return new Nette\Caching\FileStorage($dir, Environment::getService('Nette\\Caching\\ICacheJournal'));
328: }
329:
330:
331:
332: 333: 334:
335: public static function createCacheJournal()
336: {
337: return new Nette\Caching\FileJournal(Environment::getVariable('tempDir'));
338: }
339:
340:
341:
342: 343: 344:
345: public static function createMailer(array $options = NULL)
346: {
347: if (empty($options['smtp'])) {
348: return new Nette\Mail\SendmailMailer;
349: } else {
350: return new Nette\Mail\SmtpMailer($options);
351: }
352: }
353:
354:
355:
356: 357: 358:
359: public static function createRobotLoader(array $options = NULL)
360: {
361: $loader = new Nette\Loaders\RobotLoader;
362: $loader->autoRebuild = isset($options['autoRebuild']) ? $options['autoRebuild'] : !Environment::isProduction();
363: $loader->setCacheStorage(Environment::getService('Nette\\Caching\\ICacheStorage'));
364: if (isset($options['directory'])) {
365: $loader->addDirectory($options['directory']);
366: } else {
367: foreach (array('appDir', 'libsDir') as $var) {
368: if ($dir = Environment::getVariable($var, NULL)) {
369: $loader->addDirectory($dir);
370: }
371: }
372: }
373: $loader->register();
374: return $loader;
375: }
376:
377: }
378: