Packages

  • Nette
    • Application
      • Diagnostics
      • Responses
      • Routers
      • UI
    • Caching
      • Storages
    • ComponentModel
    • Config
      • Adapters
      • Extensions
    • Database
      • Diagnostics
      • Drivers
      • Reflection
      • Table
    • DI
      • Diagnostics
    • Diagnostics
    • Forms
      • Controls
      • Rendering
    • Http
    • Iterators
    • Latte
      • Macros
    • Loaders
    • Localization
    • Mail
    • Reflection
    • Security
      • Diagnostics
    • Templating
    • Utils
      • PhpGenerator
  • NetteModule
  • none

Classes

  • Overview
  • Package
  • Class
  • Tree
  • Deprecated
  • Other releases
  • Nette homepage
  1: <?php
  2: 
  3: /**
  4:  * This file is part of the Nette Framework (https://nette.org)
  5:  * Copyright (c) 2004 David Grudl (http://davidgrudl.com)
  6:  * @package Nette\Config\Extensions
  7:  */
  8: 
  9: 
 10: 
 11: /**
 12:  * Core Nette Framework services.
 13:  *
 14:  * @author     David Grudl
 15:  * @package Nette\Config\Extensions
 16:  */
 17: class NetteExtension extends ConfigCompilerExtension
 18: {
 19:     public $defaults = array(
 20:         'xhtml' => TRUE,
 21:         'session' => array(
 22:             'iAmUsingBadHost' => NULL,
 23:             'autoStart' => 'smart',  // true|false|smart
 24:             'expiration' => NULL,
 25:         ),
 26:         'application' => array(
 27:             'debugger' => TRUE,
 28:             'errorPresenter' => NULL,
 29:             'catchExceptions' => '%productionMode%',
 30:         ),
 31:         'routing' => array(
 32:             'debugger' => TRUE,
 33:             'routes' => array(), // of [mask => action]
 34:         ),
 35:         'security' => array(
 36:             'debugger' => TRUE,
 37:             'frames' => 'SAMEORIGIN', // X-Frame-Options
 38:             'users' => array(), // of [user => password]
 39:             'roles' => array(), // of [role => parents]
 40:             'resources' => array(), // of [resource => parents]
 41:         ),
 42:         'mailer' => array(
 43:             'smtp' => FALSE,
 44:         ),
 45:         'database' => array(), // of [name => dsn, user, password, debugger, explain, autowired, reflection]
 46:         'forms' => array(
 47:             'messages' => array(),
 48:         ),
 49:         'container' => array(
 50:             'debugger' => FALSE,
 51:         ),
 52:         'debugger' => array(
 53:             'email' => NULL,
 54:             'editor' => NULL,
 55:             'browser' => NULL,
 56:             'strictMode' => NULL,
 57:             'bar' => array(), // of class name
 58:             'blueScreen' => array(), // of callback
 59:         ),
 60:     );
 61: 
 62:     public $databaseDefaults = array(
 63:         'dsn' => NULL,
 64:         'user' => NULL,
 65:         'password' => NULL,
 66:         'options' => NULL,
 67:         'debugger' => TRUE,
 68:         'explain' => TRUE,
 69:         'reflection' => 'DiscoveredReflection',
 70:     );
 71: 
 72: 
 73:     public function loadConfiguration()
 74:     {
 75:         $container = $this->getContainerBuilder();
 76:         $config = $this->getConfig($this->defaults);
 77: 
 78: 
 79:         // cache
 80:         $container->addDefinition($this->prefix('cacheJournal'))
 81:             ->setClass('FileJournal', array('%tempDir%'));
 82: 
 83:         $container->addDefinition('cacheStorage') // no namespace for back compatibility
 84:             ->setClass('FileStorage', array('%tempDir%/cache'));
 85: 
 86:         $container->addDefinition($this->prefix('templateCacheStorage'))
 87:             ->setClass('PhpFileStorage', array('%tempDir%/cache'))
 88:             ->setAutowired(FALSE);
 89: 
 90:         $container->addDefinition($this->prefix('cache'))
 91:             ->setClass('Cache', array(1 => '%namespace%'))
 92:             ->setParameters(array('namespace' => NULL));
 93: 
 94: 
 95:         // http
 96:         $container->addDefinition($this->prefix('httpRequestFactory'))
 97:             ->setClass('HttpRequestFactory')
 98:             ->addSetup('setEncoding', array('UTF-8'))
 99:             ->setInternal(TRUE);
100: 
101:         $container->addDefinition('httpRequest') // no namespace for back compatibility
102:             ->setClass('HttpRequest')
103:             ->setFactory('@\HttpRequestFactory::createHttpRequest');
104: 
105:         $container->addDefinition('httpResponse') // no namespace for back compatibility
106:             ->setClass('HttpResponse');
107: 
108:         $container->addDefinition($this->prefix('httpContext'))
109:             ->setClass('HttpContext');
110: 
111: 
112:         // session
113:         $session = $container->addDefinition('session') // no namespace for back compatibility
114:             ->setClass('Session');
115: 
116:         if (isset($config['session']['expiration'])) {
117:             $session->addSetup('setExpiration', array($config['session']['expiration']));
118:         }
119:         if (isset($config['session']['iAmUsingBadHost'])) {
120:             $session->addSetup('Framework::$iAmUsingBadHost = ?;', array((bool) $config['session']['iAmUsingBadHost']));
121:         }
122:         unset($config['session']['expiration'], $config['session']['autoStart'], $config['session']['iAmUsingBadHost']);
123:         if (!empty($config['session'])) {
124:             $session->addSetup('setOptions', array($config['session']));
125:         }
126: 
127: 
128:         // security
129:         $container->addDefinition($this->prefix('userStorage'))
130:             ->setClass('UserStorage');
131: 
132:         $user = $container->addDefinition('user') // no namespace for back compatibility
133:             ->setClass('User');
134: 
135:         if (!$container->parameters['productionMode'] && $config['security']['debugger']) {
136:             $user->addSetup('Debugger::$bar->addPanel(?)', array(
137:                 new DIStatement('UserPanel')
138:             ));
139:         }
140: 
141:         if ($config['security']['users']) {
142:             $container->addDefinition($this->prefix('authenticator'))
143:                 ->setClass('SimpleAuthenticator', array($config['security']['users']));
144:         }
145: 
146:         if ($config['security']['roles'] || $config['security']['resources']) {
147:             $authorizator = $container->addDefinition($this->prefix('authorizator'))
148:                 ->setClass('Permission');
149:             foreach ($config['security']['roles'] as $role => $parents) {
150:                 $authorizator->addSetup('addRole', array($role, $parents));
151:             }
152:             foreach ($config['security']['resources'] as $resource => $parents) {
153:                 $authorizator->addSetup('addResource', array($resource, $parents));
154:             }
155:         }
156: 
157: 
158:         // application
159:         $application = $container->addDefinition('application') // no namespace for back compatibility
160:             ->setClass('Application')
161:             ->addSetup('$catchExceptions', $config['application']['catchExceptions'])
162:             ->addSetup('$errorPresenter', $config['application']['errorPresenter']);
163: 
164:         if ($config['application']['debugger']) {
165:             $application->addSetup('RoutingDebugger::initializePanel');
166:         }
167: 
168:         $container->addDefinition($this->prefix('presenterFactory'))
169:             ->setClass('PresenterFactory', array(
170:                 isset($container->parameters['appDir']) ? $container->parameters['appDir'] : NULL
171:             ));
172: 
173: 
174:         // routing
175:         $router = $container->addDefinition('router') // no namespace for back compatibility
176:             ->setClass('RouteList');
177: 
178:         foreach ($config['routing']['routes'] as $mask => $action) {
179:             $router->addSetup('$service[] = new Route(?, ?);', array($mask, $action));
180:         }
181: 
182:         if (!$container->parameters['productionMode'] && $config['routing']['debugger']) {
183:             $application->addSetup('Debugger::$bar->addPanel(?)', array(
184:                 new DIStatement('RoutingDebugger')
185:             ));
186:         }
187: 
188: 
189:         // mailer
190:         if (empty($config['mailer']['smtp'])) {
191:             $container->addDefinition($this->prefix('mailer'))
192:                 ->setClass('SendmailMailer');
193:         } else {
194:             $container->addDefinition($this->prefix('mailer'))
195:                 ->setClass('SmtpMailer', array($config['mailer']));
196:         }
197: 
198:         $container->addDefinition($this->prefix('mail'))
199:             ->setClass('Mail')
200:             ->addSetup('setMailer')
201:             ->setShared(FALSE);
202: 
203: 
204:         // forms
205:         $container->addDefinition($this->prefix('basicForm'))
206:             ->setClass('Form')
207:             ->setShared(FALSE);
208: 
209: 
210:         // templating
211:         $latte = $container->addDefinition($this->prefix('latte'))
212:             ->setClass('LatteFilter')
213:             ->setShared(FALSE);
214: 
215:         if (empty($config['xhtml'])) {
216:             $latte->addSetup('$service->getCompiler()->defaultContentType = ?', LatteCompiler::CONTENT_HTML);
217:         }
218: 
219:         $container->addDefinition($this->prefix('template'))
220:             ->setClass('FileTemplate')
221:             ->addSetup('registerFilter', array($latte))
222:             ->addSetup('registerHelperLoader', array('TemplateHelpers::loader'))
223:             ->setShared(FALSE);
224: 
225: 
226:         // database
227:         $container->addDefinition($this->prefix('database'))
228:                 ->setClass('DINestedAccessor', array('@container', $this->prefix('database')));
229: 
230:         if (isset($config['database']['dsn'])) {
231:             $config['database'] = array('default' => $config['database']);
232:         }
233: 
234:         $autowired = TRUE;
235:         foreach ((array) $config['database'] as $name => $info) {
236:             if (!is_array($info)) {
237:                 continue;
238:             }
239:             $info += $this->databaseDefaults + array('autowired' => $autowired);
240:             $autowired = FALSE;
241: 
242:             foreach ((array) $info['options'] as $key => $value) {
243:                 if (preg_match('#^PDO::\w+\z#', $key)) {
244:                     unset($info['options'][$key]);
245:                     $info['options'][constant($key)] = $value;
246:                 }
247:             }
248: 
249:             $connection = $container->addDefinition($this->prefix("database.$name"))
250:                 ->setClass('Connection', array($info['dsn'], $info['user'], $info['password'], $info['options']))
251:                 ->setAutowired($info['autowired'])
252:                 ->addSetup('setCacheStorage')
253:                 ->addSetup('Debugger::$blueScreen->addPanel(?)', array(
254:                     'DatabasePanel::renderException'
255:                 ));
256: 
257:             if ($info['reflection']) {
258:                 $connection->addSetup('setDatabaseReflection', is_string($info['reflection'])
259:                     ? array(new DIStatement(preg_match('#^[a-z]+\z#', $info['reflection']) ? 'Nette\Database\Reflection\\' . ucfirst($info['reflection']) . 'Reflection' : $info['reflection']))
260:                     : ConfigCompiler::filterArguments(array($info['reflection']))
261:                 );
262:             }
263: 
264:             if (!$container->parameters['productionMode'] && $info['debugger']) {
265:                 $panel = $container->addDefinition($this->prefix("database.{$name}ConnectionPanel"))
266:                     ->setClass('DatabasePanel')
267:                     ->setAutowired(FALSE)
268:                     ->addSetup('$explain', !empty($info['explain']))
269:                     ->addSetup('$name', $name)
270:                     ->addSetup('Debugger::$bar->addPanel(?)', array('@self'));
271: 
272:                 $connection->addSetup('$service->onQuery[] = ?', array(array($panel, 'logQuery')));
273:             }
274:         }
275:     }
276: 
277: 
278:     public function afterCompile(PhpClassType $class)
279:     {
280:         $initialize = $class->methods['initialize'];
281:         $container = $this->getContainerBuilder();
282:         $config = $this->getConfig($this->defaults);
283: 
284:         // debugger
285:         foreach (array('email', 'editor', 'browser', 'strictMode', 'maxLen', 'maxDepth') as $key) {
286:             if (isset($config['debugger'][$key])) {
287:                 $initialize->addBody('Debugger::$? = ?;', array($key, $config['debugger'][$key]));
288:             }
289:         }
290: 
291:         if (!$container->parameters['productionMode']) {
292:             if ($config['container']['debugger']) {
293:                 $config['debugger']['bar'][] = 'ContainerPanel';
294:             }
295: 
296:             foreach ((array) $config['debugger']['bar'] as $item) {
297:                 $initialize->addBody($container->formatPhp(
298:                     'Debugger::$bar->addPanel(?);',
299:                     ConfigCompiler::filterArguments(array(is_string($item) ? new DIStatement($item) : $item))
300:                 ));
301:             }
302:         }
303: 
304:         foreach ((array) $config['debugger']['blueScreen'] as $item) {
305:             $initialize->addBody($container->formatPhp(
306:                 'Debugger::$blueScreen->addPanel(?);',
307:                 ConfigCompiler::filterArguments(array($item))
308:             ));
309:         }
310: 
311:         if (!empty($container->parameters['tempDir'])) {
312:             $initialize->addBody($this->checkTempDir($container->expand('%tempDir%/cache')));
313:         }
314: 
315:         foreach ((array) $config['forms']['messages'] as $name => $text) {
316:             $initialize->addBody('Rules::$defaultMessages[Form::?] = ?;', array($name, $text));
317:         }
318: 
319:         if ($config['session']['autoStart'] === 'smart') {
320:             $initialize->addBody('$this->getService("session")->exists() && $this->getService("session")->start();');
321:         } elseif ($config['session']['autoStart']) {
322:             $initialize->addBody('$this->getService("session")->start();');
323:         }
324: 
325:         if (empty($config['xhtml'])) {
326:             $initialize->addBody('Html::$xhtml = ?;', array((bool) $config['xhtml']));
327:         }
328: 
329:         if (isset($config['security']['frames']) && $config['security']['frames'] !== TRUE) {
330:             $frames = $config['security']['frames'];
331:             if ($frames === FALSE) {
332:                 $frames = 'DENY';
333:             } elseif (preg_match('#^https?:#', $frames)) {
334:                 $frames = "ALLOW-FROM $frames";
335:             }
336:             $initialize->addBody('header(?);', array("X-Frame-Options: $frames"));
337:         }
338: 
339:         foreach ($container->findByTag('run') as $name => $on) {
340:             if ($on) {
341:                 $initialize->addBody('$this->getService(?);', array($name));
342:             }
343:         }
344:     }
345: 
346: 
347:     private function checkTempDir($dir)
348:     {
349:         // checks whether directory is writable
350:         $uniq = uniqid('_', TRUE);
351:         if (!@mkdir("$dir/$uniq", 0777)) { // @ - is escalated to exception
352:             throw new InvalidStateException("Unable to write to directory '$dir'. Make this directory writable.");
353:         }
354: 
355:         // tests subdirectory mode
356:         $useDirs = @file_put_contents("$dir/$uniq/_", '') !== FALSE; // @ - error is expected
357:         @unlink("$dir/$uniq/_");
358:         @rmdir("$dir/$uniq"); // @ - directory may not already exist
359: 
360:         return 'FileStorage::$useDirectories = ' . ($useDirs ? 'TRUE' : 'FALSE') . ";\n";
361:     }
362: 
363: }
364: 
Nette Framework 2.0.18 (for PHP 5.2, un-prefixed) API documentation generated by ApiGen 2.8.0