Namespaces

  • 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

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