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

Classes

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