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