1: <?php
2:
3: 4: 5: 6: 7: 8: 9: 10:
11:
12: namespace Nette\Config\Extensions;
13:
14: use Nette,
15: Nette\DI\ContainerBuilder,
16: Nette\Utils\Validators;
17:
18:
19:
20: 21: 22: 23: 24:
25: class NetteExtension extends Nette\Config\CompilerExtension
26: {
27: public $defaults = array(
28: 'xhtml' => TRUE,
29: 'iAmUsingBadHost' => FALSE,
30: 'session' => array(
31: 'autoStart' => NULL,
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(),
42: ),
43: 'security' => array(
44: 'debugger' => TRUE,
45: 'users' => array(),
46: 'roles' => array(),
47: 'resources' => array(),
48: ),
49: 'mail' => array(
50: 'smtp' => FALSE,
51: ),
52: 'database' => array(),
53: 'forms' => array(
54: 'messages' => array(),
55: ),
56: );
57:
58: public $databaseDefaults = array(
59: 'dsn' => NULL,
60: 'user' => NULL,
61: 'password' => NULL,
62: 'options' => NULL,
63: 'debugger' => TRUE,
64: 'explain' => TRUE,
65: );
66:
67:
68:
69: public function loadConfiguration()
70: {
71: $container = $this->getContainerBuilder();
72: $config = $this->getConfig($this->defaults);
73:
74:
75:
76: $container->addDefinition('cacheJournal')
77: ->setClass('Nette\Caching\Storages\FileJournal', array('%tempDir%'));
78:
79: $container->addDefinition('cacheStorage')
80: ->setClass('Nette\Caching\Storages\FileStorage', array('%tempDir%/cache'));
81:
82: $container->addDefinition('templateCacheStorage')
83: ->setClass('Nette\Caching\Storages\PhpFileStorage', array('%tempDir%/cache'))
84: ->setAutowired(FALSE);
85:
86: $container->addDefinition($this->prefix('cache'))
87: ->setClass('Nette\Caching\Cache', array(1 => '%namespace%'))
88: ->setParameters(array('namespace' => NULL));
89:
90:
91:
92: $container->addDefinition('httpRequestFactory')
93: ->setClass('Nette\Http\RequestFactory')
94: ->addSetup('setEncoding', array('UTF-8'))
95: ->setInternal(TRUE)
96: ->setShared(FALSE);
97:
98: $container->addDefinition('httpRequest')
99: ->setClass('Nette\Http\Request')
100: ->setFactory('@Nette\Http\RequestFactory::createHttpRequest');
101:
102: $container->addDefinition('httpResponse')
103: ->setClass('Nette\Http\Response');
104:
105: $container->addDefinition('httpContext')
106: ->setClass('Nette\Http\Context');
107:
108: $session = $container->addDefinition('session')
109: ->setClass('Nette\Http\Session');
110:
111: if (isset($config['session']['expiration'])) {
112: $session->addSetup('setExpiration', array($config['session']['expiration']));
113: unset($config['session']['expiration']);
114: }
115: unset($config['session']['autoStart']);
116: if (!empty($config['session'])) {
117: Validators::assertField($config, 'session', 'array');
118: $session->addSetup('setOptions', array($config['session']));
119: }
120:
121: $container->addDefinition('userStorage')
122: ->setClass('Nette\Http\UserStorage');
123:
124:
125:
126: $user = $container->addDefinition('user')
127: ->setClass('Nette\Security\User');
128:
129: if (empty($config['productionMode']) && $config['security']['debugger']) {
130: $user->addSetup('Nette\Diagnostics\Debugger::$bar->addPanel(?)', array(
131: new Nette\DI\Statement('Nette\Security\Diagnostics\UserPanel')
132: ));
133: }
134:
135: if ($config['security']['users']) {
136: $container->addDefinition($this->prefix('authenticator'))
137: ->setClass('Nette\Security\SimpleAuthenticator', array($config['security']['users']));
138: }
139:
140: if ($config['security']['roles'] || $config['security']['resources']) {
141: $authorizator = $container->addDefinition($this->prefix('authorizator'))
142: ->setClass('Nette\Security\Permission');
143: foreach ($config['security']['roles'] as $role => $parents) {
144: $authorizator->addSetup('addRole', array($role, $parents));
145: }
146: foreach ($config['security']['resources'] as $resource => $parents) {
147: $authorizator->addSetup('addResource', array($resource, $parents));
148: }
149: }
150:
151:
152:
153: $application = $container->addDefinition('application')
154: ->setClass('Nette\Application\Application')
155: ->addSetup('$catchExceptions', $config['application']['catchExceptions'])
156: ->addSetup('$errorPresenter', $config['application']['errorPresenter']);
157:
158: if ($config['application']['debugger']) {
159: $application->addSetup('Nette\Application\Diagnostics\RoutingPanel::initializePanel');
160: }
161:
162: if (empty($config['productionMode']) && $config['routing']['debugger']) {
163: $application->addSetup('Nette\Diagnostics\Debugger::$bar->addPanel(?)', array(
164: new Nette\DI\Statement('Nette\Application\Diagnostics\RoutingPanel')
165: ));
166: }
167:
168:
169:
170: $router = $container->addDefinition('router')
171: ->setClass('Nette\Application\Routers\RouteList');
172:
173: foreach ($config['routing']['routes'] as $mask => $action) {
174: $router->addSetup('$service[] = new Nette\Application\Routers\Route(?, ?);', array($mask, $action));
175: }
176:
177: $container->addDefinition('presenterFactory')
178: ->setClass('Nette\Application\PresenterFactory', array(
179: isset($container->parameters['appDir']) ? $container->parameters['appDir'] : NULL
180: ));
181:
182:
183:
184: if (empty($config['mailer']['smtp'])) {
185: $container->addDefinition('mailer')
186: ->setClass('Nette\Mail\SendmailMailer');
187: } else {
188: Validators::assertField($config, 'mailer', 'array');
189: $container->addDefinition('mailer')
190: ->setClass('Nette\Mail\SmtpMailer', array($config['mailer']));
191: }
192:
193:
194:
195: $container->addDefinition($this->prefix('form'))
196: ->setClass('Nette\Forms\Form')
197: ->setShared(FALSE);
198:
199:
200:
201: $latte = $container->addDefinition($this->prefix('latte'))
202: ->setClass('Nette\Latte\Engine')
203: ->setShared(FALSE);
204:
205: if (empty($config['xhtml'])) {
206: $latte->addSetup('$service->getCompiler()->defaultContentType = ?', Nette\Latte\Compiler::CONTENT_HTML);
207: }
208:
209: $container->addDefinition($this->prefix('template'))
210: ->setClass('Nette\Templating\FileTemplate')
211: ->addSetup('registerFilter', array($latte))
212: ->addSetup('registerHelperLoader', array('Nette\Templating\Helpers::loader'))
213: ->setShared(FALSE);
214:
215:
216:
217: $container->addDefinition($this->prefix('database'))
218: ->setClass('Nette\DI\NestedAccessor', array('@container', $this->prefix('database')));
219:
220: $autowired = TRUE;
221: foreach ((array) $config['database'] as $name => $info) {
222: if (!is_array($info)) {
223: continue;
224: }
225: $info += $this->databaseDefaults + array('autowired' => $autowired);
226: $autowired = FALSE;
227:
228: foreach ((array) $info['options'] as $key => $value) {
229: unset($info['options'][$key]);
230: $info['options'][constant($key)] = $value;
231: }
232:
233: $connection = $container->addDefinition($this->prefix("database_$name"))
234: ->setClass('Nette\Database\Connection', array($info['dsn'], $info['user'], $info['password'], $info['options']))
235: ->setAutowired($info['autowired'])
236: ->addSetup('setCacheStorage')
237: ->addSetup('setDatabaseReflection', array(new Nette\DI\Statement('Nette\Database\Reflection\DiscoveredReflection')))
238: ->addSetup('Nette\Diagnostics\Debugger::$blueScreen->addPanel(?)', array(
239: 'Nette\Database\Diagnostics\ConnectionPanel::renderException'
240: ));
241:
242: if (empty($config['productionMode']) && $info['debugger']) {
243: $panel = $container->addDefinition($this->prefix("database_{$name}RoutingPanel"))
244: ->setClass('Nette\Database\Diagnostics\ConnectionPanel')
245: ->addSetup('$explain', !empty($info['explain']))
246: ->addSetup('Nette\Diagnostics\Debugger::$bar->addPanel(?)', array('@self'));
247:
248: $connection->addSetup('$service->onQuery[] = ?', array(array($panel, 'logQuery')));
249: }
250: }
251: }
252:
253:
254:
255: public function afterCompile(Nette\Utils\PhpGenerator\ClassType $class)
256: {
257: $initialize = $class->methods['initialize'];
258: $container = $this->getContainerBuilder();
259: $config = $this->getConfig($this->defaults);
260:
261: if (!empty($container->parameters['tempDir'])) {
262: $initialize->addBody($this->checkTempDir($container->expand('%tempDir%/cache')));
263: }
264:
265: foreach ((array) $config['forms']['messages'] as $name => $text) {
266: $initialize->addBody('Nette\Forms\Rules::$defaultMessages[Nette\Forms\Form::?] = ?;', array($name, $text));
267: }
268:
269: if ($config['session']['autoStart'] === 'smart') {
270: $initialize->addBody('$this->session->exists() && $this->session->start();');
271: } elseif ($config['session']['autoStart']) {
272: $initialize->addBody('$this->session->start();');
273: }
274:
275: if (isset($config['iAmUsingBadHost'])) {
276: $initialize->addBody('Nette\Framework::$iAmUsingBadHost = ?;', array((bool) $config['iAmUsingBadHost']));
277: }
278:
279: if (empty($config['xhtml'])) {
280: $initialize->addBody('Nette\Utils\Html::$xhtml = ?;', array((bool) $config['xhtml']));
281: }
282:
283: if (empty($config['productionMode'])) {
284: $initialize->addBody('Nette\Diagnostics\Debugger::$bar->addPanel(new Nette\DI\Diagnostics\ContainerPanel($this));');
285: }
286:
287: foreach ($container->findByTag('run') as $name => $foo) {
288: $initialize->addBody('$this->getService(?);', array($name));
289: }
290: }
291:
292:
293:
294: private function checkTempDir($dir)
295: {
296:
297: $uniq = uniqid('_', TRUE);
298: if (!@mkdir("$dir/$uniq", 0777)) {
299: throw new Nette\InvalidStateException("Unable to write to directory '$dir'. Make this directory writable.");
300: }
301:
302:
303: $useDirs = @file_put_contents("$dir/$uniq/_", '') !== FALSE;
304: @unlink("$dir/$uniq/_");
305: @rmdir("$dir/$uniq");
306:
307: return 'Nette\Caching\Storages\FileStorage::$useDirectories = ' . ($useDirs ? 'TRUE' : 'FALSE') . ";\n";
308: }
309:
310: }
311: