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
  • PHP

Classes

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