Completed
Pull Request — master (#7)
by Markus
06:25
created
src/dispatcher/Dispatcher.class.php 3 patches
Doc Comments   +2 added lines, -2 removed lines patch added patch discarded remove patch
@@ -324,7 +324,7 @@  discard block
 block discarded – undo
324 324
 	 * @param      string $moduleName A module name.
325 325
 	 * @param      string $controllerName An controller name.
326 326
 	 *
327
-	 * @return     mixed  the path to the controller file if the controller file
327
+	 * @return     string|false  the path to the controller file if the controller file
328 328
 	 *                    exists and is readable, false in any other case
329 329
 	 *
330 330
 	 * @author     Felix Gilcher <[email protected]>
@@ -414,7 +414,7 @@  discard block
 block discarded – undo
414 414
 	 * @param      string $moduleName A module name.
415 415
 	 * @param      string $viewName A view name.
416 416
 	 *
417
-	 * @return     mixed  the path to the view file if the view file 
417
+	 * @return     string|false  the path to the view file if the view file 
418 418
 	 *                    exists and is readable, false in any other case
419 419
 	 * 
420 420
 	 * @author     Felix Gilcher <[email protected]>
Please login to merge, or discard this patch.
Indentation   +584 added lines, -584 removed lines patch added patch discarded remove patch
@@ -50,671 +50,671 @@
 block discarded – undo
50 50
  */
51 51
 class Dispatcher extends ParameterHolder
52 52
 {
53
-	/**
54
-	 * @var        int The number of execution containers run so far.
55
-	 */
56
-	protected $numExecutions = 0;
53
+    /**
54
+     * @var        int The number of execution containers run so far.
55
+     */
56
+    protected $numExecutions = 0;
57 57
 	
58
-	/**
59
-	 * @var        Context An Context instance.
60
-	 */
61
-	protected $context = null;
58
+    /**
59
+     * @var        Context An Context instance.
60
+     */
61
+    protected $context = null;
62 62
 	
63
-	/**
64
-	 * @var        Response The global response.
65
-	 */
66
-	protected $response = null;
63
+    /**
64
+     * @var        Response The global response.
65
+     */
66
+    protected $response = null;
67 67
 	
68
-	/**
69
-	 * @var        FilterChain The global filter chain.
70
-	 */
71
-	protected $filterChain = null;
68
+    /**
69
+     * @var        FilterChain The global filter chain.
70
+     */
71
+    protected $filterChain = null;
72 72
 	
73
-	/**
74
-	 * @var        array An array of filter instances for reuse.
75
-	 */
76
-	protected $filters = array(
77
-		'global' => array(),
78
-		'controller' => array(
79
-			'*' => null
80
-		),
81
-		'dispatch' => null,
82
-		'execution' => null,
83
-		'security' => null
84
-	);
73
+    /**
74
+     * @var        array An array of filter instances for reuse.
75
+     */
76
+    protected $filters = array(
77
+        'global' => array(),
78
+        'controller' => array(
79
+            '*' => null
80
+        ),
81
+        'dispatch' => null,
82
+        'execution' => null,
83
+        'security' => null
84
+    );
85 85
 	
86
-	/**
87
-	 * @var        string The default Output Type.
88
-	 */
89
-	protected $defaultOutputType = null;
86
+    /**
87
+     * @var        string The default Output Type.
88
+     */
89
+    protected $defaultOutputType = null;
90 90
 	
91
-	/**
92
-	 * @var        array An array of registered Output Types.
93
-	 */
94
-	protected $outputTypes = array();
91
+    /**
92
+     * @var        array An array of registered Output Types.
93
+     */
94
+    protected $outputTypes = array();
95 95
 	
96
-	/**
97
-	 * @var        array Ref to the request data object from the request.
98
-	 */
99
-	private $requestData = null;
96
+    /**
97
+     * @var        array Ref to the request data object from the request.
98
+     */
99
+    private $requestData = null;
100 100
 	
101
-	/**
102
-	 * Increment the execution counter.
103
-	 * Will throw an exception if the maximum amount of runs is exceeded.
104
-	 *
105
-	 * @throws     DispatcherException If too many execution runs were made.
106
-	 *
107
-	 * @author     David Zülke <[email protected]>
108
-	 * @since      0.11.0
109
-	 */
110
-	public function countExecution()
111
-	{
112
-		$maxExecutions = $this->getParameter('max_executions');
101
+    /**
102
+     * Increment the execution counter.
103
+     * Will throw an exception if the maximum amount of runs is exceeded.
104
+     *
105
+     * @throws     DispatcherException If too many execution runs were made.
106
+     *
107
+     * @author     David Zülke <[email protected]>
108
+     * @since      0.11.0
109
+     */
110
+    public function countExecution()
111
+    {
112
+        $maxExecutions = $this->getParameter('max_executions');
113 113
 		
114
-		if(++$this->numExecutions > $maxExecutions && $maxExecutions > 0) {
115
-			throw new DispatcherException('Too many execution runs have been detected for this Context.');
116
-		}
117
-	}
114
+        if(++$this->numExecutions > $maxExecutions && $maxExecutions > 0) {
115
+            throw new DispatcherException('Too many execution runs have been detected for this Context.');
116
+        }
117
+    }
118 118
 	
119
-	/**
120
-	 * Create and initialize new execution container instance.
121
-	 *
122
-	 * @param      string                 $moduleName    The name of the module.
123
-	 * @param      string                 $controllerName    The name of the controller.
124
-	 * @param      RequestDataHolder      $arguments     A RequestDataHolder with additional
125
-	 *                                    request arguments.
126
-	 * @param      string                 $outputType    Optional name of an initial output type
127
-	 *                                    to set.
128
-	 * @param      string                 $requestMethod Optional name of the request method to
129
-	 *                                    be used in this container.
130
-	 *
131
-	 * @return     ExecutionContainer A new execution container instance,
132
-	 *                                     fully initialized.
133
-	 *
134
-	 * @author     David Zülke <[email protected]>
135
-	 * @since      0.11.0
136
-	 */
137
-	public function createExecutionContainer($moduleName = null, $controllerName = null, RequestDataHolder $arguments = null, $outputType = null, $requestMethod = null)
138
-	{
139
-		// create a new execution container
119
+    /**
120
+     * Create and initialize new execution container instance.
121
+     *
122
+     * @param      string                 $moduleName    The name of the module.
123
+     * @param      string                 $controllerName    The name of the controller.
124
+     * @param      RequestDataHolder      $arguments     A RequestDataHolder with additional
125
+     *                                    request arguments.
126
+     * @param      string                 $outputType    Optional name of an initial output type
127
+     *                                    to set.
128
+     * @param      string                 $requestMethod Optional name of the request method to
129
+     *                                    be used in this container.
130
+     *
131
+     * @return     ExecutionContainer A new execution container instance,
132
+     *                                     fully initialized.
133
+     *
134
+     * @author     David Zülke <[email protected]>
135
+     * @since      0.11.0
136
+     */
137
+    public function createExecutionContainer($moduleName = null, $controllerName = null, RequestDataHolder $arguments = null, $outputType = null, $requestMethod = null)
138
+    {
139
+        // create a new execution container
140 140
         /** @var ExecutionContainer $container */
141
-		$container = $this->context->createInstanceFor('execution_container');
142
-		$container->setModuleName($moduleName);
143
-		$container->setControllerName($controllerName);
144
-		$container->setRequestData($this->requestData);
145
-		if($arguments !== null) {
146
-			$container->setArguments($arguments);
147
-		}
148
-		$container->setOutputType($this->context->getDispatcher()->getOutputType($outputType));
149
-		if($requestMethod === null) {
150
-			$requestMethod = $this->context->getRequest()->getMethod();
151
-		}
152
-		$container->setRequestMethod($requestMethod);
153
-		return $container;
154
-	}
141
+        $container = $this->context->createInstanceFor('execution_container');
142
+        $container->setModuleName($moduleName);
143
+        $container->setControllerName($controllerName);
144
+        $container->setRequestData($this->requestData);
145
+        if($arguments !== null) {
146
+            $container->setArguments($arguments);
147
+        }
148
+        $container->setOutputType($this->context->getDispatcher()->getOutputType($outputType));
149
+        if($requestMethod === null) {
150
+            $requestMethod = $this->context->getRequest()->getMethod();
151
+        }
152
+        $container->setRequestMethod($requestMethod);
153
+        return $container;
154
+    }
155 155
 	
156
-	/**
157
-	 * Initialize a module and load its autoload, module config etc.
158
-	 *
159
-	 * @param      string $moduleName The name of the module to initialize.
160
-	 *
161
-	 * @author     Felix Gilcher <[email protected]>
162
-	 * @since      1.0.0
163
-	 */
164
-	public function initializeModule($moduleName)
165
-	{
166
-		$lowerModuleName = strtolower($moduleName);
156
+    /**
157
+     * Initialize a module and load its autoload, module config etc.
158
+     *
159
+     * @param      string $moduleName The name of the module to initialize.
160
+     *
161
+     * @author     Felix Gilcher <[email protected]>
162
+     * @since      1.0.0
163
+     */
164
+    public function initializeModule($moduleName)
165
+    {
166
+        $lowerModuleName = strtolower($moduleName);
167 167
 		
168
-		if(null === Config::get('modules.' . $lowerModuleName . '.enabled')) {
169
-			// set some defaults first
170
-			Config::fromArray(array(
171
-				'modules.' . $lowerModuleName . '.agavi.controller.path' => '%core.module_dir%/${moduleName}/controllers/${controllerName}Controller.class.php',
172
-				'modules.' . $lowerModuleName . '.agavi.cache.path' => '%core.module_dir%/${moduleName}/cache/${controllerName}.xml',
173
-				'modules.' . $lowerModuleName . '.agavi.template.directory' => '%core.module_dir%/${module}/templates',
174
-				'modules.' . $lowerModuleName . '.agavi.validate.path' => '%core.module_dir%/${moduleName}/validate/${controllerName}.xml',
175
-				'modules.' . $lowerModuleName . '.agavi.view.path' => '%core.module_dir%/${moduleName}/views/${viewName}View.class.php',
176
-				'modules.' . $lowerModuleName . '.agavi.view.name' => '${controllerName}${viewName}',
177
-			));
178
-			// include the module configuration
179
-			// loaded only once due to the way load() (former import()) works
180
-			if(is_readable(Config::get('core.module_dir') . '/' . $moduleName . '/config/module.xml')) {
181
-				include_once(ConfigCache::checkConfig(Config::get('core.module_dir') . '/' . $moduleName . '/config/module.xml'));
182
-			} else {
183
-				Config::set('modules.' . $lowerModuleName . '.enabled', true);
184
-			}
168
+        if(null === Config::get('modules.' . $lowerModuleName . '.enabled')) {
169
+            // set some defaults first
170
+            Config::fromArray(array(
171
+                'modules.' . $lowerModuleName . '.agavi.controller.path' => '%core.module_dir%/${moduleName}/controllers/${controllerName}Controller.class.php',
172
+                'modules.' . $lowerModuleName . '.agavi.cache.path' => '%core.module_dir%/${moduleName}/cache/${controllerName}.xml',
173
+                'modules.' . $lowerModuleName . '.agavi.template.directory' => '%core.module_dir%/${module}/templates',
174
+                'modules.' . $lowerModuleName . '.agavi.validate.path' => '%core.module_dir%/${moduleName}/validate/${controllerName}.xml',
175
+                'modules.' . $lowerModuleName . '.agavi.view.path' => '%core.module_dir%/${moduleName}/views/${viewName}View.class.php',
176
+                'modules.' . $lowerModuleName . '.agavi.view.name' => '${controllerName}${viewName}',
177
+            ));
178
+            // include the module configuration
179
+            // loaded only once due to the way load() (former import()) works
180
+            if(is_readable(Config::get('core.module_dir') . '/' . $moduleName . '/config/module.xml')) {
181
+                include_once(ConfigCache::checkConfig(Config::get('core.module_dir') . '/' . $moduleName . '/config/module.xml'));
182
+            } else {
183
+                Config::set('modules.' . $lowerModuleName . '.enabled', true);
184
+            }
185 185
 			
186
-			$moduleAutoload = Config::get('core.module_dir') . '/' . $moduleName . '/config/autoload.xml';
187
-			if(is_readable($moduleAutoload)) {
188
-				ConfigCache::load($moduleAutoload);
189
-			}
186
+            $moduleAutoload = Config::get('core.module_dir') . '/' . $moduleName . '/config/autoload.xml';
187
+            if(is_readable($moduleAutoload)) {
188
+                ConfigCache::load($moduleAutoload);
189
+            }
190 190
 			
191
-			if(Config::get('modules.' . $lowerModuleName . '.enabled')) {
192
-				$moduleConfigHandlers = Config::get('core.module_dir') . '/' . $moduleName . '/config/config_handlers.xml';
193
-				if(is_readable($moduleConfigHandlers)) {
194
-					ConfigCache::addConfigHandlersFile($moduleConfigHandlers);
195
-				}
196
-			}
197
-		}
191
+            if(Config::get('modules.' . $lowerModuleName . '.enabled')) {
192
+                $moduleConfigHandlers = Config::get('core.module_dir') . '/' . $moduleName . '/config/config_handlers.xml';
193
+                if(is_readable($moduleConfigHandlers)) {
194
+                    ConfigCache::addConfigHandlersFile($moduleConfigHandlers);
195
+                }
196
+            }
197
+        }
198 198
 		
199
-		if(!Config::get('modules.' . $lowerModuleName . '.enabled')) {
200
-			throw new DisabledModuleException(sprintf('The module "%1$s" is disabled.', $moduleName));
201
-		}
199
+        if(!Config::get('modules.' . $lowerModuleName . '.enabled')) {
200
+            throw new DisabledModuleException(sprintf('The module "%1$s" is disabled.', $moduleName));
201
+        }
202 202
 		
203
-		// check for a module config.php
204
-		$moduleConfig = Config::get('core.module_dir') . '/' . $moduleName . '/config.php';
205
-		if(is_readable($moduleConfig)) {
206
-			require_once($moduleConfig);
207
-		}
208
-	}
203
+        // check for a module config.php
204
+        $moduleConfig = Config::get('core.module_dir') . '/' . $moduleName . '/config.php';
205
+        if(is_readable($moduleConfig)) {
206
+            require_once($moduleConfig);
207
+        }
208
+    }
209 209
 	
210
-	/**
211
-	 * Dispatch a request
212
-	 *
213
-	 * @param      RequestDataHolder  $arguments An optional request data holder object
214
-	 *                                with additional request data.
215
-	 * @param      ExecutionContainer $container An optional execution container that,
216
-	 *                                if given, will be executed right away,
217
-	 *                                skipping routing execution.
218
-	 *
219
-	 * @return     Response The response produced during this dispatch call.
220
-	 *
221
-	 * @author     David Zülke <[email protected]>
222
-	 * @since      0.9.0
223
-	 */
224
-	public function dispatch(RequestDataHolder $arguments = null, ExecutionContainer $container = null)
225
-	{
226
-		try {
210
+    /**
211
+     * Dispatch a request
212
+     *
213
+     * @param      RequestDataHolder  $arguments An optional request data holder object
214
+     *                                with additional request data.
215
+     * @param      ExecutionContainer $container An optional execution container that,
216
+     *                                if given, will be executed right away,
217
+     *                                skipping routing execution.
218
+     *
219
+     * @return     Response The response produced during this dispatch call.
220
+     *
221
+     * @author     David Zülke <[email protected]>
222
+     * @since      0.9.0
223
+     */
224
+    public function dispatch(RequestDataHolder $arguments = null, ExecutionContainer $container = null)
225
+    {
226
+        try {
227 227
 			
228
-			$rq = $this->context->getRequest();
229
-			$rd = $rq->getRequestData();
228
+            $rq = $this->context->getRequest();
229
+            $rd = $rq->getRequestData();
230 230
 			
231
-			if($container === null) {
232
-				// match routes and assign returned initial execution container
233
-				$container = $this->context->getRouting()->execute();
234
-			}
231
+            if($container === null) {
232
+                // match routes and assign returned initial execution container
233
+                $container = $this->context->getRouting()->execute();
234
+            }
235 235
 			
236
-			if($container instanceof ExecutionContainer) {
237
-				// merge in any arguments given. they need to have precedence over what the routing found
238
-				if($arguments !== null) {
239
-					$rd->merge($arguments);
240
-				}
236
+            if($container instanceof ExecutionContainer) {
237
+                // merge in any arguments given. they need to have precedence over what the routing found
238
+                if($arguments !== null) {
239
+                    $rd->merge($arguments);
240
+                }
241 241
 				
242
-				// next, we have to see if the routing did anything useful, i.e. whether or not it was enabled.
243
-				$moduleName = $container->getModuleName();
244
-				$controllerName = $container->getControllerName();
245
-				if(!$moduleName) {
246
-					// no module has been specified; that means the routing did not run, as it would otherwise have the 404 controller's module name
242
+                // next, we have to see if the routing did anything useful, i.e. whether or not it was enabled.
243
+                $moduleName = $container->getModuleName();
244
+                $controllerName = $container->getControllerName();
245
+                if(!$moduleName) {
246
+                    // no module has been specified; that means the routing did not run, as it would otherwise have the 404 controller's module name
247 247
 					
248
-					// lets see if our request data has values for module and controller
249
-					$ma = $rq->getParameter('module_accessor');
250
-					$aa = $rq->getParameter('controller_accessor');
251
-					if($rd->hasParameter($ma) && $rd->hasParameter($aa)) {
252
-						// yup. grab those
253
-						$moduleName = $rd->getParameter($ma);
254
-						$controllerName = $rd->getParameter($aa);
255
-					} else {
256
-						// nope. then its time for the default controller
257
-						$moduleName = Config::get('controllers.default_module');
258
-						$controllerName = Config::get('controllers.default_controller');
259
-					}
248
+                    // lets see if our request data has values for module and controller
249
+                    $ma = $rq->getParameter('module_accessor');
250
+                    $aa = $rq->getParameter('controller_accessor');
251
+                    if($rd->hasParameter($ma) && $rd->hasParameter($aa)) {
252
+                        // yup. grab those
253
+                        $moduleName = $rd->getParameter($ma);
254
+                        $controllerName = $rd->getParameter($aa);
255
+                    } else {
256
+                        // nope. then its time for the default controller
257
+                        $moduleName = Config::get('controllers.default_module');
258
+                        $controllerName = Config::get('controllers.default_controller');
259
+                    }
260 260
 					
261 261
                     // so by now we hopefully have something reasonable for module and controller names - let's set them on the container
262
-					$container->setModuleName($moduleName);
263
-					$container->setControllerName($controllerName);
264
-				}
262
+                    $container->setModuleName($moduleName);
263
+                    $container->setControllerName($controllerName);
264
+                }
265 265
 				
266
-				if(!Config::get('core.available', false)) {
267
-					$container = $container->createSystemControllerForwardContainer('unavailable');
268
-				}
266
+                if(!Config::get('core.available', false)) {
267
+                    $container = $container->createSystemControllerForwardContainer('unavailable');
268
+                }
269 269
 				
270
-				// create a new filter chain
271
-				/** @var FilterChain $filterChain */
272
-				$filterChain = $this->getFilterChain();
270
+                // create a new filter chain
271
+                /** @var FilterChain $filterChain */
272
+                $filterChain = $this->getFilterChain();
273 273
 				
274
-				$this->loadFilters($filterChain, 'global');
274
+                $this->loadFilters($filterChain, 'global');
275 275
 				
276
-				// register the dispatch filter
277
-				$filterChain->register($this->filters['dispatch'], 'agavi_dispatch_filter');
276
+                // register the dispatch filter
277
+                $filterChain->register($this->filters['dispatch'], 'agavi_dispatch_filter');
278 278
 				
279
-				// go, go, go!
280
-				$filterChain->execute($container);
279
+                // go, go, go!
280
+                $filterChain->execute($container);
281 281
 				
282
-				$response = $container->getResponse();
283
-			} elseif($container instanceof Response) {
284
-				// the routing returned a response!
285
-				$response = $container;
286
-				// set $container to null so Exception::render() won't think it is a container if an exception happens later!
287
-				$container = null;
288
-			} else {
289
-				throw new AgaviException('AgaviRouting::execute() returned neither ExecutionContainer nor Response object.');
290
-			}
291
-			$response->merge($this->response);
282
+                $response = $container->getResponse();
283
+            } elseif($container instanceof Response) {
284
+                // the routing returned a response!
285
+                $response = $container;
286
+                // set $container to null so Exception::render() won't think it is a container if an exception happens later!
287
+                $container = null;
288
+            } else {
289
+                throw new AgaviException('AgaviRouting::execute() returned neither ExecutionContainer nor Response object.');
290
+            }
291
+            $response->merge($this->response);
292 292
 			
293
-			if($this->getParameter('send_response')) {
294
-				$response->send();
295
-			}
293
+            if($this->getParameter('send_response')) {
294
+                $response->send();
295
+            }
296 296
 			
297
-			return $response;
297
+            return $response;
298 298
 			
299
-		} catch(\Exception $e) {
300
-			AgaviException::render($e, $this->context, $container);
301
-		}
302
-	}
299
+        } catch(\Exception $e) {
300
+            AgaviException::render($e, $this->context, $container);
301
+        }
302
+    }
303 303
 	
304
-	/**
305
-	 * Get the global response instance.
306
-	 *
307
-	 * @return     Response The global response.
308
-	 *
309
-	 * @author     David Zülke <[email protected]>
310
-	 * @since      0.11.0
311
-	 */
312
-	public function getGlobalResponse()
313
-	{
314
-		return $this->response;
315
-	}
304
+    /**
305
+     * Get the global response instance.
306
+     *
307
+     * @return     Response The global response.
308
+     *
309
+     * @author     David Zülke <[email protected]>
310
+     * @since      0.11.0
311
+     */
312
+    public function getGlobalResponse()
313
+    {
314
+        return $this->response;
315
+    }
316 316
 	
317 317
 	
318
-	/**
319
-	 * Indicates whether or not a module has a specific controller file.
320
-	 * 
321
-	 * Please note that this is only a cursory check and does not 
322
-	 * check whether the file actually contains the proper class
323
-	 *
324
-	 * @param      string $moduleName A module name.
325
-	 * @param      string $controllerName An controller name.
326
-	 *
327
-	 * @return     mixed  the path to the controller file if the controller file
328
-	 *                    exists and is readable, false in any other case
329
-	 *
330
-	 * @author     Felix Gilcher <[email protected]>
331
-	 * @since      1.0.0
332
-	 */
333
-	public function checkControllerFile($moduleName, $controllerName)
334
-	{
335
-		$this->initializeModule($moduleName);
318
+    /**
319
+     * Indicates whether or not a module has a specific controller file.
320
+     * 
321
+     * Please note that this is only a cursory check and does not 
322
+     * check whether the file actually contains the proper class
323
+     *
324
+     * @param      string $moduleName A module name.
325
+     * @param      string $controllerName An controller name.
326
+     *
327
+     * @return     mixed  the path to the controller file if the controller file
328
+     *                    exists and is readable, false in any other case
329
+     *
330
+     * @author     Felix Gilcher <[email protected]>
331
+     * @since      1.0.0
332
+     */
333
+    public function checkControllerFile($moduleName, $controllerName)
334
+    {
335
+        $this->initializeModule($moduleName);
336 336
 		
337
-		$controllerName = Toolkit::canonicalName($controllerName);
338
-		$file = Toolkit::evaluateModuleDirective(
339
-			$moduleName,
340
-			'agavi.controller.path',
341
-			array(
342
-				'moduleName' => $moduleName,
343
-				'controllerName' => $controllerName,
344
-			)
345
-		);
337
+        $controllerName = Toolkit::canonicalName($controllerName);
338
+        $file = Toolkit::evaluateModuleDirective(
339
+            $moduleName,
340
+            'agavi.controller.path',
341
+            array(
342
+                'moduleName' => $moduleName,
343
+                'controllerName' => $controllerName,
344
+            )
345
+        );
346 346
 		
347
-		if(is_readable($file) && substr($controllerName, 0, 1) !== '/') {
348
-			return $file;
349
-		}
347
+        if(is_readable($file) && substr($controllerName, 0, 1) !== '/') {
348
+            return $file;
349
+        }
350 350
 		
351
-		return false;
352
-	}
351
+        return false;
352
+    }
353 353
 	
354
-	/**
355
-	 * Retrieve an Controller implementation instance.
356
-	 *
357
-	 * @param      string $moduleName A module name.
358
-	 * @param      string $controllerName An controller name.
359
-	 *
360
-	 * @return     Controller An Controller implementation instance
361
-	 *
362
-	 * @throws     FileNotFoundException|ClassNotFoundException if the controller could not be found.
363
-	 *
364
-	 * @author     Sean Kerr <[email protected]>
365
-	 * @author     Mike Vincent <[email protected]>
366
-	 * @author     David Zülke <[email protected]>
367
-	 * @since      0.9.0
368
-	 */
369
-	public function createControllerInstance($moduleName, $controllerName)
370
-	{
371
-		$this->initializeModule($moduleName);
354
+    /**
355
+     * Retrieve an Controller implementation instance.
356
+     *
357
+     * @param      string $moduleName A module name.
358
+     * @param      string $controllerName An controller name.
359
+     *
360
+     * @return     Controller An Controller implementation instance
361
+     *
362
+     * @throws     FileNotFoundException|ClassNotFoundException if the controller could not be found.
363
+     *
364
+     * @author     Sean Kerr <[email protected]>
365
+     * @author     Mike Vincent <[email protected]>
366
+     * @author     David Zülke <[email protected]>
367
+     * @since      0.9.0
368
+     */
369
+    public function createControllerInstance($moduleName, $controllerName)
370
+    {
371
+        $this->initializeModule($moduleName);
372 372
 		
373
-		$controllerName = Toolkit::canonicalName($controllerName);
374
-		$longControllerName = str_replace('/', '_', $controllerName);
373
+        $controllerName = Toolkit::canonicalName($controllerName);
374
+        $longControllerName = str_replace('/', '_', $controllerName);
375 375
 		
376
-		$class = $moduleName . '_' . $longControllerName . 'Controller';
376
+        $class = $moduleName . '_' . $longControllerName . 'Controller';
377 377
 		
378
-		if(!class_exists($class)) {
379
-			if(false !== ($file = $this->checkControllerFile($moduleName, $controllerName))) {
380
-				require($file);
381
-			} else {
382
-				throw new FileNotFoundException(sprintf('Could not find file for Controller "%s" in Module "%s".', $controllerName, $moduleName));
383
-			}
378
+        if(!class_exists($class)) {
379
+            if(false !== ($file = $this->checkControllerFile($moduleName, $controllerName))) {
380
+                require($file);
381
+            } else {
382
+                throw new FileNotFoundException(sprintf('Could not find file for Controller "%s" in Module "%s".', $controllerName, $moduleName));
383
+            }
384 384
 			
385
-			if(!class_exists($class, false)) {
386
-				throw new ClassNotFoundException(sprintf('Failed to instantiate Controller "%s" in Module "%s" because file "%s" does not contain class "%s".', $controllerName, $moduleName, $file, $class));
387
-			}
388
-		} 
385
+            if(!class_exists($class, false)) {
386
+                throw new ClassNotFoundException(sprintf('Failed to instantiate Controller "%s" in Module "%s" because file "%s" does not contain class "%s".', $controllerName, $moduleName, $file, $class));
387
+            }
388
+        } 
389 389
 		
390
-		return new $class();
391
-	}
390
+        return new $class();
391
+    }
392 392
 
393
-	/**
394
-	 * Retrieve the current application context.
395
-	 *
396
-	 * @return     Context An Context instance.
397
-	 *
398
-	 * @author     Sean Kerr <[email protected]>
399
-	 * @since      0.9.0
400
-	 */
401
-	public final function getContext()
402
-	{
403
-		return $this->context;
404
-	}
393
+    /**
394
+     * Retrieve the current application context.
395
+     *
396
+     * @return     Context An Context instance.
397
+     *
398
+     * @author     Sean Kerr <[email protected]>
399
+     * @since      0.9.0
400
+     */
401
+    public final function getContext()
402
+    {
403
+        return $this->context;
404
+    }
405 405
 
406 406
 
407 407
 	
408
-	/**
409
-	 * Indicates whether or not a module has a specific view file.
410
-	 * 
411
-	 * Please note that this is only a cursory check and does not 
412
-	 * check whether the file actually contains the proper class
413
-	 *
414
-	 * @param      string $moduleName A module name.
415
-	 * @param      string $viewName A view name.
416
-	 *
417
-	 * @return     mixed  the path to the view file if the view file 
418
-	 *                    exists and is readable, false in any other case
419
-	 * 
420
-	 * @author     Felix Gilcher <[email protected]>
421
-	 * @since      1.0.0
422
-	 */
423
-	public function checkViewFile($moduleName, $viewName)
424
-	{
425
-		$this->initializeModule($moduleName);
408
+    /**
409
+     * Indicates whether or not a module has a specific view file.
410
+     * 
411
+     * Please note that this is only a cursory check and does not 
412
+     * check whether the file actually contains the proper class
413
+     *
414
+     * @param      string $moduleName A module name.
415
+     * @param      string $viewName A view name.
416
+     *
417
+     * @return     mixed  the path to the view file if the view file 
418
+     *                    exists and is readable, false in any other case
419
+     * 
420
+     * @author     Felix Gilcher <[email protected]>
421
+     * @since      1.0.0
422
+     */
423
+    public function checkViewFile($moduleName, $viewName)
424
+    {
425
+        $this->initializeModule($moduleName);
426 426
 		
427
-		$viewName = Toolkit::canonicalName($viewName);
428
-		$file = Toolkit::evaluateModuleDirective(
429
-			$moduleName,
430
-			'agavi.view.path',
431
-			array(
432
-				'moduleName' => $moduleName,
433
-				'viewName' => $viewName,
434
-			)
435
-		);
427
+        $viewName = Toolkit::canonicalName($viewName);
428
+        $file = Toolkit::evaluateModuleDirective(
429
+            $moduleName,
430
+            'agavi.view.path',
431
+            array(
432
+                'moduleName' => $moduleName,
433
+                'viewName' => $viewName,
434
+            )
435
+        );
436 436
 		
437
-		if(is_readable($file) && substr($viewName, 0, 1) !== '/') {
438
-			return $file;
439
-		}
437
+        if(is_readable($file) && substr($viewName, 0, 1) !== '/') {
438
+            return $file;
439
+        }
440 440
 		
441
-		return false;
442
-	}
441
+        return false;
442
+    }
443 443
 	
444
-	/**
445
-	 * Retrieve a View implementation instance.
446
-	 *
447
-	 * @param      string $moduleName A module name.
448
-	 * @param      string $viewName A view name.
449
-	 *
450
-	 * @return     View A View implementation instance,
451
-	 *
452
-	 * @throws     AgaviException if the view could not be found.
453
-	 *
454
-	 * @author     Sean Kerr <[email protected]>
455
-	 * @author     Mike Vincent <[email protected]>
456
-	 * @author     David Zülke <[email protected]>
457
-	 * @since      0.9.0
458
-	 */
459
-	public function createViewInstance($moduleName, $viewName)
460
-	{
461
-		try {
462
-			$this->initializeModule($moduleName);
463
-		} catch(DisabledModuleException $e) {
464
-			// views from disabled modules should be usable by definition
465
-			// swallow
466
-		}
444
+    /**
445
+     * Retrieve a View implementation instance.
446
+     *
447
+     * @param      string $moduleName A module name.
448
+     * @param      string $viewName A view name.
449
+     *
450
+     * @return     View A View implementation instance,
451
+     *
452
+     * @throws     AgaviException if the view could not be found.
453
+     *
454
+     * @author     Sean Kerr <[email protected]>
455
+     * @author     Mike Vincent <[email protected]>
456
+     * @author     David Zülke <[email protected]>
457
+     * @since      0.9.0
458
+     */
459
+    public function createViewInstance($moduleName, $viewName)
460
+    {
461
+        try {
462
+            $this->initializeModule($moduleName);
463
+        } catch(DisabledModuleException $e) {
464
+            // views from disabled modules should be usable by definition
465
+            // swallow
466
+        }
467 467
 		
468
-		$viewName = Toolkit::canonicalName($viewName);
469
-		$longViewName = str_replace('/', '_', $viewName);
468
+        $viewName = Toolkit::canonicalName($viewName);
469
+        $longViewName = str_replace('/', '_', $viewName);
470 470
 		
471
-		$class = $moduleName . '_' . $longViewName . 'View';
471
+        $class = $moduleName . '_' . $longViewName . 'View';
472 472
 		
473
-		if(!class_exists($class)) {
473
+        if(!class_exists($class)) {
474 474
 			
475
-			if(false !== ($file = $this->checkViewFile($moduleName, $viewName))) {
476
-				require($file);
477
-			} else {
478
-				throw new FileNotFoundException(sprintf('Could not find file for View "%s" in Module "%s".', $viewName, $moduleName));
479
-			}
475
+            if(false !== ($file = $this->checkViewFile($moduleName, $viewName))) {
476
+                require($file);
477
+            } else {
478
+                throw new FileNotFoundException(sprintf('Could not find file for View "%s" in Module "%s".', $viewName, $moduleName));
479
+            }
480 480
 			
481
-			if(!class_exists($class, false)) {
482
-				throw new ClassNotFoundException(sprintf('Failed to instantiate View "%s" in Module "%s" because file "%s" does not contain class "%s".', $viewName, $moduleName, $file, $class));
483
-			}
484
-		} 
481
+            if(!class_exists($class, false)) {
482
+                throw new ClassNotFoundException(sprintf('Failed to instantiate View "%s" in Module "%s" because file "%s" does not contain class "%s".', $viewName, $moduleName, $file, $class));
483
+            }
484
+        } 
485 485
 		
486
-		return new $class();
487
-	}
486
+        return new $class();
487
+    }
488 488
 
489
-	/**
490
-	 * Constructor.
491
-	 *
492
-	 * @author     David Zülke <[email protected]>
493
-	 * @since      0.11.0
494
-	 */
495
-	public function __construct()
496
-	{
497
-		parent::__construct();
498
-		$this->setParameters(array(
499
-			'max_executions' => 20,
500
-			'send_response' => true,
501
-		));
502
-	}
489
+    /**
490
+     * Constructor.
491
+     *
492
+     * @author     David Zülke <[email protected]>
493
+     * @since      0.11.0
494
+     */
495
+    public function __construct()
496
+    {
497
+        parent::__construct();
498
+        $this->setParameters(array(
499
+            'max_executions' => 20,
500
+            'send_response' => true,
501
+        ));
502
+    }
503 503
 	
504
-	/**
505
-	 * Initialize this Dispatcher.
506
-	 *
507
-	 * @param      Context $context A Context instance.
508
-	 * @param      array   $parameters An array of initialization parameters.
509
-	 *
510
-	 * @author     David Zülke <[email protected]>
511
-	 * @since      0.9.0
512
-	 */
513
-	public function initialize(Context $context, array $parameters = array())
514
-	{
515
-		$this->context = $context;
504
+    /**
505
+     * Initialize this Dispatcher.
506
+     *
507
+     * @param      Context $context A Context instance.
508
+     * @param      array   $parameters An array of initialization parameters.
509
+     *
510
+     * @author     David Zülke <[email protected]>
511
+     * @since      0.9.0
512
+     */
513
+    public function initialize(Context $context, array $parameters = array())
514
+    {
515
+        $this->context = $context;
516 516
 		
517
-		$this->setParameters($parameters);
517
+        $this->setParameters($parameters);
518 518
 		
519
-		$this->response = $this->context->createInstanceFor('response');
519
+        $this->response = $this->context->createInstanceFor('response');
520 520
 		
521
-		$cfg = Config::get('core.config_dir') . '/output_types.xml';
522
-		require(ConfigCache::checkConfig($cfg, $this->context->getName()));
521
+        $cfg = Config::get('core.config_dir') . '/output_types.xml';
522
+        require(ConfigCache::checkConfig($cfg, $this->context->getName()));
523 523
 		
524
-		if(Config::get('core.use_security', false)) {
525
-			$this->filters['security'] = $this->context->createInstanceFor('security_filter');
526
-		}
524
+        if(Config::get('core.use_security', false)) {
525
+            $this->filters['security'] = $this->context->createInstanceFor('security_filter');
526
+        }
527 527
 		
528
-		$this->filters['dispatch'] = $this->context->createInstanceFor('dispatch_filter');
528
+        $this->filters['dispatch'] = $this->context->createInstanceFor('dispatch_filter');
529 529
 		
530
-		$this->filters['execution'] = $this->context->createInstanceFor('execution_filter');
531
-	}
530
+        $this->filters['execution'] = $this->context->createInstanceFor('execution_filter');
531
+    }
532 532
 	
533
-	/**
534
-	 * Get a filter.
535
-	 *
536
-	 * @param      string $which The name of the filter list section.
537
-	 *
538
-	 * @return     Filter A filter instance, or null.
539
-	 *
540
-	 * @author     David Zülke <[email protected]>
541
-	 * @since      0.11.0
542
-	 */
543
-	public function getFilter($which)
544
-	{
545
-		return (isset($this->filters[$which]) ? $this->filters[$which] : null);
546
-	}
533
+    /**
534
+     * Get a filter.
535
+     *
536
+     * @param      string $which The name of the filter list section.
537
+     *
538
+     * @return     Filter A filter instance, or null.
539
+     *
540
+     * @author     David Zülke <[email protected]>
541
+     * @since      0.11.0
542
+     */
543
+    public function getFilter($which)
544
+    {
545
+        return (isset($this->filters[$which]) ? $this->filters[$which] : null);
546
+    }
547 547
 	
548
-	/**
549
-	 * Get the global filter chain.
550
-	 *
551
-	 * @return     FilterChain The global filter chain.
552
-	 *
553
-	 * @author     David Zülke <[email protected]>
554
-	 * @since      1.1.0
555
-	 */
556
-	public function getFilterChain()
557
-	{
558
-		if($this->filterChain === null) {
559
-			$this->filterChain = $this->context->createInstanceFor('filter_chain');
560
-			$this->filterChain->setType(FilterChain::TYPE_GLOBAL);
561
-		}
548
+    /**
549
+     * Get the global filter chain.
550
+     *
551
+     * @return     FilterChain The global filter chain.
552
+     *
553
+     * @author     David Zülke <[email protected]>
554
+     * @since      1.1.0
555
+     */
556
+    public function getFilterChain()
557
+    {
558
+        if($this->filterChain === null) {
559
+            $this->filterChain = $this->context->createInstanceFor('filter_chain');
560
+            $this->filterChain->setType(FilterChain::TYPE_GLOBAL);
561
+        }
562 562
 		
563
-		return $this->filterChain;
564
-	}
563
+        return $this->filterChain;
564
+    }
565 565
 	
566
-	/**
567
-	 * Load filters.
568
-	 *
569
-	 * @param      FilterChain $filterChain A FilterChain instance.
570
-	 * @param      string      $which "global" or "controller".
571
-	 * @param      string      $module A module name, or "*" for the generic config.
572
-	 *
573
-	 * @author     David Zülke <[email protected]>
574
-	 * @since      0.11.0
575
-	 */
576
-	public function loadFilters(FilterChain $filterChain, $which = 'global', $module = null)
577
-	{
578
-		if($module === null) {
579
-			$module = '*';
580
-		}
566
+    /**
567
+     * Load filters.
568
+     *
569
+     * @param      FilterChain $filterChain A FilterChain instance.
570
+     * @param      string      $which "global" or "controller".
571
+     * @param      string      $module A module name, or "*" for the generic config.
572
+     *
573
+     * @author     David Zülke <[email protected]>
574
+     * @since      0.11.0
575
+     */
576
+    public function loadFilters(FilterChain $filterChain, $which = 'global', $module = null)
577
+    {
578
+        if($module === null) {
579
+            $module = '*';
580
+        }
581 581
 		
582
-		if(($which != 'global' && !isset($this->filters[$which][$module])) || $which == 'global' && $this->filters[$which] == null) {
583
-			if($which == 'global') {
584
-				$this->filters[$which] = array();
585
-				$filters =& $this->filters[$which];
586
-			} else {
587
-				$this->filters[$which][$module] = array();
588
-				$filters =& $this->filters[$which][$module];
589
-			}
590
-			$config = ($module == '*' ? Config::get('core.config_dir') : Config::get('core.module_dir') . '/' . $module . '/config') . '/' . $which . '_filters.xml';
591
-			if(is_readable($config)) {
592
-				require(ConfigCache::checkConfig($config, $this->context->getName()));
593
-			}
594
-		} else {
595
-			if($which == 'global') {
596
-				$filters =& $this->filters[$which];
597
-			} else {
598
-				$filters =& $this->filters[$which][$module];
599
-			}
600
-		}
582
+        if(($which != 'global' && !isset($this->filters[$which][$module])) || $which == 'global' && $this->filters[$which] == null) {
583
+            if($which == 'global') {
584
+                $this->filters[$which] = array();
585
+                $filters =& $this->filters[$which];
586
+            } else {
587
+                $this->filters[$which][$module] = array();
588
+                $filters =& $this->filters[$which][$module];
589
+            }
590
+            $config = ($module == '*' ? Config::get('core.config_dir') : Config::get('core.module_dir') . '/' . $module . '/config') . '/' . $which . '_filters.xml';
591
+            if(is_readable($config)) {
592
+                require(ConfigCache::checkConfig($config, $this->context->getName()));
593
+            }
594
+        } else {
595
+            if($which == 'global') {
596
+                $filters =& $this->filters[$which];
597
+            } else {
598
+                $filters =& $this->filters[$which][$module];
599
+            }
600
+        }
601 601
 		
602
-		foreach($filters as $name => $filter) {
603
-			$filterChain->register($filter, $name);
604
-		}
605
-	}
602
+        foreach($filters as $name => $filter) {
603
+            $filterChain->register($filter, $name);
604
+        }
605
+    }
606 606
 
607
-	/**
608
-	 * Indicates whether or not a module has a specific model.
609
-	 *
610
-	 * @param      string $moduleName A module name.
611
-	 * @param      string $modelName A model name.
612
-	 *
613
-	 * @return     bool true, if the model exists, otherwise false.
614
-	 *
615
-	 * @author     Sean Kerr <[email protected]>
616
-	 * @since      0.9.0
617
-	 */
618
-	public function modelExists($moduleName, $modelName)
619
-	{
620
-		$modelName = Toolkit::canonicalName($modelName);
621
-		$file = Config::get('core.module_dir') . '/' . $moduleName . '/models/' . $modelName .	'Model.class.php';
622
-		return is_readable($file);
623
-	}
607
+    /**
608
+     * Indicates whether or not a module has a specific model.
609
+     *
610
+     * @param      string $moduleName A module name.
611
+     * @param      string $modelName A model name.
612
+     *
613
+     * @return     bool true, if the model exists, otherwise false.
614
+     *
615
+     * @author     Sean Kerr <[email protected]>
616
+     * @since      0.9.0
617
+     */
618
+    public function modelExists($moduleName, $modelName)
619
+    {
620
+        $modelName = Toolkit::canonicalName($modelName);
621
+        $file = Config::get('core.module_dir') . '/' . $moduleName . '/models/' . $modelName .	'Model.class.php';
622
+        return is_readable($file);
623
+    }
624 624
 
625
-	/**
626
-	 * Indicates whether or not a module exists.
627
-	 *
628
-	 * @param      string $moduleName A module name.
629
-	 *
630
-	 * @return     bool true, if the module exists, otherwise false.
631
-	 *
632
-	 * @author     Sean Kerr <[email protected]>
633
-	 * @since      0.9.0
634
-	 */
635
-	public function moduleExists($moduleName)
636
-	{
637
-		$file = Config::get('core.module_dir') . '/' . $moduleName . '/config/module.xml';
638
-		return is_readable($file);
639
-	}
625
+    /**
626
+     * Indicates whether or not a module exists.
627
+     *
628
+     * @param      string $moduleName A module name.
629
+     *
630
+     * @return     bool true, if the module exists, otherwise false.
631
+     *
632
+     * @author     Sean Kerr <[email protected]>
633
+     * @since      0.9.0
634
+     */
635
+    public function moduleExists($moduleName)
636
+    {
637
+        $file = Config::get('core.module_dir') . '/' . $moduleName . '/config/module.xml';
638
+        return is_readable($file);
639
+    }
640 640
 
641
-	/**
642
-	 * Do any necessary startup work after initialization.
643
-	 *
644
-	 * This method is not called directly after initialize().
645
-	 *
646
-	 * @author     David Zülke <[email protected]>
647
-	 * @since      0.11.0
648
-	 */
649
-	public function startup()
650
-	{
651
-		// grab a pointer to the request data
652
-		$this->requestData = $this->context->getRequest()->getRequestData();
653
-	}
641
+    /**
642
+     * Do any necessary startup work after initialization.
643
+     *
644
+     * This method is not called directly after initialize().
645
+     *
646
+     * @author     David Zülke <[email protected]>
647
+     * @since      0.11.0
648
+     */
649
+    public function startup()
650
+    {
651
+        // grab a pointer to the request data
652
+        $this->requestData = $this->context->getRequest()->getRequestData();
653
+    }
654 654
 
655
-	/**
656
-	 * Execute the shutdown procedure for this Dispatcher.
657
-	 *
658
-	 * @author     Sean Kerr <[email protected]>
659
-	 * @since      0.9.0
660
-	 */
661
-	public function shutdown()
662
-	{
663
-	}
655
+    /**
656
+     * Execute the shutdown procedure for this Dispatcher.
657
+     *
658
+     * @author     Sean Kerr <[email protected]>
659
+     * @since      0.9.0
660
+     */
661
+    public function shutdown()
662
+    {
663
+    }
664 664
 
665
-	/**
666
-	 * Indicates whether or not a module has a specific controller.
667
-	 *
668
-	 * @param      string $moduleName A module name.
669
-	 * @param      string $controllerName A view name.
670
-	 *
671
-	 * @return     bool true, if the controller exists, otherwise false.
672
-	 *
673
-	 * @author     David Zülke <[email protected]>
674
-	 * @since      1.0.1
675
-	 */
676
-	public function controllerExists($moduleName, $controllerName)
677
-	{
678
-		return $this->checkControllerFile($moduleName, $controllerName) !== false;
679
-	}
665
+    /**
666
+     * Indicates whether or not a module has a specific controller.
667
+     *
668
+     * @param      string $moduleName A module name.
669
+     * @param      string $controllerName A view name.
670
+     *
671
+     * @return     bool true, if the controller exists, otherwise false.
672
+     *
673
+     * @author     David Zülke <[email protected]>
674
+     * @since      1.0.1
675
+     */
676
+    public function controllerExists($moduleName, $controllerName)
677
+    {
678
+        return $this->checkControllerFile($moduleName, $controllerName) !== false;
679
+    }
680 680
 
681
-	/**
682
-	 * Indicates whether or not a module has a specific view.
683
-	 *
684
-	 * @param      string $moduleName A module name.
685
-	 * @param      string $viewName A view name.
686
-	 *
687
-	 * @return     bool true, if the view exists, otherwise false.
688
-	 *
689
-	 * @author     Sean Kerr <[email protected]>
690
-	 * @since      0.9.0
691
-	 */
692
-	public function viewExists($moduleName, $viewName)
693
-	{
694
-		return $this->checkViewFile($moduleName, $viewName) !== false;
695
-	}
681
+    /**
682
+     * Indicates whether or not a module has a specific view.
683
+     *
684
+     * @param      string $moduleName A module name.
685
+     * @param      string $viewName A view name.
686
+     *
687
+     * @return     bool true, if the view exists, otherwise false.
688
+     *
689
+     * @author     Sean Kerr <[email protected]>
690
+     * @since      0.9.0
691
+     */
692
+    public function viewExists($moduleName, $viewName)
693
+    {
694
+        return $this->checkViewFile($moduleName, $viewName) !== false;
695
+    }
696 696
 	
697
-	/**
698
-	 * Retrieve an Output Type object
699
-	 *
700
-	 * @param      string $name The optional output type name.
701
-	 *
702
-	 * @return     OutputType An Output Type object.
703
-	 *
704
-	 * @author     David Zülke <[email protected]>
705
-	 * @since      0.11.0
706
-	 */
707
-	public function getOutputType($name = null)
708
-	{
709
-		if($name === null) {
710
-			$name = $this->defaultOutputType;
711
-		}
712
-		if(isset($this->outputTypes[$name])) {
713
-			return $this->outputTypes[$name];
714
-		} else {
715
-			throw new AgaviException('Output Type "' . $name . '" has not been configured.');
716
-		}
717
-	}
697
+    /**
698
+     * Retrieve an Output Type object
699
+     *
700
+     * @param      string $name The optional output type name.
701
+     *
702
+     * @return     OutputType An Output Type object.
703
+     *
704
+     * @author     David Zülke <[email protected]>
705
+     * @since      0.11.0
706
+     */
707
+    public function getOutputType($name = null)
708
+    {
709
+        if($name === null) {
710
+            $name = $this->defaultOutputType;
711
+        }
712
+        if(isset($this->outputTypes[$name])) {
713
+            return $this->outputTypes[$name];
714
+        } else {
715
+            throw new AgaviException('Output Type "' . $name . '" has not been configured.');
716
+        }
717
+    }
718 718
 }
719 719
 
720 720
 ?>
721 721
\ No newline at end of file
Please login to merge, or discard this patch.
Spacing   +43 added lines, -43 removed lines patch added patch discarded remove patch
@@ -111,7 +111,7 @@  discard block
 block discarded – undo
111 111
 	{
112 112
 		$maxExecutions = $this->getParameter('max_executions');
113 113
 		
114
-		if(++$this->numExecutions > $maxExecutions && $maxExecutions > 0) {
114
+		if (++$this->numExecutions > $maxExecutions && $maxExecutions > 0) {
115 115
 			throw new DispatcherException('Too many execution runs have been detected for this Context.');
116 116
 		}
117 117
 	}
@@ -142,11 +142,11 @@  discard block
 block discarded – undo
142 142
 		$container->setModuleName($moduleName);
143 143
 		$container->setControllerName($controllerName);
144 144
 		$container->setRequestData($this->requestData);
145
-		if($arguments !== null) {
145
+		if ($arguments !== null) {
146 146
 			$container->setArguments($arguments);
147 147
 		}
148 148
 		$container->setOutputType($this->context->getDispatcher()->getOutputType($outputType));
149
-		if($requestMethod === null) {
149
+		if ($requestMethod === null) {
150 150
 			$requestMethod = $this->context->getRequest()->getMethod();
151 151
 		}
152 152
 		$container->setRequestMethod($requestMethod);
@@ -165,7 +165,7 @@  discard block
 block discarded – undo
165 165
 	{
166 166
 		$lowerModuleName = strtolower($moduleName);
167 167
 		
168
-		if(null === Config::get('modules.' . $lowerModuleName . '.enabled')) {
168
+		if (null === Config::get('modules.' . $lowerModuleName . '.enabled')) {
169 169
 			// set some defaults first
170 170
 			Config::fromArray(array(
171 171
 				'modules.' . $lowerModuleName . '.agavi.controller.path' => '%core.module_dir%/${moduleName}/controllers/${controllerName}Controller.class.php',
@@ -177,32 +177,32 @@  discard block
 block discarded – undo
177 177
 			));
178 178
 			// include the module configuration
179 179
 			// loaded only once due to the way load() (former import()) works
180
-			if(is_readable(Config::get('core.module_dir') . '/' . $moduleName . '/config/module.xml')) {
180
+			if (is_readable(Config::get('core.module_dir') . '/' . $moduleName . '/config/module.xml')) {
181 181
 				include_once(ConfigCache::checkConfig(Config::get('core.module_dir') . '/' . $moduleName . '/config/module.xml'));
182 182
 			} else {
183 183
 				Config::set('modules.' . $lowerModuleName . '.enabled', true);
184 184
 			}
185 185
 			
186 186
 			$moduleAutoload = Config::get('core.module_dir') . '/' . $moduleName . '/config/autoload.xml';
187
-			if(is_readable($moduleAutoload)) {
187
+			if (is_readable($moduleAutoload)) {
188 188
 				ConfigCache::load($moduleAutoload);
189 189
 			}
190 190
 			
191
-			if(Config::get('modules.' . $lowerModuleName . '.enabled')) {
191
+			if (Config::get('modules.' . $lowerModuleName . '.enabled')) {
192 192
 				$moduleConfigHandlers = Config::get('core.module_dir') . '/' . $moduleName . '/config/config_handlers.xml';
193
-				if(is_readable($moduleConfigHandlers)) {
193
+				if (is_readable($moduleConfigHandlers)) {
194 194
 					ConfigCache::addConfigHandlersFile($moduleConfigHandlers);
195 195
 				}
196 196
 			}
197 197
 		}
198 198
 		
199
-		if(!Config::get('modules.' . $lowerModuleName . '.enabled')) {
199
+		if (!Config::get('modules.' . $lowerModuleName . '.enabled')) {
200 200
 			throw new DisabledModuleException(sprintf('The module "%1$s" is disabled.', $moduleName));
201 201
 		}
202 202
 		
203 203
 		// check for a module config.php
204 204
 		$moduleConfig = Config::get('core.module_dir') . '/' . $moduleName . '/config.php';
205
-		if(is_readable($moduleConfig)) {
205
+		if (is_readable($moduleConfig)) {
206 206
 			require_once($moduleConfig);
207 207
 		}
208 208
 	}
@@ -228,27 +228,27 @@  discard block
 block discarded – undo
228 228
 			$rq = $this->context->getRequest();
229 229
 			$rd = $rq->getRequestData();
230 230
 			
231
-			if($container === null) {
231
+			if ($container === null) {
232 232
 				// match routes and assign returned initial execution container
233 233
 				$container = $this->context->getRouting()->execute();
234 234
 			}
235 235
 			
236
-			if($container instanceof ExecutionContainer) {
236
+			if ($container instanceof ExecutionContainer) {
237 237
 				// merge in any arguments given. they need to have precedence over what the routing found
238
-				if($arguments !== null) {
238
+				if ($arguments !== null) {
239 239
 					$rd->merge($arguments);
240 240
 				}
241 241
 				
242 242
 				// next, we have to see if the routing did anything useful, i.e. whether or not it was enabled.
243 243
 				$moduleName = $container->getModuleName();
244 244
 				$controllerName = $container->getControllerName();
245
-				if(!$moduleName) {
245
+				if (!$moduleName) {
246 246
 					// no module has been specified; that means the routing did not run, as it would otherwise have the 404 controller's module name
247 247
 					
248 248
 					// lets see if our request data has values for module and controller
249 249
 					$ma = $rq->getParameter('module_accessor');
250 250
 					$aa = $rq->getParameter('controller_accessor');
251
-					if($rd->hasParameter($ma) && $rd->hasParameter($aa)) {
251
+					if ($rd->hasParameter($ma) && $rd->hasParameter($aa)) {
252 252
 						// yup. grab those
253 253
 						$moduleName = $rd->getParameter($ma);
254 254
 						$controllerName = $rd->getParameter($aa);
@@ -263,7 +263,7 @@  discard block
 block discarded – undo
263 263
 					$container->setControllerName($controllerName);
264 264
 				}
265 265
 				
266
-				if(!Config::get('core.available', false)) {
266
+				if (!Config::get('core.available', false)) {
267 267
 					$container = $container->createSystemControllerForwardContainer('unavailable');
268 268
 				}
269 269
 				
@@ -280,7 +280,7 @@  discard block
 block discarded – undo
280 280
 				$filterChain->execute($container);
281 281
 				
282 282
 				$response = $container->getResponse();
283
-			} elseif($container instanceof Response) {
283
+			} elseif ($container instanceof Response) {
284 284
 				// the routing returned a response!
285 285
 				$response = $container;
286 286
 				// set $container to null so Exception::render() won't think it is a container if an exception happens later!
@@ -290,13 +290,13 @@  discard block
 block discarded – undo
290 290
 			}
291 291
 			$response->merge($this->response);
292 292
 			
293
-			if($this->getParameter('send_response')) {
293
+			if ($this->getParameter('send_response')) {
294 294
 				$response->send();
295 295
 			}
296 296
 			
297 297
 			return $response;
298 298
 			
299
-		} catch(\Exception $e) {
299
+		} catch (\Exception $e) {
300 300
 			AgaviException::render($e, $this->context, $container);
301 301
 		}
302 302
 	}
@@ -344,7 +344,7 @@  discard block
 block discarded – undo
344 344
 			)
345 345
 		);
346 346
 		
347
-		if(is_readable($file) && substr($controllerName, 0, 1) !== '/') {
347
+		if (is_readable($file) && substr($controllerName, 0, 1) !== '/') {
348 348
 			return $file;
349 349
 		}
350 350
 		
@@ -375,14 +375,14 @@  discard block
 block discarded – undo
375 375
 		
376 376
 		$class = $moduleName . '_' . $longControllerName . 'Controller';
377 377
 		
378
-		if(!class_exists($class)) {
379
-			if(false !== ($file = $this->checkControllerFile($moduleName, $controllerName))) {
378
+		if (!class_exists($class)) {
379
+			if (false !== ($file = $this->checkControllerFile($moduleName, $controllerName))) {
380 380
 				require($file);
381 381
 			} else {
382 382
 				throw new FileNotFoundException(sprintf('Could not find file for Controller "%s" in Module "%s".', $controllerName, $moduleName));
383 383
 			}
384 384
 			
385
-			if(!class_exists($class, false)) {
385
+			if (!class_exists($class, false)) {
386 386
 				throw new ClassNotFoundException(sprintf('Failed to instantiate Controller "%s" in Module "%s" because file "%s" does not contain class "%s".', $controllerName, $moduleName, $file, $class));
387 387
 			}
388 388
 		} 
@@ -434,7 +434,7 @@  discard block
 block discarded – undo
434 434
 			)
435 435
 		);
436 436
 		
437
-		if(is_readable($file) && substr($viewName, 0, 1) !== '/') {
437
+		if (is_readable($file) && substr($viewName, 0, 1) !== '/') {
438 438
 			return $file;
439 439
 		}
440 440
 		
@@ -460,7 +460,7 @@  discard block
 block discarded – undo
460 460
 	{
461 461
 		try {
462 462
 			$this->initializeModule($moduleName);
463
-		} catch(DisabledModuleException $e) {
463
+		} catch (DisabledModuleException $e) {
464 464
 			// views from disabled modules should be usable by definition
465 465
 			// swallow
466 466
 		}
@@ -470,15 +470,15 @@  discard block
 block discarded – undo
470 470
 		
471 471
 		$class = $moduleName . '_' . $longViewName . 'View';
472 472
 		
473
-		if(!class_exists($class)) {
473
+		if (!class_exists($class)) {
474 474
 			
475
-			if(false !== ($file = $this->checkViewFile($moduleName, $viewName))) {
475
+			if (false !== ($file = $this->checkViewFile($moduleName, $viewName))) {
476 476
 				require($file);
477 477
 			} else {
478 478
 				throw new FileNotFoundException(sprintf('Could not find file for View "%s" in Module "%s".', $viewName, $moduleName));
479 479
 			}
480 480
 			
481
-			if(!class_exists($class, false)) {
481
+			if (!class_exists($class, false)) {
482 482
 				throw new ClassNotFoundException(sprintf('Failed to instantiate View "%s" in Module "%s" because file "%s" does not contain class "%s".', $viewName, $moduleName, $file, $class));
483 483
 			}
484 484
 		} 
@@ -521,7 +521,7 @@  discard block
 block discarded – undo
521 521
 		$cfg = Config::get('core.config_dir') . '/output_types.xml';
522 522
 		require(ConfigCache::checkConfig($cfg, $this->context->getName()));
523 523
 		
524
-		if(Config::get('core.use_security', false)) {
524
+		if (Config::get('core.use_security', false)) {
525 525
 			$this->filters['security'] = $this->context->createInstanceFor('security_filter');
526 526
 		}
527 527
 		
@@ -555,7 +555,7 @@  discard block
 block discarded – undo
555 555
 	 */
556 556
 	public function getFilterChain()
557 557
 	{
558
-		if($this->filterChain === null) {
558
+		if ($this->filterChain === null) {
559 559
 			$this->filterChain = $this->context->createInstanceFor('filter_chain');
560 560
 			$this->filterChain->setType(FilterChain::TYPE_GLOBAL);
561 561
 		}
@@ -575,31 +575,31 @@  discard block
 block discarded – undo
575 575
 	 */
576 576
 	public function loadFilters(FilterChain $filterChain, $which = 'global', $module = null)
577 577
 	{
578
-		if($module === null) {
578
+		if ($module === null) {
579 579
 			$module = '*';
580 580
 		}
581 581
 		
582
-		if(($which != 'global' && !isset($this->filters[$which][$module])) || $which == 'global' && $this->filters[$which] == null) {
583
-			if($which == 'global') {
582
+		if (($which != 'global' && !isset($this->filters[$which][$module])) || $which == 'global' && $this->filters[$which] == null) {
583
+			if ($which == 'global') {
584 584
 				$this->filters[$which] = array();
585
-				$filters =& $this->filters[$which];
585
+				$filters = & $this->filters[$which];
586 586
 			} else {
587 587
 				$this->filters[$which][$module] = array();
588
-				$filters =& $this->filters[$which][$module];
588
+				$filters = & $this->filters[$which][$module];
589 589
 			}
590 590
 			$config = ($module == '*' ? Config::get('core.config_dir') : Config::get('core.module_dir') . '/' . $module . '/config') . '/' . $which . '_filters.xml';
591
-			if(is_readable($config)) {
591
+			if (is_readable($config)) {
592 592
 				require(ConfigCache::checkConfig($config, $this->context->getName()));
593 593
 			}
594 594
 		} else {
595
-			if($which == 'global') {
596
-				$filters =& $this->filters[$which];
595
+			if ($which == 'global') {
596
+				$filters = & $this->filters[$which];
597 597
 			} else {
598
-				$filters =& $this->filters[$which][$module];
598
+				$filters = & $this->filters[$which][$module];
599 599
 			}
600 600
 		}
601 601
 		
602
-		foreach($filters as $name => $filter) {
602
+		foreach ($filters as $name => $filter) {
603 603
 			$filterChain->register($filter, $name);
604 604
 		}
605 605
 	}
@@ -618,7 +618,7 @@  discard block
 block discarded – undo
618 618
 	public function modelExists($moduleName, $modelName)
619 619
 	{
620 620
 		$modelName = Toolkit::canonicalName($modelName);
621
-		$file = Config::get('core.module_dir') . '/' . $moduleName . '/models/' . $modelName .	'Model.class.php';
621
+		$file = Config::get('core.module_dir') . '/' . $moduleName . '/models/' . $modelName . 'Model.class.php';
622 622
 		return is_readable($file);
623 623
 	}
624 624
 
@@ -706,10 +706,10 @@  discard block
 block discarded – undo
706 706
 	 */
707 707
 	public function getOutputType($name = null)
708 708
 	{
709
-		if($name === null) {
709
+		if ($name === null) {
710 710
 			$name = $this->defaultOutputType;
711 711
 		}
712
-		if(isset($this->outputTypes[$name])) {
712
+		if (isset($this->outputTypes[$name])) {
713 713
 			return $this->outputTypes[$name];
714 714
 		} else {
715 715
 			throw new AgaviException('Output Type "' . $name . '" has not been configured.');
Please login to merge, or discard this patch.
src/filter/FormPopulationFilter.class.php 2 patches
Unused Use Statements   -1 removed lines patch added patch discarded remove patch
@@ -16,7 +16,6 @@
 block discarded – undo
16 16
 use Agavi\Core\Context;
17 17
 use Agavi\Dispatcher\ExecutionContainer;
18 18
 use Agavi\Exception\AgaviException;
19
-use Agavi\Exception\FilterException;
20 19
 use Agavi\Exception\ParseException;
21 20
 use Agavi\Logging\LoggerInterface;
22 21
 use Agavi\Request\RequestDataHolder;
Please login to merge, or discard this patch.
Indentation   +1001 added lines, -1001 removed lines patch added patch discarded remove patch
@@ -57,25 +57,25 @@  discard block
 block discarded – undo
57 57
  */
58 58
 class FormPopulationFilter extends Filter implements GlobalFilterInterface
59 59
 {
60
-	const ENCODING_UTF_8 = 'utf-8';
60
+    const ENCODING_UTF_8 = 'utf-8';
61 61
 
62
-	const ENCODING_ISO_8859_1 = 'iso-8859-1';
62
+    const ENCODING_ISO_8859_1 = 'iso-8859-1';
63 63
 
64
-	/**
65
-	 * @var        \DOMDocument Our (X)HTML document.
66
-	 */
67
-	protected $doc;
64
+    /**
65
+     * @var        \DOMDocument Our (X)HTML document.
66
+     */
67
+    protected $doc;
68 68
 
69
-	/**
70
-	 * @var        \DOMXPath Our XPath instance for the document.
71
-	 */
72
-	protected $xpath;
69
+    /**
70
+     * @var        \DOMXPath Our XPath instance for the document.
71
+     */
72
+    protected $xpath;
73 73
 
74
-	/**
75
-	 * @var        string The XML NS prefix we're working on with XPath, including
76
-	 *                    a colon (or empty string if document has no NS).
77
-	 */
78
-	protected $xmlnsPrefix = '';
74
+    /**
75
+     * @var        string The XML NS prefix we're working on with XPath, including
76
+     *                    a colon (or empty string if document has no NS).
77
+     */
78
+    protected $xmlnsPrefix = '';
79 79
 
80 80
     /**
81 81
      * Execute this filter.
@@ -88,1018 +88,1018 @@  discard block
 block discarded – undo
88 88
      * @author     David Zülke <[email protected]>
89 89
      * @since      0.11.0
90 90
      */
91
-	public function execute(FilterChain $filterChain, ExecutionContainer $container)
92
-	{
93
-		$filterChain->execute($container);
94
-		$response = $container->getResponse();
95
-
96
-		if(!$response->isContentMutable() || !($output = $response->getContent())) {
97
-			return;
98
-		}
99
-
100
-		$rq = $this->getContext()->getRequest();
101
-
102
-		$cfg = $rq->getAttributes('org.agavi.filter.FormPopulationFilter');
103
-
104
-		$ot = $response->getOutputType();
105
-
106
-		if(is_array($cfg['output_types']) && !in_array($ot->getName(), $cfg['output_types'])) {
107
-			return;
108
-		}
109
-
110
-		if(is_array($cfg['populate']) || $cfg['populate'] instanceof ParameterHolder) {
111
-			$populate = $cfg['populate'];
112
-		} elseif($cfg['populate'] === true || (in_array($container->getRequestMethod(), $cfg['methods']) && $cfg['populate'] !== false)) {
113
-			$populate = $rq->getRequestData();
114
-		} else {
115
-			return;
116
-		}
117
-
118
-		$skip = null;
119
-		if($cfg['skip'] instanceof ParameterHolder) {
120
-			$cfg['skip'] = $cfg['skip']->getParameters();
121
-		} elseif($cfg['skip'] !== null && !is_array($cfg['skip'])) {
122
-			$cfg['skip'] = null;
123
-		}
124
-		if($cfg['skip'] !== null && count($cfg['skip'])) {
125
-			$skip = '/(\A' . str_replace('\[\]', '\[[^\]]*\]', implode('|\A', array_map('preg_quote', $cfg['skip'], array_fill(0, count($cfg['skip']), '/')))) . ')/';
126
-		}
127
-
128
-		if($cfg['force_request_uri'] !== false) {
129
-			$ruri = $cfg['force_request_uri'];
130
-		} else {
131
-			$ruri = $rq->getRequestUri();
132
-		}
133
-		if($cfg['force_request_url'] !== false) {
134
-			$rurl = $cfg['force_request_url'];
135
-		} else {
136
-			$rurl = $rq->getUrl();
137
-		}
138
-
139
-		if(isset($cfg['validation_report']) && $cfg['validation_report'] instanceof ValidationReport) {
140
-			$vr = $cfg['validation_report'];
141
-		} else {
142
-			$vr = $container->getValidationManager()->getReport();
143
-		}
144
-
145
-		$errorMessageRules = array();
146
-		if(isset($cfg['error_messages']) && is_array($cfg['error_messages'])) {
147
-			$errorMessageRules = $cfg['error_messages'];
148
-		}
149
-		$fieldErrorMessageRules = $errorMessageRules;
150
-		if(isset($cfg['field_error_messages']) && is_array($cfg['field_error_messages']) && count($cfg['field_error_messages'])) {
151
-			$fieldErrorMessageRules = $cfg['field_error_messages'];
152
-		}
153
-		$multiFieldErrorMessageRules = $fieldErrorMessageRules;
154
-		if(isset($cfg['multi_field_error_messages']) && is_array($cfg['multi_field_error_messages']) && count($cfg['multi_field_error_messages'])) {
155
-			$multiFieldErrorMessageRules = $cfg['multi_field_error_messages'];
156
-		}
157
-
158
-		$luie = libxml_use_internal_errors(true);
159
-		libxml_clear_errors();
160
-
161
-		$this->doc = new \DOMDocument();
162
-
163
-		$this->doc->substituteEntities = $cfg['dom_substitute_entities'];
164
-		$this->doc->resolveExternals   = $cfg['dom_resolve_externals'];
165
-		$this->doc->validateOnParse    = $cfg['dom_validate_on_parse'];
166
-		$this->doc->preserveWhiteSpace = $cfg['dom_preserve_white_space'];
167
-		$this->doc->formatOutput       = $cfg['dom_format_output'];
168
-
169
-		$xhtml = (preg_match('/<!DOCTYPE[^>]+XHTML[^>]+/', $output) > 0 && strtolower($cfg['force_output_mode']) != 'html') || strtolower($cfg['force_output_mode']) == 'xhtml';
170
-
171
-		$hasXmlProlog = false;
172
-		if($xhtml && preg_match('/^<\?xml[^\?]*\?>/', $output)) {
173
-			$hasXmlProlog = true;
174
-		} elseif($xhtml && preg_match('/;\s*charset=(")?(?P<charset>.+?(?(1)(?=(?<!\\\\)")|($|(?=[;\s]))))(?(1)")/i', $ot->getParameter('http_headers[Content-Type]'), $matches)) {
175
-			// media-type = type "/" subtype *( ";" parameter ), says http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.7
176
-			// add an XML prolog with the char encoding, works around issues with ISO-8859-1 etc
177
-			$output = "<?xml version='1.0' encoding='" . $matches['charset'] . "' ?>\n" . $output;
178
-		}
179
-
180
-		if($xhtml && $cfg['parse_xhtml_as_xml']) {
181
-			$this->doc->loadXML($output);
182
-			$this->xpath = new \DOMXPath($this->doc);
183
-			if($this->doc->documentElement && $this->doc->documentElement->namespaceURI) {
184
-				$this->xpath->registerNamespace('html', $this->doc->documentElement->namespaceURI);
185
-				$this->xmlnsPrefix = 'html:';
186
-			} else {
187
-				$this->xmlnsPrefix = '';
188
-			}
189
-		} else {
190
-			$this->doc->loadHTML($output);
191
-			$this->xpath = new \DOMXPath($this->doc);
192
-			$this->xmlnsPrefix = '';
193
-		}
194
-
195
-		if(libxml_get_last_error() !== false) {
196
-			$errors = array();
197
-			$maxError = LIBXML_ERR_NONE;
198
-			foreach(libxml_get_errors() as $error) {
199
-				$errors[] = sprintf('[%s #%d] Line %d: %s', $error->level == LIBXML_ERR_WARNING ? 'Warning' : ($error->level == LIBXML_ERR_ERROR ? 'Error' : 'Fatal'), $error->code, $error->line, $error->message);
200
-				$maxError = max($maxError, $error->level);
201
-			}
202
-			libxml_clear_errors();
203
-			libxml_use_internal_errors($luie);
204
-			$emsg = sprintf(
205
-				"Form Population Filter encountered the following error%s while parsing the document:\n\n"
206
-				. "%s\n\n"
207
-				. "Non-fatal errors are typically recoverable; you may set the 'ignore_parse_errors' configuration parameter to LIBXML_ERR_WARNING or LIBXML_ERR_ERROR (default) to suppress them.\n"
208
-				. "If you set 'ignore_parse_errors' to LIBXML_ERR_FATAL (recommended for production), Form Population Filter will silently abort execution in the event of fatal errors.\n"
209
-				. "Regardless of the setting, all errors encountered will be logged.",
210
-				count($errors) > 1 ? 's' : '',
211
-				implode("\n", $errors)
212
-			);
213
-			if(Config::get('core.use_logging') && $cfg['log_parse_errors'] !== false && $maxError >= $cfg['log_parse_errors']) {
214
-				$severity = LoggerInterface::INFO;
215
-				switch($maxError) {
216
-					case LIBXML_ERR_WARNING:
217
-						$severity = LoggerInterface::WARN;
218
-						break;
219
-					case LIBXML_ERR_ERROR:
220
-						$severity = LoggerInterface::ERROR;
221
-						break;
222
-					case LIBXML_ERR_FATAL:
223
-						$severity = LoggerInterface::FATAL;
224
-						break;
225
-				}
226
-				$lmsg = $emsg . "\n\nResponse content:\n\n" . $response->getContent();
227
-				$lm = $this->context->getLoggerManager();
228
-				$mc = $lm->getDefaultMessageClass();
229
-				$m = new $mc($lmsg, $severity);
230
-				$lm->log($m, $cfg['logging_logger']);
231
-			}
91
+    public function execute(FilterChain $filterChain, ExecutionContainer $container)
92
+    {
93
+        $filterChain->execute($container);
94
+        $response = $container->getResponse();
95
+
96
+        if(!$response->isContentMutable() || !($output = $response->getContent())) {
97
+            return;
98
+        }
99
+
100
+        $rq = $this->getContext()->getRequest();
101
+
102
+        $cfg = $rq->getAttributes('org.agavi.filter.FormPopulationFilter');
103
+
104
+        $ot = $response->getOutputType();
105
+
106
+        if(is_array($cfg['output_types']) && !in_array($ot->getName(), $cfg['output_types'])) {
107
+            return;
108
+        }
109
+
110
+        if(is_array($cfg['populate']) || $cfg['populate'] instanceof ParameterHolder) {
111
+            $populate = $cfg['populate'];
112
+        } elseif($cfg['populate'] === true || (in_array($container->getRequestMethod(), $cfg['methods']) && $cfg['populate'] !== false)) {
113
+            $populate = $rq->getRequestData();
114
+        } else {
115
+            return;
116
+        }
117
+
118
+        $skip = null;
119
+        if($cfg['skip'] instanceof ParameterHolder) {
120
+            $cfg['skip'] = $cfg['skip']->getParameters();
121
+        } elseif($cfg['skip'] !== null && !is_array($cfg['skip'])) {
122
+            $cfg['skip'] = null;
123
+        }
124
+        if($cfg['skip'] !== null && count($cfg['skip'])) {
125
+            $skip = '/(\A' . str_replace('\[\]', '\[[^\]]*\]', implode('|\A', array_map('preg_quote', $cfg['skip'], array_fill(0, count($cfg['skip']), '/')))) . ')/';
126
+        }
127
+
128
+        if($cfg['force_request_uri'] !== false) {
129
+            $ruri = $cfg['force_request_uri'];
130
+        } else {
131
+            $ruri = $rq->getRequestUri();
132
+        }
133
+        if($cfg['force_request_url'] !== false) {
134
+            $rurl = $cfg['force_request_url'];
135
+        } else {
136
+            $rurl = $rq->getUrl();
137
+        }
138
+
139
+        if(isset($cfg['validation_report']) && $cfg['validation_report'] instanceof ValidationReport) {
140
+            $vr = $cfg['validation_report'];
141
+        } else {
142
+            $vr = $container->getValidationManager()->getReport();
143
+        }
144
+
145
+        $errorMessageRules = array();
146
+        if(isset($cfg['error_messages']) && is_array($cfg['error_messages'])) {
147
+            $errorMessageRules = $cfg['error_messages'];
148
+        }
149
+        $fieldErrorMessageRules = $errorMessageRules;
150
+        if(isset($cfg['field_error_messages']) && is_array($cfg['field_error_messages']) && count($cfg['field_error_messages'])) {
151
+            $fieldErrorMessageRules = $cfg['field_error_messages'];
152
+        }
153
+        $multiFieldErrorMessageRules = $fieldErrorMessageRules;
154
+        if(isset($cfg['multi_field_error_messages']) && is_array($cfg['multi_field_error_messages']) && count($cfg['multi_field_error_messages'])) {
155
+            $multiFieldErrorMessageRules = $cfg['multi_field_error_messages'];
156
+        }
157
+
158
+        $luie = libxml_use_internal_errors(true);
159
+        libxml_clear_errors();
160
+
161
+        $this->doc = new \DOMDocument();
162
+
163
+        $this->doc->substituteEntities = $cfg['dom_substitute_entities'];
164
+        $this->doc->resolveExternals   = $cfg['dom_resolve_externals'];
165
+        $this->doc->validateOnParse    = $cfg['dom_validate_on_parse'];
166
+        $this->doc->preserveWhiteSpace = $cfg['dom_preserve_white_space'];
167
+        $this->doc->formatOutput       = $cfg['dom_format_output'];
168
+
169
+        $xhtml = (preg_match('/<!DOCTYPE[^>]+XHTML[^>]+/', $output) > 0 && strtolower($cfg['force_output_mode']) != 'html') || strtolower($cfg['force_output_mode']) == 'xhtml';
170
+
171
+        $hasXmlProlog = false;
172
+        if($xhtml && preg_match('/^<\?xml[^\?]*\?>/', $output)) {
173
+            $hasXmlProlog = true;
174
+        } elseif($xhtml && preg_match('/;\s*charset=(")?(?P<charset>.+?(?(1)(?=(?<!\\\\)")|($|(?=[;\s]))))(?(1)")/i', $ot->getParameter('http_headers[Content-Type]'), $matches)) {
175
+            // media-type = type "/" subtype *( ";" parameter ), says http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.7
176
+            // add an XML prolog with the char encoding, works around issues with ISO-8859-1 etc
177
+            $output = "<?xml version='1.0' encoding='" . $matches['charset'] . "' ?>\n" . $output;
178
+        }
179
+
180
+        if($xhtml && $cfg['parse_xhtml_as_xml']) {
181
+            $this->doc->loadXML($output);
182
+            $this->xpath = new \DOMXPath($this->doc);
183
+            if($this->doc->documentElement && $this->doc->documentElement->namespaceURI) {
184
+                $this->xpath->registerNamespace('html', $this->doc->documentElement->namespaceURI);
185
+                $this->xmlnsPrefix = 'html:';
186
+            } else {
187
+                $this->xmlnsPrefix = '';
188
+            }
189
+        } else {
190
+            $this->doc->loadHTML($output);
191
+            $this->xpath = new \DOMXPath($this->doc);
192
+            $this->xmlnsPrefix = '';
193
+        }
194
+
195
+        if(libxml_get_last_error() !== false) {
196
+            $errors = array();
197
+            $maxError = LIBXML_ERR_NONE;
198
+            foreach(libxml_get_errors() as $error) {
199
+                $errors[] = sprintf('[%s #%d] Line %d: %s', $error->level == LIBXML_ERR_WARNING ? 'Warning' : ($error->level == LIBXML_ERR_ERROR ? 'Error' : 'Fatal'), $error->code, $error->line, $error->message);
200
+                $maxError = max($maxError, $error->level);
201
+            }
202
+            libxml_clear_errors();
203
+            libxml_use_internal_errors($luie);
204
+            $emsg = sprintf(
205
+                "Form Population Filter encountered the following error%s while parsing the document:\n\n"
206
+                . "%s\n\n"
207
+                . "Non-fatal errors are typically recoverable; you may set the 'ignore_parse_errors' configuration parameter to LIBXML_ERR_WARNING or LIBXML_ERR_ERROR (default) to suppress them.\n"
208
+                . "If you set 'ignore_parse_errors' to LIBXML_ERR_FATAL (recommended for production), Form Population Filter will silently abort execution in the event of fatal errors.\n"
209
+                . "Regardless of the setting, all errors encountered will be logged.",
210
+                count($errors) > 1 ? 's' : '',
211
+                implode("\n", $errors)
212
+            );
213
+            if(Config::get('core.use_logging') && $cfg['log_parse_errors'] !== false && $maxError >= $cfg['log_parse_errors']) {
214
+                $severity = LoggerInterface::INFO;
215
+                switch($maxError) {
216
+                    case LIBXML_ERR_WARNING:
217
+                        $severity = LoggerInterface::WARN;
218
+                        break;
219
+                    case LIBXML_ERR_ERROR:
220
+                        $severity = LoggerInterface::ERROR;
221
+                        break;
222
+                    case LIBXML_ERR_FATAL:
223
+                        $severity = LoggerInterface::FATAL;
224
+                        break;
225
+                }
226
+                $lmsg = $emsg . "\n\nResponse content:\n\n" . $response->getContent();
227
+                $lm = $this->context->getLoggerManager();
228
+                $mc = $lm->getDefaultMessageClass();
229
+                $m = new $mc($lmsg, $severity);
230
+                $lm->log($m, $cfg['logging_logger']);
231
+            }
232 232
 			
233
-			// should we throw an exception, or carry on?
234
-			if($maxError > $cfg['ignore_parse_errors']) {
235
-				throw new ParseException($emsg);
236
-			} elseif($maxError == LIBXML_ERR_FATAL) {
237
-				// for fatal errors, we cannot continue populating, so we must silently abort
238
-				return;
239
-			}
240
-		}
241
-
242
-		libxml_clear_errors();
243
-		libxml_use_internal_errors($luie);
244
-
245
-		$properXhtml = false;
246
-		/** @var \DOMElement $meta */
247
-		foreach($this->xpath->query(sprintf('//%1$shead/%1$smeta', $this->xmlnsPrefix)) as $meta) {
248
-			if(strtolower($meta->getAttribute('http-equiv')) == 'content-type') {
249
-				if($this->doc->encoding === null) {
250
-					// media-type = type "/" subtype *( ";" parameter ), says http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.7
251
-					if(preg_match('/;\s*charset=(")?(?P<charset>.+?(?(1)(?=(?<!\\\\)")|($|(?=[;\s]))))(?(1)")/i', $meta->getAttribute('content'), $matches)) {
252
-						$this->doc->encoding = $matches['charset'];
253
-					} else {
254
-						$this->doc->encoding = self::ENCODING_UTF_8;
255
-					}
256
-				}
257
-				if(strpos($meta->getAttribute('content'), 'application/xhtml+xml') !== false) {
258
-					$properXhtml = true;
259
-				}
260
-				break;
261
-			}
262
-		}
263
-
264
-		if(($encoding = $cfg['force_encoding']) === false) {
265
-			if($this->doc->actualEncoding) {
266
-				$encoding = $this->doc->actualEncoding;
267
-			} elseif($this->doc->encoding) {
268
-				$encoding = $this->doc->encoding;
269
-			} else {
270
-				$encoding = $this->doc->encoding = self::ENCODING_UTF_8;
271
-			}
272
-		} else {
273
-			$this->doc->encoding = $encoding;
274
-		}
275
-		$encoding = strtolower($encoding);
276
-		$utf8 = $encoding == self::ENCODING_UTF_8;
277
-		if(!$utf8 && $encoding != self::ENCODING_ISO_8859_1 && !function_exists('iconv')) {
278
-			throw new AgaviException('No iconv module available, input encoding "' . $encoding . '" cannot be handled.');
279
-		}
280
-
281
-		$base = $this->xpath->query(sprintf('/%1$shtml/%1$shead/%1$sbase[@href]', $this->xmlnsPrefix));
282
-		if($base->length) {
283
-			$baseHref = $base->item(0)->getAttribute('href');
284
-		} else {
285
-			$baseHref = $rq->getUrl();
286
-		}
287
-		$baseHref = substr($baseHref, 0, strrpos($baseHref, '/') + 1);
288
-
289
-		$forms = array();
290
-		if(is_array($populate)) {
291
-			$queries = array();
292
-			foreach($populate as $id => $data) {
293
-				if(is_string($id)) {
294
-					$id = sprintf('@id="%s"', $id);
295
-					if($data === true) {
296
-						// prepend to the array to give re-populates preferential treatment, see #1461
297
-						array_unshift($queries, $id);
298
-					} else {
299
-						$queries[] = $id;
300
-					}
301
-				}
302
-			}
303
-			if($queries) {
304
-				// we must assemble the array by hand as neither '//form[@id="foo"] or //form[@id="bar"]' nor '//form[@id="foo"] || //form[@id="bar"]' will order the elements as given in the query (order of element in the document is used instead and that can be a problem for error insertion, see #1461)
305
-				$forms = array();
306
-				foreach($queries as $query) {
307
-					$form = $this->xpath->query(sprintf('//%1$sform[%2$s]', $this->xmlnsPrefix, $query));
308
-					if($form->length) {
309
-						$forms[] = $form->item(0);
310
-					}
311
-				}
312
-			}
313
-		} else {
314
-			$forms = $this->xpath->query(Toolkit::expandVariables($cfg['forms_xpath'], array('htmlnsPrefix' => $this->xmlnsPrefix)));
315
-		}
316
-
317
-		// an array of all validation incidents; errors inserted for fields or multiple fields will be removed in here
318
-		$allIncidents = $vr->getIncidents();
319
-
320
-		foreach($forms as $form) {
321
-			if($form->tagName == 'form') {
322
-				if($populate instanceof ParameterHolder) {
323
-					$action = preg_replace('/#.*$/', '', trim($form->getAttribute('action')));
324
-					if(!(
325
-						$action == $rurl ||
326
-						(strpos($action, '/') === 0 && preg_replace(array('#/\./#', '#/\.$#', '#[^\./]+/\.\.(/|\z)#', '#/{2,}#'), array('/', '/', '', '/'), $action) == $ruri) ||
327
-						$baseHref . preg_replace(array('#/\./#', '#/\.$#', '#[^\./]+/\.\.(/|\z)#', '#/{2,}#'), array('/', '/', '', '/'), $action) == $rurl
328
-					)) {
329
-						continue;
330
-					}
331
-					$p = $populate;
332
-				} else {
333
-					if(isset($populate[$form->getAttribute('id')])) {
334
-						if($populate[$form->getAttribute('id')] instanceof ParameterHolder) {
335
-							$p = $populate[$form->getAttribute('id')];
336
-						} elseif($populate[$form->getAttribute('id')] === true) {
337
-							$p = $rq->getRequestData();
338
-						} else {
339
-							continue;
340
-						}
341
-					} else {
342
-						continue;
343
-					}
344
-				}
345
-			} else {
346
-				if($populate === true) {
347
-					$p = $rq->getRequestData();
348
-				} else {
349
-					$p = $populate;
350
-				}
351
-			}
352
-
353
-			// our array for remembering foo[] field's indices
354
-			$remember = array();
355
-
356
-			// build the XPath query
357
-			// we select descendants of the given form
358
-			// as well as any element in the document associated with the form using a "form" attribute that contains the ID of the current form
359
-			// provided they match the following criteria:
360
-			// * <textarea> with a "name" attribute
361
-			// * <select> with a "name" attribute
362
-			// * <button type="submit"> with a "name" attribute
363
-			// * <input> with a "name" attribute except for the following:
364
-			//  * <input type="checkbox"> elements with a "name" attribute that contains the character sequence "[]" and no "value" attribute
365
-			//  * <input type="hidden"> unless config option "include_hidden_inputs" is true (defaults to true)
366
-			$query = sprintf('
233
+            // should we throw an exception, or carry on?
234
+            if($maxError > $cfg['ignore_parse_errors']) {
235
+                throw new ParseException($emsg);
236
+            } elseif($maxError == LIBXML_ERR_FATAL) {
237
+                // for fatal errors, we cannot continue populating, so we must silently abort
238
+                return;
239
+            }
240
+        }
241
+
242
+        libxml_clear_errors();
243
+        libxml_use_internal_errors($luie);
244
+
245
+        $properXhtml = false;
246
+        /** @var \DOMElement $meta */
247
+        foreach($this->xpath->query(sprintf('//%1$shead/%1$smeta', $this->xmlnsPrefix)) as $meta) {
248
+            if(strtolower($meta->getAttribute('http-equiv')) == 'content-type') {
249
+                if($this->doc->encoding === null) {
250
+                    // media-type = type "/" subtype *( ";" parameter ), says http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.7
251
+                    if(preg_match('/;\s*charset=(")?(?P<charset>.+?(?(1)(?=(?<!\\\\)")|($|(?=[;\s]))))(?(1)")/i', $meta->getAttribute('content'), $matches)) {
252
+                        $this->doc->encoding = $matches['charset'];
253
+                    } else {
254
+                        $this->doc->encoding = self::ENCODING_UTF_8;
255
+                    }
256
+                }
257
+                if(strpos($meta->getAttribute('content'), 'application/xhtml+xml') !== false) {
258
+                    $properXhtml = true;
259
+                }
260
+                break;
261
+            }
262
+        }
263
+
264
+        if(($encoding = $cfg['force_encoding']) === false) {
265
+            if($this->doc->actualEncoding) {
266
+                $encoding = $this->doc->actualEncoding;
267
+            } elseif($this->doc->encoding) {
268
+                $encoding = $this->doc->encoding;
269
+            } else {
270
+                $encoding = $this->doc->encoding = self::ENCODING_UTF_8;
271
+            }
272
+        } else {
273
+            $this->doc->encoding = $encoding;
274
+        }
275
+        $encoding = strtolower($encoding);
276
+        $utf8 = $encoding == self::ENCODING_UTF_8;
277
+        if(!$utf8 && $encoding != self::ENCODING_ISO_8859_1 && !function_exists('iconv')) {
278
+            throw new AgaviException('No iconv module available, input encoding "' . $encoding . '" cannot be handled.');
279
+        }
280
+
281
+        $base = $this->xpath->query(sprintf('/%1$shtml/%1$shead/%1$sbase[@href]', $this->xmlnsPrefix));
282
+        if($base->length) {
283
+            $baseHref = $base->item(0)->getAttribute('href');
284
+        } else {
285
+            $baseHref = $rq->getUrl();
286
+        }
287
+        $baseHref = substr($baseHref, 0, strrpos($baseHref, '/') + 1);
288
+
289
+        $forms = array();
290
+        if(is_array($populate)) {
291
+            $queries = array();
292
+            foreach($populate as $id => $data) {
293
+                if(is_string($id)) {
294
+                    $id = sprintf('@id="%s"', $id);
295
+                    if($data === true) {
296
+                        // prepend to the array to give re-populates preferential treatment, see #1461
297
+                        array_unshift($queries, $id);
298
+                    } else {
299
+                        $queries[] = $id;
300
+                    }
301
+                }
302
+            }
303
+            if($queries) {
304
+                // we must assemble the array by hand as neither '//form[@id="foo"] or //form[@id="bar"]' nor '//form[@id="foo"] || //form[@id="bar"]' will order the elements as given in the query (order of element in the document is used instead and that can be a problem for error insertion, see #1461)
305
+                $forms = array();
306
+                foreach($queries as $query) {
307
+                    $form = $this->xpath->query(sprintf('//%1$sform[%2$s]', $this->xmlnsPrefix, $query));
308
+                    if($form->length) {
309
+                        $forms[] = $form->item(0);
310
+                    }
311
+                }
312
+            }
313
+        } else {
314
+            $forms = $this->xpath->query(Toolkit::expandVariables($cfg['forms_xpath'], array('htmlnsPrefix' => $this->xmlnsPrefix)));
315
+        }
316
+
317
+        // an array of all validation incidents; errors inserted for fields or multiple fields will be removed in here
318
+        $allIncidents = $vr->getIncidents();
319
+
320
+        foreach($forms as $form) {
321
+            if($form->tagName == 'form') {
322
+                if($populate instanceof ParameterHolder) {
323
+                    $action = preg_replace('/#.*$/', '', trim($form->getAttribute('action')));
324
+                    if(!(
325
+                        $action == $rurl ||
326
+                        (strpos($action, '/') === 0 && preg_replace(array('#/\./#', '#/\.$#', '#[^\./]+/\.\.(/|\z)#', '#/{2,}#'), array('/', '/', '', '/'), $action) == $ruri) ||
327
+                        $baseHref . preg_replace(array('#/\./#', '#/\.$#', '#[^\./]+/\.\.(/|\z)#', '#/{2,}#'), array('/', '/', '', '/'), $action) == $rurl
328
+                    )) {
329
+                        continue;
330
+                    }
331
+                    $p = $populate;
332
+                } else {
333
+                    if(isset($populate[$form->getAttribute('id')])) {
334
+                        if($populate[$form->getAttribute('id')] instanceof ParameterHolder) {
335
+                            $p = $populate[$form->getAttribute('id')];
336
+                        } elseif($populate[$form->getAttribute('id')] === true) {
337
+                            $p = $rq->getRequestData();
338
+                        } else {
339
+                            continue;
340
+                        }
341
+                    } else {
342
+                        continue;
343
+                    }
344
+                }
345
+            } else {
346
+                if($populate === true) {
347
+                    $p = $rq->getRequestData();
348
+                } else {
349
+                    $p = $populate;
350
+                }
351
+            }
352
+
353
+            // our array for remembering foo[] field's indices
354
+            $remember = array();
355
+
356
+            // build the XPath query
357
+            // we select descendants of the given form
358
+            // as well as any element in the document associated with the form using a "form" attribute that contains the ID of the current form
359
+            // provided they match the following criteria:
360
+            // * <textarea> with a "name" attribute
361
+            // * <select> with a "name" attribute
362
+            // * <button type="submit"> with a "name" attribute
363
+            // * <input> with a "name" attribute except for the following:
364
+            //  * <input type="checkbox"> elements with a "name" attribute that contains the character sequence "[]" and no "value" attribute
365
+            //  * <input type="hidden"> unless config option "include_hidden_inputs" is true (defaults to true)
366
+            $query = sprintf('
367 367
 				descendant::%1$stextarea[@name] |
368 368
 				descendant::%1$sselect[@name] |
369 369
 				descendant::%1$sbutton[@name and @type="submit"] |
370 370
 				descendant::%1$sinput[@name and (not(@type="checkbox") or (not(contains(@name, "[]")) or (contains(@name, "[]") and @value)))]',
371
-				$this->xmlnsPrefix
372
-			);
371
+                $this->xmlnsPrefix
372
+            );
373 373
 			
374
-			if(($formId = $form->hasAttribute('id')) != "") {
375
-				// find elements associated with this form as well
376
-				$query .= sprintf(' |
374
+            if(($formId = $form->hasAttribute('id')) != "") {
375
+                // find elements associated with this form as well
376
+                $query .= sprintf(' |
377 377
 					//%1$stextarea[@form="%2$s" and @name] |
378 378
 					//%1$sselect[@form="%2$s" and @name] |
379 379
 					//%1$sbutton[@form="%2$s" and @name and @type="submit"] |
380 380
 					//%1$sinput[@form="%2$s" and @name and (not(@type="checkbox") or (not(contains(@name, "[]")) or (contains(@name, "[]") and @value)))]',
381
-					$this->xmlnsPrefix,
382
-					$formId
383
-				);
384
-			}
381
+                    $this->xmlnsPrefix,
382
+                    $formId
383
+                );
384
+            }
385 385
 			
386
-			foreach($this->xpath->query($query, $form) as $element) {
387
-
388
-				$pname = $name = $element->getAttribute('name');
389
-
390
-				$multiple = $element->nodeName == 'select' && $element->hasAttribute('multiple');
391
-
392
-				$checkValue = false;
393
-				if($element->getAttribute('type') == 'checkbox' || $element->getAttribute('type') == 'radio') {
394
-					if(($pos = strpos($pname, '[]')) && ($pos + 2 != strlen($pname))) {
395
-						// foo[][3] checkboxes etc not possible, [] must occur only once and at the end
396
-						continue;
397
-					} elseif($pos !== false) {
398
-						$checkValue = true;
399
-						$pname = substr($pname, 0, $pos);
400
-					}
401
-				}
402
-				if(preg_match_all('/([^\[]+)?(?:\[([^\]]*)\])/', $pname, $matches)) {
403
-					$pname = $matches[1][0];
404
-
405
-					if($multiple) {
406
-						$count = count($matches[2]) - 1;
407
-					} else {
408
-						$count = count($matches[2]);
409
-					}
410
-					for($i = 0; $i < $count; $i++) {
411
-						$val = $matches[2][$i];
412
-						if((string)$matches[2][$i] === (string)(int)$matches[2][$i]) {
413
-							$val = (int)$val;
414
-						}
415
-						if(!isset($remember[$pname])) {
416
-							$add = ($val !== "" ? $val : 0);
417
-							if(is_int($add)) {
418
-								$remember[$pname] = $add;
419
-							}
420
-						} else {
421
-							if($val !== "") {
422
-								$add = $val;
423
-								if(is_int($val) && $add > $remember[$pname]) {
424
-									$remember[$pname] = $add;
425
-								}
426
-							} else {
427
-								$add = ++$remember[$pname];
428
-							}
429
-						}
430
-						$pname .= '[' . $add . ']';
431
-					}
432
-				}
433
-
434
-				if(!$utf8) {
435
-					$pname = $this->fromUtf8($pname, $encoding);
436
-				}
437
-
438
-				if($skip !== null && preg_match($skip, $pname . ($checkValue ? '[]' : ''))) {
439
-					// skip field
440
-					continue;
441
-				}
442
-
443
-				$argument = new ValidationArgument(
444
-					$pname,
445
-					($element->nodeName == 'input' && $element->getAttribute('type') == 'file')
446
-						? WebRequestDataHolder::SOURCE_FILES
447
-						: RequestDataHolder::SOURCE_PARAMETERS
448
-				);
386
+            foreach($this->xpath->query($query, $form) as $element) {
387
+
388
+                $pname = $name = $element->getAttribute('name');
389
+
390
+                $multiple = $element->nodeName == 'select' && $element->hasAttribute('multiple');
391
+
392
+                $checkValue = false;
393
+                if($element->getAttribute('type') == 'checkbox' || $element->getAttribute('type') == 'radio') {
394
+                    if(($pos = strpos($pname, '[]')) && ($pos + 2 != strlen($pname))) {
395
+                        // foo[][3] checkboxes etc not possible, [] must occur only once and at the end
396
+                        continue;
397
+                    } elseif($pos !== false) {
398
+                        $checkValue = true;
399
+                        $pname = substr($pname, 0, $pos);
400
+                    }
401
+                }
402
+                if(preg_match_all('/([^\[]+)?(?:\[([^\]]*)\])/', $pname, $matches)) {
403
+                    $pname = $matches[1][0];
404
+
405
+                    if($multiple) {
406
+                        $count = count($matches[2]) - 1;
407
+                    } else {
408
+                        $count = count($matches[2]);
409
+                    }
410
+                    for($i = 0; $i < $count; $i++) {
411
+                        $val = $matches[2][$i];
412
+                        if((string)$matches[2][$i] === (string)(int)$matches[2][$i]) {
413
+                            $val = (int)$val;
414
+                        }
415
+                        if(!isset($remember[$pname])) {
416
+                            $add = ($val !== "" ? $val : 0);
417
+                            if(is_int($add)) {
418
+                                $remember[$pname] = $add;
419
+                            }
420
+                        } else {
421
+                            if($val !== "") {
422
+                                $add = $val;
423
+                                if(is_int($val) && $add > $remember[$pname]) {
424
+                                    $remember[$pname] = $add;
425
+                                }
426
+                            } else {
427
+                                $add = ++$remember[$pname];
428
+                            }
429
+                        }
430
+                        $pname .= '[' . $add . ']';
431
+                    }
432
+                }
433
+
434
+                if(!$utf8) {
435
+                    $pname = $this->fromUtf8($pname, $encoding);
436
+                }
437
+
438
+                if($skip !== null && preg_match($skip, $pname . ($checkValue ? '[]' : ''))) {
439
+                    // skip field
440
+                    continue;
441
+                }
442
+
443
+                $argument = new ValidationArgument(
444
+                    $pname,
445
+                    ($element->nodeName == 'input' && $element->getAttribute('type') == 'file')
446
+                        ? WebRequestDataHolder::SOURCE_FILES
447
+                        : RequestDataHolder::SOURCE_PARAMETERS
448
+                );
449 449
 				
450
-				// there's an error with the element's name in the request? good. let's give the baby a class!
451
-				if($vr->getAuthoritativeArgumentSeverity($argument) > Validator::SILENT) {
452
-					// a collection of all elements that need an error class
453
-					$errorClassElements = array();
454
-					// the element itself of course
455
-					$errorClassElements[] = $element;
456
-					// all implicit labels
457
-					foreach($this->xpath->query(sprintf('ancestor::%1$slabel[not(@for)]', $this->xmlnsPrefix), $element) as $label) {
458
-						$errorClassElements[] = $label;
459
-					}
460
-					// and all explicit labels
461
-					if(($id = $element->getAttribute('id')) != '') {
462
-						// we use // and not descendant: because it doesn't have to be a child of the form element
463
-						foreach($this->xpath->query(sprintf('//%1$slabel[@for="%2$s"]', $this->xmlnsPrefix, $id), $form) as $label) {
464
-							$errorClassElements[] = $label;
465
-						}
466
-					}
467
-
468
-					// now loop over all those elements and assign the class
469
-					foreach($errorClassElements as $errorClassElement) {
470
-						// go over all the elements in the error class map
471
-						foreach($cfg['error_class_map'] as $xpathExpression => $errorClassName) {
472
-							// evaluate each xpath expression
473
-							$errorClassResults = $this->xpath->query(Toolkit::expandVariables($xpathExpression, array('htmlnsPrefix' => $this->xmlnsPrefix)), $errorClassElement);
474
-							if($errorClassResults && $errorClassResults->length) {
475
-								// we have results. the xpath expressions are used to locale the actual elements we set the error class on - doesn't necessarily have to be the erroneous element or the label!
476
-								foreach($errorClassResults as $errorClassDestinationElement) {
477
-									$errorClassDestinationElement->setAttribute('class', preg_replace('/\s*$/', ' ' . $errorClassName, $errorClassDestinationElement->getAttribute('class')));
478
-								}
450
+                // there's an error with the element's name in the request? good. let's give the baby a class!
451
+                if($vr->getAuthoritativeArgumentSeverity($argument) > Validator::SILENT) {
452
+                    // a collection of all elements that need an error class
453
+                    $errorClassElements = array();
454
+                    // the element itself of course
455
+                    $errorClassElements[] = $element;
456
+                    // all implicit labels
457
+                    foreach($this->xpath->query(sprintf('ancestor::%1$slabel[not(@for)]', $this->xmlnsPrefix), $element) as $label) {
458
+                        $errorClassElements[] = $label;
459
+                    }
460
+                    // and all explicit labels
461
+                    if(($id = $element->getAttribute('id')) != '') {
462
+                        // we use // and not descendant: because it doesn't have to be a child of the form element
463
+                        foreach($this->xpath->query(sprintf('//%1$slabel[@for="%2$s"]', $this->xmlnsPrefix, $id), $form) as $label) {
464
+                            $errorClassElements[] = $label;
465
+                        }
466
+                    }
467
+
468
+                    // now loop over all those elements and assign the class
469
+                    foreach($errorClassElements as $errorClassElement) {
470
+                        // go over all the elements in the error class map
471
+                        foreach($cfg['error_class_map'] as $xpathExpression => $errorClassName) {
472
+                            // evaluate each xpath expression
473
+                            $errorClassResults = $this->xpath->query(Toolkit::expandVariables($xpathExpression, array('htmlnsPrefix' => $this->xmlnsPrefix)), $errorClassElement);
474
+                            if($errorClassResults && $errorClassResults->length) {
475
+                                // we have results. the xpath expressions are used to locale the actual elements we set the error class on - doesn't necessarily have to be the erroneous element or the label!
476
+                                foreach($errorClassResults as $errorClassDestinationElement) {
477
+                                    $errorClassDestinationElement->setAttribute('class', preg_replace('/\s*$/', ' ' . $errorClassName, $errorClassDestinationElement->getAttribute('class')));
478
+                                }
479 479
 								
480
-								// and break the foreach, our expression matched after all - no need to look further
481
-								break;
482
-							}
483
-						}
484
-					}
485
-
486
-					// up next: the error messages
487
-					$fieldIncidents = array();
488
-					$multiFieldIncidents = array();
489
-					// grab all incidents for this field
490
-					foreach($vr->byArgument($argument)->getIncidents() as $incident) {
491
-						if(($incidentKey = array_search($incident, $allIncidents, true)) !== false) {
492
-							// does this one have more than one field?
493
-							// and is it really more than one parameter or file, not a cookie or header?
494
-							$incidentArgumentCount = 0;
495
-							$incidentArguments = $incident->getArguments();
496
-							foreach($incidentArguments as $incidentArgument) {
497
-								if(in_array($incidentArgument->getSource(), array(WebRequestDataHolder::SOURCE_FILES, RequestDataHolder::SOURCE_PARAMETERS))) {
498
-									$incidentArgumentCount++;
499
-								}
500
-							}
501
-							if($incidentArgumentCount > 1) {
502
-								$multiFieldIncidents[] = $incident;
503
-							} else {
504
-								$fieldIncidents[] = $incident;
505
-							}
506
-							// remove it from the list of all incidents
507
-							unset($allIncidents[$incidentKey]);
508
-						}
509
-					}
510
-					// 1) insert error messages that are specific to this field
511
-					if(!$this->insertErrorMessages($element, $fieldErrorMessageRules, $fieldIncidents)) {
512
-						$allIncidents = array_merge($allIncidents, $fieldIncidents);
513
-					}
514
-					// 2) insert error messages that belong to multiple fields (including this one), if that message was not inserted before
515
-					if(!$this->insertErrorMessages($element, $multiFieldErrorMessageRules, $multiFieldIncidents)) {
516
-						$allIncidents = array_merge($allIncidents, $multiFieldIncidents);
517
-					}
518
-				}
519
-
520
-				// FPF only handles "normal" values, as file inputs cannot be re-populated, so getParameter() with no source-specific stuff is fine here
521
-				$value = $p->getParameter($pname);
522
-
523
-				if(is_array($value) && !($element->nodeName == 'select' || $checkValue)) {
524
-					// name didn't match exactly. skip.
525
-					continue;
526
-				}
527
-
528
-				if(is_bool($value)) {
529
-					$value = (string)(int)$value;
530
-				} elseif(!$utf8) {
531
-					$value = $this->toUtf8($value, $encoding);
532
-				} else {
533
-					if(is_array($value)) {
534
-						$value = array_map('strval', $value);
535
-					} else {
536
-						$value = (string) $value;
537
-					}
538
-				}
539
-
540
-				if($element->nodeName == 'input') {
541
-					$inputType = $element->getAttribute('type');
542
-
543
-					if($inputType == 'checkbox' || $inputType == 'radio') {
544
-
545
-						// checkboxes and radios
546
-						$element->removeAttribute('checked');
547
-
548
-						if($checkValue && is_array($value)) {
549
-							$eValue = $element->getAttribute('value');
550
-							if(!$utf8) {
551
-								$eValue = $this->fromUtf8($eValue, $encoding);
552
-							}
553
-							if(!in_array($eValue, $value)) {
554
-								continue;
555
-							} else {
556
-								$element->setAttribute('checked', 'checked');
557
-							}
558
-						} elseif($p->hasParameter($pname) && (($element->hasAttribute('value') && $element->getAttribute('value') == $value) || (!$element->hasAttribute('value') && $p->getParameter($pname)))) {
559
-							$element->setAttribute('checked', 'checked');
560
-						}
561
-
562
-					} elseif($inputType != 'button' && $inputType != 'submit') {
480
+                                // and break the foreach, our expression matched after all - no need to look further
481
+                                break;
482
+                            }
483
+                        }
484
+                    }
485
+
486
+                    // up next: the error messages
487
+                    $fieldIncidents = array();
488
+                    $multiFieldIncidents = array();
489
+                    // grab all incidents for this field
490
+                    foreach($vr->byArgument($argument)->getIncidents() as $incident) {
491
+                        if(($incidentKey = array_search($incident, $allIncidents, true)) !== false) {
492
+                            // does this one have more than one field?
493
+                            // and is it really more than one parameter or file, not a cookie or header?
494
+                            $incidentArgumentCount = 0;
495
+                            $incidentArguments = $incident->getArguments();
496
+                            foreach($incidentArguments as $incidentArgument) {
497
+                                if(in_array($incidentArgument->getSource(), array(WebRequestDataHolder::SOURCE_FILES, RequestDataHolder::SOURCE_PARAMETERS))) {
498
+                                    $incidentArgumentCount++;
499
+                                }
500
+                            }
501
+                            if($incidentArgumentCount > 1) {
502
+                                $multiFieldIncidents[] = $incident;
503
+                            } else {
504
+                                $fieldIncidents[] = $incident;
505
+                            }
506
+                            // remove it from the list of all incidents
507
+                            unset($allIncidents[$incidentKey]);
508
+                        }
509
+                    }
510
+                    // 1) insert error messages that are specific to this field
511
+                    if(!$this->insertErrorMessages($element, $fieldErrorMessageRules, $fieldIncidents)) {
512
+                        $allIncidents = array_merge($allIncidents, $fieldIncidents);
513
+                    }
514
+                    // 2) insert error messages that belong to multiple fields (including this one), if that message was not inserted before
515
+                    if(!$this->insertErrorMessages($element, $multiFieldErrorMessageRules, $multiFieldIncidents)) {
516
+                        $allIncidents = array_merge($allIncidents, $multiFieldIncidents);
517
+                    }
518
+                }
519
+
520
+                // FPF only handles "normal" values, as file inputs cannot be re-populated, so getParameter() with no source-specific stuff is fine here
521
+                $value = $p->getParameter($pname);
522
+
523
+                if(is_array($value) && !($element->nodeName == 'select' || $checkValue)) {
524
+                    // name didn't match exactly. skip.
525
+                    continue;
526
+                }
527
+
528
+                if(is_bool($value)) {
529
+                    $value = (string)(int)$value;
530
+                } elseif(!$utf8) {
531
+                    $value = $this->toUtf8($value, $encoding);
532
+                } else {
533
+                    if(is_array($value)) {
534
+                        $value = array_map('strval', $value);
535
+                    } else {
536
+                        $value = (string) $value;
537
+                    }
538
+                }
539
+
540
+                if($element->nodeName == 'input') {
541
+                    $inputType = $element->getAttribute('type');
542
+
543
+                    if($inputType == 'checkbox' || $inputType == 'radio') {
544
+
545
+                        // checkboxes and radios
546
+                        $element->removeAttribute('checked');
547
+
548
+                        if($checkValue && is_array($value)) {
549
+                            $eValue = $element->getAttribute('value');
550
+                            if(!$utf8) {
551
+                                $eValue = $this->fromUtf8($eValue, $encoding);
552
+                            }
553
+                            if(!in_array($eValue, $value)) {
554
+                                continue;
555
+                            } else {
556
+                                $element->setAttribute('checked', 'checked');
557
+                            }
558
+                        } elseif($p->hasParameter($pname) && (($element->hasAttribute('value') && $element->getAttribute('value') == $value) || (!$element->hasAttribute('value') && $p->getParameter($pname)))) {
559
+                            $element->setAttribute('checked', 'checked');
560
+                        }
561
+
562
+                    } elseif($inputType != 'button' && $inputType != 'submit') {
563 563
 						
564
-						// everything else
564
+                        // everything else
565 565
 						
566
-						// unless "include_hidden_inputs" is false and it's a hidden input...
567
-						if($cfg['include_hidden_inputs'] || $inputType != 'hidden') {
568
-							// remove original value
569
-							$element->removeAttribute('value');
566
+                        // unless "include_hidden_inputs" is false and it's a hidden input...
567
+                        if($cfg['include_hidden_inputs'] || $inputType != 'hidden') {
568
+                            // remove original value
569
+                            $element->removeAttribute('value');
570 570
 							
571
-							// and set a new one if it's there and unless it's a password field (or we actually want to refill those)
572
-							if($p->hasParameter($pname) && ($cfg['include_password_inputs'] || $inputType != 'password')) {
573
-								$element->setAttribute('value', $value);
574
-							}
575
-						}
576
-					}
577
-
578
-				} elseif($element->nodeName == 'select') {
579
-					// select elements
580
-					// yes, we still use XPath because there could be OPTGROUPs
581
-					foreach($this->xpath->query(sprintf('descendant::%1$soption', $this->xmlnsPrefix), $element) as $option) {
582
-						$option->removeAttribute('selected');
583
-						if($p->hasParameter($pname) && ($option->getAttribute('value') === $value || ($multiple && is_array($value) && in_array($option->getAttribute('value'), $value)))) {
584
-							$option->setAttribute('selected', 'selected');
585
-						}
586
-					}
587
-
588
-				} elseif($element->nodeName == 'textarea') {
589
-
590
-					// textareas
591
-					foreach($element->childNodes as $cn) {
592
-						// remove all child nodes (= text nodes)
593
-						$element->removeChild($cn);
594
-					}
595
-					// append a new text node
596
-					if($xhtml && $properXhtml) {
597
-						$element->appendChild($this->doc->createCDATASection($value));
598
-					} else {
599
-						$element->appendChild($this->doc->createTextNode($value));
600
-					}
601
-				}
602
-
603
-			}
604
-
605
-			// now output the remaining incidents
606
-			// might include errors for cookies, headers and whatnot, but that is okay
607
-			if($this->insertErrorMessages($form, $errorMessageRules, $allIncidents)) {
608
-				$allIncidents = array();
609
-			}
610
-		}
611
-
612
-		$rq->setAttribute('orphaned_errors', $allIncidents, 'org.agavi.filter.FormPopulationFilter');
613
-
614
-		if($xhtml) {
615
-			$firstError = null;
616
-
617
-			if(!$cfg['parse_xhtml_as_xml']) {
618
-				// workaround for a bug in dom or something that results in two xmlns attributes being generated for the <html> element
619
-				// attributes must be removed and created again
620
-				// and don't change the DOMNodeList in the foreach!
621
-				$remove = array();
622
-				$reset = array();
623
-				foreach($this->doc->documentElement->attributes as $attribute) {
624
-					// remember to remove the node
625
-					$remove[] = $attribute;
626
-					// not for the xmlns attribute itself
627
-					if($attribute->nodeName != 'xmlns') {
628
-						// can't do $attribute->prefix. we're in HTML parsing mode, remember? even if there is a prefix, the attribute node will not have a namespace
629
-						$attributeNameParts = explode(':', $attribute->nodeName);
630
-						if(isset($attributeNameParts[1])) {
631
-							// it's a namespaced node
632
-							$attributeNamespaceUri = $attribute->parentNode->lookupNamespaceURI($attributeNameParts[0]);
633
-							if($attributeNamespaceUri) {
634
-								// it is an attribute, for which the namespace is known internally (even though we're in HTML mode), typically xml: or xmlns:.
635
-								// so we need to create a new node, in the right namespace
636
-								$attributeCopy = $this->doc->createAttributeNS($attributeNamespaceUri, $attribute->nodeName);
637
-							} else {
638
-								// it's a foo:bar node - just copy it over
639
-								$attributeCopy = $attribute;
640
-							}
641
-						} else {
642
-							// no namespace on this node, copy it
643
-							$attributeCopy = $attribute;
644
-						}
645
-						// don't forget the attribute value
646
-						$attributeCopy->nodeValue = $attribute->nodeValue;
647
-						// and remember to set this attribute later
648
-						$reset[] = $attributeCopy;
649
-					}
650
-				}
571
+                            // and set a new one if it's there and unless it's a password field (or we actually want to refill those)
572
+                            if($p->hasParameter($pname) && ($cfg['include_password_inputs'] || $inputType != 'password')) {
573
+                                $element->setAttribute('value', $value);
574
+                            }
575
+                        }
576
+                    }
577
+
578
+                } elseif($element->nodeName == 'select') {
579
+                    // select elements
580
+                    // yes, we still use XPath because there could be OPTGROUPs
581
+                    foreach($this->xpath->query(sprintf('descendant::%1$soption', $this->xmlnsPrefix), $element) as $option) {
582
+                        $option->removeAttribute('selected');
583
+                        if($p->hasParameter($pname) && ($option->getAttribute('value') === $value || ($multiple && is_array($value) && in_array($option->getAttribute('value'), $value)))) {
584
+                            $option->setAttribute('selected', 'selected');
585
+                        }
586
+                    }
587
+
588
+                } elseif($element->nodeName == 'textarea') {
589
+
590
+                    // textareas
591
+                    foreach($element->childNodes as $cn) {
592
+                        // remove all child nodes (= text nodes)
593
+                        $element->removeChild($cn);
594
+                    }
595
+                    // append a new text node
596
+                    if($xhtml && $properXhtml) {
597
+                        $element->appendChild($this->doc->createCDATASection($value));
598
+                    } else {
599
+                        $element->appendChild($this->doc->createTextNode($value));
600
+                    }
601
+                }
602
+
603
+            }
604
+
605
+            // now output the remaining incidents
606
+            // might include errors for cookies, headers and whatnot, but that is okay
607
+            if($this->insertErrorMessages($form, $errorMessageRules, $allIncidents)) {
608
+                $allIncidents = array();
609
+            }
610
+        }
611
+
612
+        $rq->setAttribute('orphaned_errors', $allIncidents, 'org.agavi.filter.FormPopulationFilter');
613
+
614
+        if($xhtml) {
615
+            $firstError = null;
616
+
617
+            if(!$cfg['parse_xhtml_as_xml']) {
618
+                // workaround for a bug in dom or something that results in two xmlns attributes being generated for the <html> element
619
+                // attributes must be removed and created again
620
+                // and don't change the DOMNodeList in the foreach!
621
+                $remove = array();
622
+                $reset = array();
623
+                foreach($this->doc->documentElement->attributes as $attribute) {
624
+                    // remember to remove the node
625
+                    $remove[] = $attribute;
626
+                    // not for the xmlns attribute itself
627
+                    if($attribute->nodeName != 'xmlns') {
628
+                        // can't do $attribute->prefix. we're in HTML parsing mode, remember? even if there is a prefix, the attribute node will not have a namespace
629
+                        $attributeNameParts = explode(':', $attribute->nodeName);
630
+                        if(isset($attributeNameParts[1])) {
631
+                            // it's a namespaced node
632
+                            $attributeNamespaceUri = $attribute->parentNode->lookupNamespaceURI($attributeNameParts[0]);
633
+                            if($attributeNamespaceUri) {
634
+                                // it is an attribute, for which the namespace is known internally (even though we're in HTML mode), typically xml: or xmlns:.
635
+                                // so we need to create a new node, in the right namespace
636
+                                $attributeCopy = $this->doc->createAttributeNS($attributeNamespaceUri, $attribute->nodeName);
637
+                            } else {
638
+                                // it's a foo:bar node - just copy it over
639
+                                $attributeCopy = $attribute;
640
+                            }
641
+                        } else {
642
+                            // no namespace on this node, copy it
643
+                            $attributeCopy = $attribute;
644
+                        }
645
+                        // don't forget the attribute value
646
+                        $attributeCopy->nodeValue = $attribute->nodeValue;
647
+                        // and remember to set this attribute later
648
+                        $reset[] = $attributeCopy;
649
+                    }
650
+                }
651 651
 				
652
-				foreach($remove as $attribute) {
653
-					$this->doc->documentElement->removeAttributeNode($attribute);
654
-				}
655
-				foreach($reset as $attribute) {
656
-					$this->doc->documentElement->setAttributeNode($attribute);
657
-				}
658
-			}
659
-			$out = $this->doc->saveXML(null, $cfg['savexml_options']);
660
-			if((!$cfg['parse_xhtml_as_xml'] || !$properXhtml) && $cfg['cdata_fix']) {
661
-				// these are ugly fixes so inline style and script blocks still work. better don't use them with XHTML to avoid trouble
662
-				// http://www.456bereastreet.com/archive/200501/the_perils_of_using_xhtml_properly/
663
-				// http://www.hixie.ch/advocacy/xhtml
664
-				$out = preg_replace('/<style([^>]*)>\s*<!\[CDATA\[\s*?/iU' . ($utf8 ? 'u' : ''), '<style$1><!--/*--><![CDATA[/*><!--*/' . "\n", $out);
665
-				if(!$firstError) {
666
-					$firstError = preg_last_error();
667
-				}
668
-				// we can't clean up whitespace before the closing element because a preg with a leading \s* expression would be horribly slow
669
-				$out = preg_replace('/\]\]>\s*<\/style>/iU' . ($utf8 ? 'u' : ''), "\n" . '/*]]>*/--></style>', $out);
670
-				if(!$firstError) {
671
-					$firstError = preg_last_error();
672
-				}
673
-				$out = preg_replace('/<script([^>]*)>\s*<!\[CDATA\[\s*?/iU' . ($utf8 ? 'u' : ''), '<script$1><!--//--><![CDATA[//><!--' . "\n", $out);
674
-				if(!$firstError) {
675
-					$firstError = preg_last_error();
676
-				}
677
-				// we can't clean up whitespace before the closing element because a preg with a leading \s* expression would be horribly slow
678
-				$out = preg_replace('/\]\]>\s*<\/script>/iU' . ($utf8 ? 'u' : ''), "\n" . '//--><!]]></script>', $out);
679
-				if(!$firstError) {
680
-					$firstError = preg_last_error();
681
-				}
682
-			}
683
-			if($cfg['remove_auto_xml_prolog'] && !$hasXmlProlog) {
684
-				// there was no xml prolog in the document before, so we remove the one generated by DOM now
685
-				$out = preg_replace('/<\?xml.*?\?>\s+/iU' . ($utf8 ? 'u' : ''), '', $out);
686
-				if(!$firstError) {
687
-					$firstError = preg_last_error();
688
-				}
689
-			} elseif(!$cfg['parse_xhtml_as_xml']) {
690
-				// yes, DOM sucks and inserts another XML prolog _after_ the DOCTYPE... and it has two question marks at the end, not one, don't ask me why
691
-				$out = preg_replace('/<\?xml.*?\?\?>\s+/iU' . ($utf8 ? 'u' : ''), '', $out);
692
-				if(!$firstError) {
693
-					$firstError = preg_last_error();
694
-				}
695
-			}
652
+                foreach($remove as $attribute) {
653
+                    $this->doc->documentElement->removeAttributeNode($attribute);
654
+                }
655
+                foreach($reset as $attribute) {
656
+                    $this->doc->documentElement->setAttributeNode($attribute);
657
+                }
658
+            }
659
+            $out = $this->doc->saveXML(null, $cfg['savexml_options']);
660
+            if((!$cfg['parse_xhtml_as_xml'] || !$properXhtml) && $cfg['cdata_fix']) {
661
+                // these are ugly fixes so inline style and script blocks still work. better don't use them with XHTML to avoid trouble
662
+                // http://www.456bereastreet.com/archive/200501/the_perils_of_using_xhtml_properly/
663
+                // http://www.hixie.ch/advocacy/xhtml
664
+                $out = preg_replace('/<style([^>]*)>\s*<!\[CDATA\[\s*?/iU' . ($utf8 ? 'u' : ''), '<style$1><!--/*--><![CDATA[/*><!--*/' . "\n", $out);
665
+                if(!$firstError) {
666
+                    $firstError = preg_last_error();
667
+                }
668
+                // we can't clean up whitespace before the closing element because a preg with a leading \s* expression would be horribly slow
669
+                $out = preg_replace('/\]\]>\s*<\/style>/iU' . ($utf8 ? 'u' : ''), "\n" . '/*]]>*/--></style>', $out);
670
+                if(!$firstError) {
671
+                    $firstError = preg_last_error();
672
+                }
673
+                $out = preg_replace('/<script([^>]*)>\s*<!\[CDATA\[\s*?/iU' . ($utf8 ? 'u' : ''), '<script$1><!--//--><![CDATA[//><!--' . "\n", $out);
674
+                if(!$firstError) {
675
+                    $firstError = preg_last_error();
676
+                }
677
+                // we can't clean up whitespace before the closing element because a preg with a leading \s* expression would be horribly slow
678
+                $out = preg_replace('/\]\]>\s*<\/script>/iU' . ($utf8 ? 'u' : ''), "\n" . '//--><!]]></script>', $out);
679
+                if(!$firstError) {
680
+                    $firstError = preg_last_error();
681
+                }
682
+            }
683
+            if($cfg['remove_auto_xml_prolog'] && !$hasXmlProlog) {
684
+                // there was no xml prolog in the document before, so we remove the one generated by DOM now
685
+                $out = preg_replace('/<\?xml.*?\?>\s+/iU' . ($utf8 ? 'u' : ''), '', $out);
686
+                if(!$firstError) {
687
+                    $firstError = preg_last_error();
688
+                }
689
+            } elseif(!$cfg['parse_xhtml_as_xml']) {
690
+                // yes, DOM sucks and inserts another XML prolog _after_ the DOCTYPE... and it has two question marks at the end, not one, don't ask me why
691
+                $out = preg_replace('/<\?xml.*?\?\?>\s+/iU' . ($utf8 ? 'u' : ''), '', $out);
692
+                if(!$firstError) {
693
+                    $firstError = preg_last_error();
694
+                }
695
+            }
696 696
 			
697
-			if($firstError) {
698
-				$error = "Form Population Filter encountered an error while performing final regular expression replaces on the output.\n";
699
-				// the preg_replaces failed and produced an empty string. let's find out why
700
-				$error .= "The error reported by preg_last_error() indicates that ";
701
-				switch($firstError) {
702
-					case PREG_BAD_UTF8_ERROR:
703
-						$error .= "the input contained malformed UTF-8 data.";
704
-						break;
705
-					case PREG_RECURSION_LIMIT_ERROR:
706
-						$error .= "the recursion limit (defined by \"pcre.recursion_limit\") was hit. This shouldn't happen unless you changed that limit yourself in php.ini or using ini_set(). If the problem is not on your end, please file a bug report with a reproduce case on the Agavi issue tracker or drop by on the IRC support channel.";
707
-						break;
708
-					case PREG_BACKTRACK_LIMIT_ERROR:
709
-						$error .= "the backtrack limit (defined by \"pcre.backtrack_limit\") was hit. This shouldn't happen unless you changed that limit yourself in php.ini or using ini_set(). If the problem is not on your end, please file a bug report with a reproduce case on the Agavi issue tracker or drop by on the IRC support channel.";
710
-						break;
711
-					case PREG_INTERNAL_ERROR:
712
-					default:
713
-						$error .= "an internal PCRE error occurred. As a quick countermeasure, try to upgrade PHP (and the bundled PCRE) as well as libxml (yes!) to the latest versions to see if the problem goes away. If the issue persists, file a bug report with a reproduce case on the Agavi issue tracker or drop by on the IRC support channel.";
714
-				}
715
-				throw new AgaviException($error);
716
-			}
717
-
718
-			$response->setContent($out);
719
-		} else {
720
-			$response->setContent($this->doc->saveHTML());
721
-		}
722
-		unset($this->xpath);
723
-		unset($this->doc);
724
-	}
725
-
726
-	/**
727
-	 * Insert the error messages from the given incidents into the given element
728
-	 * using the given rules.
729
-	 *
730
-	 * @param      \DOMElement          $element The element to work on.
731
-	 * @param      array                $rules An array of insertion rules
732
-	 * @param      ValidationIncident[] $incidents An array of ValidationIncidents.
733
-	 *
734
-	 * @return     bool Whether or not the inserts were successful.
735
-	 *
736
-	 * @author     David Zülke <[email protected]>
737
-	 * @since      0.11.0
738
-	 */
739
-	protected function insertErrorMessages(\DOMElement $element, array $rules, array $incidents)
740
-	{
741
-		$errors = array();
742
-		foreach($incidents as $incident) {
743
-			if($incident->getSeverity() <= Validator::SILENT) {
744
-				continue;
745
-			}
746
-			foreach($incident->getErrors() as $error) {
747
-				if(strlen($error->getMessage())) {
748
-					$errors[] = $error;
749
-				}
750
-			}
751
-		}
697
+            if($firstError) {
698
+                $error = "Form Population Filter encountered an error while performing final regular expression replaces on the output.\n";
699
+                // the preg_replaces failed and produced an empty string. let's find out why
700
+                $error .= "The error reported by preg_last_error() indicates that ";
701
+                switch($firstError) {
702
+                    case PREG_BAD_UTF8_ERROR:
703
+                        $error .= "the input contained malformed UTF-8 data.";
704
+                        break;
705
+                    case PREG_RECURSION_LIMIT_ERROR:
706
+                        $error .= "the recursion limit (defined by \"pcre.recursion_limit\") was hit. This shouldn't happen unless you changed that limit yourself in php.ini or using ini_set(). If the problem is not on your end, please file a bug report with a reproduce case on the Agavi issue tracker or drop by on the IRC support channel.";
707
+                        break;
708
+                    case PREG_BACKTRACK_LIMIT_ERROR:
709
+                        $error .= "the backtrack limit (defined by \"pcre.backtrack_limit\") was hit. This shouldn't happen unless you changed that limit yourself in php.ini or using ini_set(). If the problem is not on your end, please file a bug report with a reproduce case on the Agavi issue tracker or drop by on the IRC support channel.";
710
+                        break;
711
+                    case PREG_INTERNAL_ERROR:
712
+                    default:
713
+                        $error .= "an internal PCRE error occurred. As a quick countermeasure, try to upgrade PHP (and the bundled PCRE) as well as libxml (yes!) to the latest versions to see if the problem goes away. If the issue persists, file a bug report with a reproduce case on the Agavi issue tracker or drop by on the IRC support channel.";
714
+                }
715
+                throw new AgaviException($error);
716
+            }
717
+
718
+            $response->setContent($out);
719
+        } else {
720
+            $response->setContent($this->doc->saveHTML());
721
+        }
722
+        unset($this->xpath);
723
+        unset($this->doc);
724
+    }
725
+
726
+    /**
727
+     * Insert the error messages from the given incidents into the given element
728
+     * using the given rules.
729
+     *
730
+     * @param      \DOMElement          $element The element to work on.
731
+     * @param      array                $rules An array of insertion rules
732
+     * @param      ValidationIncident[] $incidents An array of ValidationIncidents.
733
+     *
734
+     * @return     bool Whether or not the inserts were successful.
735
+     *
736
+     * @author     David Zülke <[email protected]>
737
+     * @since      0.11.0
738
+     */
739
+    protected function insertErrorMessages(\DOMElement $element, array $rules, array $incidents)
740
+    {
741
+        $errors = array();
742
+        foreach($incidents as $incident) {
743
+            if($incident->getSeverity() <= Validator::SILENT) {
744
+                continue;
745
+            }
746
+            foreach($incident->getErrors() as $error) {
747
+                if(strlen($error->getMessage())) {
748
+                    $errors[] = $error;
749
+                }
750
+            }
751
+        }
752 752
 		
753
-		if(!$errors) {
754
-			// nothing to do here
755
-			return true;
756
-		}
757
-
758
-		$luie = libxml_use_internal_errors(true);
759
-		libxml_clear_errors();
760
-
761
-		$insertSuccessful = false;
762
-		foreach($rules as $xpathExpression => $errorMessageInfo) {
763
-			$targets = $this->xpath->query(Toolkit::expandVariables($xpathExpression, array('htmlnsPrefix' => $this->xmlnsPrefix)), $element);
764
-
765
-			if(!$targets || !$targets->length) {
766
-				continue;
767
-			}
768
-
769
-			if(!is_array($errorMessageInfo)) {
770
-				$errorMessageInfo = array('markup' => $errorMessageInfo);
771
-			}
772
-			if(isset($errorMessageInfo['markup'])) {
773
-				$errorMarkup = $errorMessageInfo['markup'];
774
-			} else {
775
-				$errorMarkup = null;
776
-			}
777
-			if(isset($errorMessageInfo['location'])) {
778
-				$errorLocation = $errorMessageInfo['location'];
779
-			} else {
780
-				$errorLocation = 'after';
781
-			}
782
-			if(isset($errorMessageInfo['container'])) {
783
-				$errorContainer = $errorMessageInfo['container'];
784
-			} else {
785
-				$errorContainer = null;
786
-			}
753
+        if(!$errors) {
754
+            // nothing to do here
755
+            return true;
756
+        }
757
+
758
+        $luie = libxml_use_internal_errors(true);
759
+        libxml_clear_errors();
760
+
761
+        $insertSuccessful = false;
762
+        foreach($rules as $xpathExpression => $errorMessageInfo) {
763
+            $targets = $this->xpath->query(Toolkit::expandVariables($xpathExpression, array('htmlnsPrefix' => $this->xmlnsPrefix)), $element);
764
+
765
+            if(!$targets || !$targets->length) {
766
+                continue;
767
+            }
768
+
769
+            if(!is_array($errorMessageInfo)) {
770
+                $errorMessageInfo = array('markup' => $errorMessageInfo);
771
+            }
772
+            if(isset($errorMessageInfo['markup'])) {
773
+                $errorMarkup = $errorMessageInfo['markup'];
774
+            } else {
775
+                $errorMarkup = null;
776
+            }
777
+            if(isset($errorMessageInfo['location'])) {
778
+                $errorLocation = $errorMessageInfo['location'];
779
+            } else {
780
+                $errorLocation = 'after';
781
+            }
782
+            if(isset($errorMessageInfo['container'])) {
783
+                $errorContainer = $errorMessageInfo['container'];
784
+            } else {
785
+                $errorContainer = null;
786
+            }
787 787
 			
788
-			if(!$errorMarkup && !$errorContainer) {
789
-				throw new AgaviExceptionn('Form Population Filter was unable to insert error messages into the document using the XPath expression "' . $xpathExpression . '" because the element information did not contain either a "markup" or "container" entry to use.');
790
-			}
788
+            if(!$errorMarkup && !$errorContainer) {
789
+                throw new AgaviExceptionn('Form Population Filter was unable to insert error messages into the document using the XPath expression "' . $xpathExpression . '" because the element information did not contain either a "markup" or "container" entry to use.');
790
+            }
791 791
 			
792
-			$errorElements = array();
792
+            $errorElements = array();
793 793
 			
794
-			if($errorMarkup) {
795
-				foreach($errors as $error) {
796
-					if(is_callable($errorMarkup)) {
797
-						// it's a callback we can use to get a DOMElement or an XML/HTML string (for convenience
798
-						// and because it is impossible to provide multiple sibling elements via a DOMElement)
799
-						// we give it the element as the first, the error message as the second (for BC reasons)
800
-						// and the error object as the third argument
801
-						$errorElement = call_user_func($errorMarkup, $element, $error->getMessage(), $error);
802
-						if(is_string($errorElement)) {
803
-							$errorElementHtml = $errorElement;
804
-							$errorElement = $this->doc->createDocumentFragment();
805
-							$errorElement->appendXML($errorElementHtml);
806
-						} else {
807
-							$this->doc->importNode($errorElement, true);
808
-						}
809
-					} elseif(is_string($errorMarkup)) {
810
-						// it's a string with the HTML to insert
811
-						// %s is the placeholder in the HTML for the error message
812
-						$errorElement = $this->doc->createDocumentFragment();
813
-						$errorElement->appendXML(
814
-							Toolkit::expandVariables(
815
-								$errorMarkup,
816
-								array(
817
-									'elementId'    => htmlspecialchars($element->getAttribute('id'), ENT_QUOTES, 'UTF-8'),
818
-									'elementName'  => htmlspecialchars($element->getAttribute('name'), ENT_QUOTES, 'UTF-8'),
819
-									'errorMessage' => htmlspecialchars($error->getMessage(), ENT_QUOTES, 'UTF-8'),
820
-								)
821
-							)
822
-						);
823
-					} else {
824
-						throw new AgaviException('Form Population Filter was unable to insert an error message into the document using the XPath expression "' . $xpathExpression . '" because the element information could not be evaluated as an XML/HTML fragment or as a PHP callback.');
825
-					}
794
+            if($errorMarkup) {
795
+                foreach($errors as $error) {
796
+                    if(is_callable($errorMarkup)) {
797
+                        // it's a callback we can use to get a DOMElement or an XML/HTML string (for convenience
798
+                        // and because it is impossible to provide multiple sibling elements via a DOMElement)
799
+                        // we give it the element as the first, the error message as the second (for BC reasons)
800
+                        // and the error object as the third argument
801
+                        $errorElement = call_user_func($errorMarkup, $element, $error->getMessage(), $error);
802
+                        if(is_string($errorElement)) {
803
+                            $errorElementHtml = $errorElement;
804
+                            $errorElement = $this->doc->createDocumentFragment();
805
+                            $errorElement->appendXML($errorElementHtml);
806
+                        } else {
807
+                            $this->doc->importNode($errorElement, true);
808
+                        }
809
+                    } elseif(is_string($errorMarkup)) {
810
+                        // it's a string with the HTML to insert
811
+                        // %s is the placeholder in the HTML for the error message
812
+                        $errorElement = $this->doc->createDocumentFragment();
813
+                        $errorElement->appendXML(
814
+                            Toolkit::expandVariables(
815
+                                $errorMarkup,
816
+                                array(
817
+                                    'elementId'    => htmlspecialchars($element->getAttribute('id'), ENT_QUOTES, 'UTF-8'),
818
+                                    'elementName'  => htmlspecialchars($element->getAttribute('name'), ENT_QUOTES, 'UTF-8'),
819
+                                    'errorMessage' => htmlspecialchars($error->getMessage(), ENT_QUOTES, 'UTF-8'),
820
+                                )
821
+                            )
822
+                        );
823
+                    } else {
824
+                        throw new AgaviException('Form Population Filter was unable to insert an error message into the document using the XPath expression "' . $xpathExpression . '" because the element information could not be evaluated as an XML/HTML fragment or as a PHP callback.');
825
+                    }
826 826
 					
827
-					$errorElements[] = $errorElement;
828
-				}
829
-			}
830
-
831
-			if($errorContainer) {
832
-				// we have an error container.
833
-				// that means that instead of inserting each message element, we add the messages into the container
834
-				// then, the container is the only element scheduled for insertion
835
-				$errorStrings = array();
836
-				if($errorElements) {
837
-					// add all error XML strings to an array
838
-					foreach($errorElements as $errorElement) {
839
-						$errorStrings[] = $errorElement->ownerDocument->saveXML($errorElement);
840
-					}
841
-				} else {
842
-					// if no error markup was given, just provide the error messages
843
-					foreach($errors as $error) {
844
-						$errorStrings[] = $error->getMessage();
845
-					}
846
-				}
847
-
848
-				// create the container element and replace the errors placeholder in the container
849
-				if(is_callable($errorContainer)) {
850
-					// it's a callback we can use to get a DOMElement or an XML/HTML string (for convenience
851
-					// and because it is impossible to provide multiple sibling elements via a DOMElement)
852
-					// we give it the element as the first, the error messages array(!) as the second (for BC reasons)
853
-					// and the array of all error objects as the third argument
854
-					$containerElement = call_user_func($errorContainer, $element, $errorStrings, $errors);
855
-					if(is_string($containerElement)) {
856
-						$containerElementHtml = $containerElement;
857
-						$containerElement = $this->doc->createDocumentFragment();
858
-						$containerElement->appendXML($containerElementHtml);
859
-					} else {
860
-						$this->doc->importNode($containerElement, true);
861
-					}
862
-				} elseif(is_string($errorContainer)) {
863
-					// it's a string with the HTML to insert
864
-					// %s is the placeholder in the HTML for the error message
865
-					$containerElement = $this->doc->createDocumentFragment();
866
-					$containerElement->appendXML(
867
-						Toolkit::expandVariables(
868
-							$errorContainer,
869
-							array(
870
-								'elementId'     => htmlspecialchars($element->getAttribute('id'), ENT_QUOTES, 'UTF-8'),
871
-								'elementName'   => htmlspecialchars($element->getAttribute('name'), ENT_QUOTES, 'UTF-8'),
872
-								'errorMessages' => implode("\n", $errorStrings),
873
-							)
874
-						)
875
-					);
876
-				} else {
877
-					throw new AgaviException('Form Population Filter was unable to insert an error message container into the document using the XPath expression "' . $xpathExpression . '" because the element information could not be evaluated as an XML/HTML fragment or as a PHP callback.');
878
-				}
879
-
880
-				// and now the trick: set the error container element as the only one in the errorElements variable
881
-				// that way, it's going to get inserted for us as if it were a normal error message element, using the location specified
882
-				$errorElements = array($containerElement);
883
-			}
884
-
885
-			if(libxml_get_last_error() !== false) {
886
-				$errors = array();
887
-				foreach(libxml_get_errors() as $error) {
888
-					$errors[] = sprintf('[%s #%d] Line %d: %s', $error->level == LIBXML_ERR_WARNING ? 'Warning' : ($error->level == LIBXML_ERR_ERROR ? 'Error' : 'Fatal'), $error->code, $error->line, $error->message);
889
-				}
890
-				libxml_clear_errors();
891
-				libxml_use_internal_errors($luie);
892
-				$emsg = sprintf(
893
-					'Form Population Filter was unable to insert an error message into the document using the XPath expression "%s" due to the following error%s: ' . "\n\n%s",
894
-					$xpathExpression,
895
-					count($errors) > 1 ? 's' : '',
896
-					implode("\n", $errors)
897
-				);
898
-				throw new ParseException($emsg);
899
-			}
900
-
901
-			foreach($errorElements as $errorElement) {
902
-				foreach($targets as $target) {
903
-					// in case the target yielded more than one location, we need to clone the element
904
-					// because the document fragment node will be corrupted after an insert
905
-					$clonedErrorElement = $errorElement->cloneNode(true);
827
+                    $errorElements[] = $errorElement;
828
+                }
829
+            }
830
+
831
+            if($errorContainer) {
832
+                // we have an error container.
833
+                // that means that instead of inserting each message element, we add the messages into the container
834
+                // then, the container is the only element scheduled for insertion
835
+                $errorStrings = array();
836
+                if($errorElements) {
837
+                    // add all error XML strings to an array
838
+                    foreach($errorElements as $errorElement) {
839
+                        $errorStrings[] = $errorElement->ownerDocument->saveXML($errorElement);
840
+                    }
841
+                } else {
842
+                    // if no error markup was given, just provide the error messages
843
+                    foreach($errors as $error) {
844
+                        $errorStrings[] = $error->getMessage();
845
+                    }
846
+                }
847
+
848
+                // create the container element and replace the errors placeholder in the container
849
+                if(is_callable($errorContainer)) {
850
+                    // it's a callback we can use to get a DOMElement or an XML/HTML string (for convenience
851
+                    // and because it is impossible to provide multiple sibling elements via a DOMElement)
852
+                    // we give it the element as the first, the error messages array(!) as the second (for BC reasons)
853
+                    // and the array of all error objects as the third argument
854
+                    $containerElement = call_user_func($errorContainer, $element, $errorStrings, $errors);
855
+                    if(is_string($containerElement)) {
856
+                        $containerElementHtml = $containerElement;
857
+                        $containerElement = $this->doc->createDocumentFragment();
858
+                        $containerElement->appendXML($containerElementHtml);
859
+                    } else {
860
+                        $this->doc->importNode($containerElement, true);
861
+                    }
862
+                } elseif(is_string($errorContainer)) {
863
+                    // it's a string with the HTML to insert
864
+                    // %s is the placeholder in the HTML for the error message
865
+                    $containerElement = $this->doc->createDocumentFragment();
866
+                    $containerElement->appendXML(
867
+                        Toolkit::expandVariables(
868
+                            $errorContainer,
869
+                            array(
870
+                                'elementId'     => htmlspecialchars($element->getAttribute('id'), ENT_QUOTES, 'UTF-8'),
871
+                                'elementName'   => htmlspecialchars($element->getAttribute('name'), ENT_QUOTES, 'UTF-8'),
872
+                                'errorMessages' => implode("\n", $errorStrings),
873
+                            )
874
+                        )
875
+                    );
876
+                } else {
877
+                    throw new AgaviException('Form Population Filter was unable to insert an error message container into the document using the XPath expression "' . $xpathExpression . '" because the element information could not be evaluated as an XML/HTML fragment or as a PHP callback.');
878
+                }
879
+
880
+                // and now the trick: set the error container element as the only one in the errorElements variable
881
+                // that way, it's going to get inserted for us as if it were a normal error message element, using the location specified
882
+                $errorElements = array($containerElement);
883
+            }
884
+
885
+            if(libxml_get_last_error() !== false) {
886
+                $errors = array();
887
+                foreach(libxml_get_errors() as $error) {
888
+                    $errors[] = sprintf('[%s #%d] Line %d: %s', $error->level == LIBXML_ERR_WARNING ? 'Warning' : ($error->level == LIBXML_ERR_ERROR ? 'Error' : 'Fatal'), $error->code, $error->line, $error->message);
889
+                }
890
+                libxml_clear_errors();
891
+                libxml_use_internal_errors($luie);
892
+                $emsg = sprintf(
893
+                    'Form Population Filter was unable to insert an error message into the document using the XPath expression "%s" due to the following error%s: ' . "\n\n%s",
894
+                    $xpathExpression,
895
+                    count($errors) > 1 ? 's' : '',
896
+                    implode("\n", $errors)
897
+                );
898
+                throw new ParseException($emsg);
899
+            }
900
+
901
+            foreach($errorElements as $errorElement) {
902
+                foreach($targets as $target) {
903
+                    // in case the target yielded more than one location, we need to clone the element
904
+                    // because the document fragment node will be corrupted after an insert
905
+                    $clonedErrorElement = $errorElement->cloneNode(true);
906 906
 					
907
-					if($errorLocation == 'before') {
908
-						$target->parentNode->insertBefore($clonedErrorElement, $target);
909
-					} elseif($errorLocation == 'after') {
910
-						// check if there is a following sibling, then insert before that one
911
-						// if not, append to parent
912
-						if($target->nextSibling) {
913
-							$target->parentNode->insertBefore($clonedErrorElement, $target->nextSibling);
914
-						} else {
915
-							$target->parentNode->appendChild($clonedErrorElement);
916
-						}
917
-					} elseif($errorLocation == 'replace') {
918
-						$target->parentNode->replaceChild($clonedErrorElement, $target);
919
-					} else {
920
-						$target->appendChild($clonedErrorElement);
921
-					}
922
-				}
923
-			}
924
-
925
-			// and break the foreach, our expression matched after all - no need to look further
926
-			$insertSuccessful = true;
927
-			break;
928
-		}
929
-
930
-		libxml_clear_errors();
931
-		libxml_use_internal_errors($luie);
932
-
933
-		return $insertSuccessful;
934
-	}
935
-
936
-	/**
937
-	 * Encode given value to UTF-8
938
-	 *
939
-	 * @param      mixed  $value The value to convert (can be an array).
940
-	 * @param      string $encoding The encoding of the value.
941
-	 *
942
-	 * @return     mixed  The converted value.
943
-	 *
944
-	 * @author     David Zülke <[email protected]>
945
-	 * @since      0.11.0
946
-	 */
947
-	protected function toUtf8($value, $encoding = self::ENCODING_ISO_8859_1)
948
-	{
949
-		if($encoding == self::ENCODING_ISO_8859_1) {
950
-			if(is_array($value)) {
951
-				foreach($value as &$val) {
952
-					$val = $this->toUtf8($val, $encoding);
953
-				}
954
-			} else {
955
-				$value = utf8_encode($value);
956
-			}
957
-		} else {
958
-			if(is_array($value)) {
959
-				foreach($value as &$val) {
960
-					$val = $this->toUtf8($val, $encoding);
961
-				}
962
-			} else {
963
-				$value = iconv($encoding, self::ENCODING_UTF_8, $value);
964
-			}
965
-		}
966
-
967
-		return $value;
968
-	}
969
-
970
-	/**
971
-	 * Decode given value from UTF-8
972
-	 *
973
-	 * @param      mixed  $value The value to convert (can be an array).
974
-	 * @param      string $encoding The encoding of the value.
975
-	 *
976
-	 * @return     mixed  The converted value.
977
-	 *
978
-	 * @author     David Zülke <[email protected]>
979
-	 * @since      0.11.0
980
-	 */
981
-	protected function fromUtf8($value, $encoding = self::ENCODING_ISO_8859_1)
982
-	{
983
-		if($encoding == self::ENCODING_ISO_8859_1) {
984
-			if(is_array($value)) {
985
-				foreach($value as &$val) {
986
-					$val = $this->fromUtf8($val, $encoding);
987
-				}
988
-			} else {
989
-				$value = utf8_decode($value);
990
-			}
991
-		} else {
992
-			if(is_array($value)) {
993
-				foreach($value as &$val) {
994
-					$val = $this->fromUtf8($val, $encoding);
995
-				}
996
-			} else {
997
-				$value = iconv(self::ENCODING_UTF_8, $encoding, $value);
998
-			}
999
-		}
1000
-
1001
-		return $value;
1002
-	}
1003
-
1004
-	/**
1005
-	 * Initialize this filter.
1006
-	 *
1007
-	 * @param      Context $context The current application context.
1008
-	 * @param      array   $parameters An associative array of initialization parameters.
1009
-	 *
1010
-	 * @throws     <b>AgaviFilterException</b> If an error occurs during
1011
-	 *                                         initialization
1012
-	 *
1013
-	 * @author     David Zülke <[email protected]>
1014
-	 * @since      0.11.0
1015
-	 */
1016
-	public function initialize(Context $context, array $parameters = array())
1017
-	{
1018
-		// set defaults
1019
-		$this->setParameters(array(
1020
-			'methods'                    => array(),
1021
-			'output_types'               => null,
1022
-
1023
-			'forms_xpath'                => '//${htmlnsPrefix}form[@action]',
1024
-			'populate'                   => null,
1025
-			'skip'                       => null,
1026
-			'include_hidden_inputs'      => true,
1027
-			'include_password_inputs'    => false,
1028
-
1029
-			'force_output_mode'          => false,
1030
-			'force_encoding'             => false,
1031
-			'force_request_uri'          => false,
1032
-			'force_request_url'          => false,
1033
-			'cdata_fix'                  => true,
1034
-			'parse_xhtml_as_xml'         => true,
1035
-			'remove_auto_xml_prolog'     => true,
1036
-			'dom_substitute_entities'    => false,
1037
-			'dom_resolve_externals'      => false,
1038
-			'dom_validate_on_parse'      => false,
1039
-			'dom_preserve_white_space'   => true,
1040
-			'dom_format_output'          => false,
1041
-			'savexml_options'            => array(),
1042
-
1043
-			'error_class'                => 'error',
1044
-			'error_class_map'            => array(),
1045
-			'error_messages'             => array(),
1046
-			'field_error_messages'       => array(),
1047
-			'multi_field_error_messages' => array(),
1048
-
1049
-			'ignore_parse_errors'        => LIBXML_ERR_ERROR,
1050
-			'log_parse_errors'           => LIBXML_ERR_WARNING,
1051
-			'logging_logger'             => null,
1052
-		));
1053
-
1054
-		// initialize parent
1055
-		parent::initialize($context, $parameters);
1056
-
1057
-		// and "clean up" some of the params just in case the user messed up
1058
-
1059
-		$errorClassMap = (array) $this->getParameter('error_class_map');
1060
-		// append a match-all expression to the map, which assigns the default error class
1061
-		$errorClassMap['self::${htmlnsPrefix}*'] = $this->getParameter('error_class');
1062
-		$this->setParameter('error_class_map', $errorClassMap);
1063
-
1064
-		$this->setParameter('methods', (array) $this->getParameter('methods'));
1065
-
1066
-		if($ot = $this->getParameter('output_types')) {
1067
-			$this->setParameter('output_types', (array) $ot);
1068
-		}
907
+                    if($errorLocation == 'before') {
908
+                        $target->parentNode->insertBefore($clonedErrorElement, $target);
909
+                    } elseif($errorLocation == 'after') {
910
+                        // check if there is a following sibling, then insert before that one
911
+                        // if not, append to parent
912
+                        if($target->nextSibling) {
913
+                            $target->parentNode->insertBefore($clonedErrorElement, $target->nextSibling);
914
+                        } else {
915
+                            $target->parentNode->appendChild($clonedErrorElement);
916
+                        }
917
+                    } elseif($errorLocation == 'replace') {
918
+                        $target->parentNode->replaceChild($clonedErrorElement, $target);
919
+                    } else {
920
+                        $target->appendChild($clonedErrorElement);
921
+                    }
922
+                }
923
+            }
924
+
925
+            // and break the foreach, our expression matched after all - no need to look further
926
+            $insertSuccessful = true;
927
+            break;
928
+        }
929
+
930
+        libxml_clear_errors();
931
+        libxml_use_internal_errors($luie);
932
+
933
+        return $insertSuccessful;
934
+    }
935
+
936
+    /**
937
+     * Encode given value to UTF-8
938
+     *
939
+     * @param      mixed  $value The value to convert (can be an array).
940
+     * @param      string $encoding The encoding of the value.
941
+     *
942
+     * @return     mixed  The converted value.
943
+     *
944
+     * @author     David Zülke <[email protected]>
945
+     * @since      0.11.0
946
+     */
947
+    protected function toUtf8($value, $encoding = self::ENCODING_ISO_8859_1)
948
+    {
949
+        if($encoding == self::ENCODING_ISO_8859_1) {
950
+            if(is_array($value)) {
951
+                foreach($value as &$val) {
952
+                    $val = $this->toUtf8($val, $encoding);
953
+                }
954
+            } else {
955
+                $value = utf8_encode($value);
956
+            }
957
+        } else {
958
+            if(is_array($value)) {
959
+                foreach($value as &$val) {
960
+                    $val = $this->toUtf8($val, $encoding);
961
+                }
962
+            } else {
963
+                $value = iconv($encoding, self::ENCODING_UTF_8, $value);
964
+            }
965
+        }
966
+
967
+        return $value;
968
+    }
969
+
970
+    /**
971
+     * Decode given value from UTF-8
972
+     *
973
+     * @param      mixed  $value The value to convert (can be an array).
974
+     * @param      string $encoding The encoding of the value.
975
+     *
976
+     * @return     mixed  The converted value.
977
+     *
978
+     * @author     David Zülke <[email protected]>
979
+     * @since      0.11.0
980
+     */
981
+    protected function fromUtf8($value, $encoding = self::ENCODING_ISO_8859_1)
982
+    {
983
+        if($encoding == self::ENCODING_ISO_8859_1) {
984
+            if(is_array($value)) {
985
+                foreach($value as &$val) {
986
+                    $val = $this->fromUtf8($val, $encoding);
987
+                }
988
+            } else {
989
+                $value = utf8_decode($value);
990
+            }
991
+        } else {
992
+            if(is_array($value)) {
993
+                foreach($value as &$val) {
994
+                    $val = $this->fromUtf8($val, $encoding);
995
+                }
996
+            } else {
997
+                $value = iconv(self::ENCODING_UTF_8, $encoding, $value);
998
+            }
999
+        }
1000
+
1001
+        return $value;
1002
+    }
1003
+
1004
+    /**
1005
+     * Initialize this filter.
1006
+     *
1007
+     * @param      Context $context The current application context.
1008
+     * @param      array   $parameters An associative array of initialization parameters.
1009
+     *
1010
+     * @throws     <b>AgaviFilterException</b> If an error occurs during
1011
+     *                                         initialization
1012
+     *
1013
+     * @author     David Zülke <[email protected]>
1014
+     * @since      0.11.0
1015
+     */
1016
+    public function initialize(Context $context, array $parameters = array())
1017
+    {
1018
+        // set defaults
1019
+        $this->setParameters(array(
1020
+            'methods'                    => array(),
1021
+            'output_types'               => null,
1022
+
1023
+            'forms_xpath'                => '//${htmlnsPrefix}form[@action]',
1024
+            'populate'                   => null,
1025
+            'skip'                       => null,
1026
+            'include_hidden_inputs'      => true,
1027
+            'include_password_inputs'    => false,
1028
+
1029
+            'force_output_mode'          => false,
1030
+            'force_encoding'             => false,
1031
+            'force_request_uri'          => false,
1032
+            'force_request_url'          => false,
1033
+            'cdata_fix'                  => true,
1034
+            'parse_xhtml_as_xml'         => true,
1035
+            'remove_auto_xml_prolog'     => true,
1036
+            'dom_substitute_entities'    => false,
1037
+            'dom_resolve_externals'      => false,
1038
+            'dom_validate_on_parse'      => false,
1039
+            'dom_preserve_white_space'   => true,
1040
+            'dom_format_output'          => false,
1041
+            'savexml_options'            => array(),
1042
+
1043
+            'error_class'                => 'error',
1044
+            'error_class_map'            => array(),
1045
+            'error_messages'             => array(),
1046
+            'field_error_messages'       => array(),
1047
+            'multi_field_error_messages' => array(),
1048
+
1049
+            'ignore_parse_errors'        => LIBXML_ERR_ERROR,
1050
+            'log_parse_errors'           => LIBXML_ERR_WARNING,
1051
+            'logging_logger'             => null,
1052
+        ));
1053
+
1054
+        // initialize parent
1055
+        parent::initialize($context, $parameters);
1056
+
1057
+        // and "clean up" some of the params just in case the user messed up
1058
+
1059
+        $errorClassMap = (array) $this->getParameter('error_class_map');
1060
+        // append a match-all expression to the map, which assigns the default error class
1061
+        $errorClassMap['self::${htmlnsPrefix}*'] = $this->getParameter('error_class');
1062
+        $this->setParameter('error_class_map', $errorClassMap);
1063
+
1064
+        $this->setParameter('methods', (array) $this->getParameter('methods'));
1065
+
1066
+        if($ot = $this->getParameter('output_types')) {
1067
+            $this->setParameter('output_types', (array) $ot);
1068
+        }
1069 1069
 		
1070
-		$savexmlOptions = 0;
1071
-		foreach((array)$this->getParameter('savexml_options', array()) as $option) {
1072
-			if(is_numeric($option)) {
1073
-				$savexmlOptions |= (int)$option;
1074
-			} elseif(defined($option)) {
1075
-				$savexmlOptions |= constant($option);
1076
-			}
1077
-		}
1078
-		$this->setParameter('savexml_options', $savexmlOptions);
1079
-
1080
-		$ignoreParseErrors =& $this->getParameter('ignore_parse_errors');
1081
-		if(is_string($ignoreParseErrors) && defined($ignoreParseErrors)) {
1082
-			$ignoreParseErrors = constant($ignoreParseErrors);
1083
-		}
1084
-		// BC
1085
-		if($ignoreParseErrors === true) {
1086
-			$ignoreParseErrors = LIBXML_ERR_FATAL;
1087
-		} elseif($ignoreParseErrors === false) {
1088
-			$ignoreParseErrors = LIBXML_ERR_NONE;
1089
-		}
1070
+        $savexmlOptions = 0;
1071
+        foreach((array)$this->getParameter('savexml_options', array()) as $option) {
1072
+            if(is_numeric($option)) {
1073
+                $savexmlOptions |= (int)$option;
1074
+            } elseif(defined($option)) {
1075
+                $savexmlOptions |= constant($option);
1076
+            }
1077
+        }
1078
+        $this->setParameter('savexml_options', $savexmlOptions);
1079
+
1080
+        $ignoreParseErrors =& $this->getParameter('ignore_parse_errors');
1081
+        if(is_string($ignoreParseErrors) && defined($ignoreParseErrors)) {
1082
+            $ignoreParseErrors = constant($ignoreParseErrors);
1083
+        }
1084
+        // BC
1085
+        if($ignoreParseErrors === true) {
1086
+            $ignoreParseErrors = LIBXML_ERR_FATAL;
1087
+        } elseif($ignoreParseErrors === false) {
1088
+            $ignoreParseErrors = LIBXML_ERR_NONE;
1089
+        }
1090 1090
 		
1091
-		$logParseErrors =& $this->getParameter('log_parse_errors');
1092
-		if(is_string($logParseErrors) && defined($logParseErrors)) {
1093
-			$logParseErrors = constant($logParseErrors);
1094
-		}
1095
-		// BC
1096
-		if($logParseErrors === true) {
1097
-			$logParseErrors = LIBXML_ERR_WARNING;
1098
-		}
1099
-
1100
-		// and now copy all that to the request namespace so it can all be modified at runtime, not just overwritten
1101
-		$this->context->getRequest()->setAttributes($this->getParameters(), 'org.agavi.filter.FormPopulationFilter');
1102
-	}
1091
+        $logParseErrors =& $this->getParameter('log_parse_errors');
1092
+        if(is_string($logParseErrors) && defined($logParseErrors)) {
1093
+            $logParseErrors = constant($logParseErrors);
1094
+        }
1095
+        // BC
1096
+        if($logParseErrors === true) {
1097
+            $logParseErrors = LIBXML_ERR_WARNING;
1098
+        }
1099
+
1100
+        // and now copy all that to the request namespace so it can all be modified at runtime, not just overwritten
1101
+        $this->context->getRequest()->setAttributes($this->getParameters(), 'org.agavi.filter.FormPopulationFilter');
1102
+    }
1103 1103
 }
1104 1104
 
1105 1105
 ?>
Please login to merge, or discard this patch.
src/controller/Controller.class.php 1 patch
Indentation   +263 added lines, -263 removed lines patch added patch discarded remove patch
@@ -38,293 +38,293 @@
 block discarded – undo
38 38
  */
39 39
 abstract class Controller
40 40
 {
41
-	/**
42
-	 * @var        ExecutionContainer This controller's execution container.
43
-	 */
44
-	protected $container = null;
41
+    /**
42
+     * @var        ExecutionContainer This controller's execution container.
43
+     */
44
+    protected $container = null;
45 45
 
46
-	/**
47
-	 * @var        Context A Context instance.
48
-	 */
49
-	protected $context = null;
46
+    /**
47
+     * @var        Context A Context instance.
48
+     */
49
+    protected $context = null;
50 50
 
51
-	/**
52
-	 * Retrieve the current application context.
53
-	 *
54
-	 * @return     Context The current Context instance.
55
-	 *
56
-	 * @author     Sean Kerr <[email protected]>
57
-	 * @since      0.9.0
58
-	 */
59
-	public final function getContext()
60
-	{
61
-		return $this->context;
62
-	}
51
+    /**
52
+     * Retrieve the current application context.
53
+     *
54
+     * @return     Context The current Context instance.
55
+     *
56
+     * @author     Sean Kerr <[email protected]>
57
+     * @since      0.9.0
58
+     */
59
+    public final function getContext()
60
+    {
61
+        return $this->context;
62
+    }
63 63
 
64
-	/**
65
-	 * Retrieve the execution container for this controller.
66
-	 *
67
-	 * @return     ExecutionContainer This controller's execution container.
68
-	 *
69
-	 * @author     David Zülke <[email protected]>
70
-	 * @since      0.11.0
71
-	 */
72
-	public final function getContainer()
73
-	{
74
-		return $this->container;
75
-	}
64
+    /**
65
+     * Retrieve the execution container for this controller.
66
+     *
67
+     * @return     ExecutionContainer This controller's execution container.
68
+     *
69
+     * @author     David Zülke <[email protected]>
70
+     * @since      0.11.0
71
+     */
72
+    public final function getContainer()
73
+    {
74
+        return $this->container;
75
+    }
76 76
 
77
-	/**
78
-	 * Retrieve the credential required to access this controller.
79
-	 *
80
-	 * @return     mixed Data that indicates the level of security for this
81
-	 *                   controller.
82
-	 *
83
-	 * @author     Sean Kerr <[email protected]>
84
-	 * @author     David Zülke <[email protected]>
85
-	 * @since      0.9.0
86
-	 */
87
-	public function getCredentials()
88
-	{
89
-		return null;
90
-	}
77
+    /**
78
+     * Retrieve the credential required to access this controller.
79
+     *
80
+     * @return     mixed Data that indicates the level of security for this
81
+     *                   controller.
82
+     *
83
+     * @author     Sean Kerr <[email protected]>
84
+     * @author     David Zülke <[email protected]>
85
+     * @since      0.9.0
86
+     */
87
+    public function getCredentials()
88
+    {
89
+        return null;
90
+    }
91 91
 
92
-	/**
93
-	 * Execute any post-validation error application logic.
94
-	 *
95
-	 * @param      RequestDataHolder $rd The controller's request data holder.
96
-	 *
97
-	 * @return     mixed A string containing the view name associated with this
98
-	 *                   controller.
99
-	 *                   Or an array with the following indices:
100
-	 *                   - The parent module of the view that will be executed.
101
-	 *                   - The view that will be executed.
102
-	 *
103
-	 * @author     Sean Kerr <[email protected]>
104
-	 * @author     David Zülke <[email protected]>
105
-	 * @since      0.9.0
106
-	 */
107
-	public function handleError(RequestDataHolder $rd)
108
-	{
109
-		return 'Error';
110
-	}
92
+    /**
93
+     * Execute any post-validation error application logic.
94
+     *
95
+     * @param      RequestDataHolder $rd The controller's request data holder.
96
+     *
97
+     * @return     mixed A string containing the view name associated with this
98
+     *                   controller.
99
+     *                   Or an array with the following indices:
100
+     *                   - The parent module of the view that will be executed.
101
+     *                   - The view that will be executed.
102
+     *
103
+     * @author     Sean Kerr <[email protected]>
104
+     * @author     David Zülke <[email protected]>
105
+     * @since      0.9.0
106
+     */
107
+    public function handleError(RequestDataHolder $rd)
108
+    {
109
+        return 'Error';
110
+    }
111 111
 
112
-	/**
113
-	 * Initialize this controller.
114
-	 *
115
-	 * @param      ExecutionContainer $container This Controller's execution container.
116
-	 *
117
-	 * @author     David Zülke <[email protected]>
118
-	 * @since      0.9.0
119
-	 */
120
-	public function initialize(ExecutionContainer $container)
121
-	{
122
-		$this->container = $container;
112
+    /**
113
+     * Initialize this controller.
114
+     *
115
+     * @param      ExecutionContainer $container This Controller's execution container.
116
+     *
117
+     * @author     David Zülke <[email protected]>
118
+     * @since      0.9.0
119
+     */
120
+    public function initialize(ExecutionContainer $container)
121
+    {
122
+        $this->container = $container;
123 123
 
124
-		$this->context = $container->getContext();
125
-	}
124
+        $this->context = $container->getContext();
125
+    }
126 126
 
127
-	/**
128
-	 * Indicates that this controller requires security.
129
-	 *
130
-	 * @return     bool true, if this controller requires security, otherwise false.
131
-	 *
132
-	 * @author     Sean Kerr <[email protected]>
133
-	 * @since      0.9.0
134
-	 */
135
-	public function isSecure()
136
-	{
137
-		return false;
138
-	}
127
+    /**
128
+     * Indicates that this controller requires security.
129
+     *
130
+     * @return     bool true, if this controller requires security, otherwise false.
131
+     *
132
+     * @author     Sean Kerr <[email protected]>
133
+     * @since      0.9.0
134
+     */
135
+    public function isSecure()
136
+    {
137
+        return false;
138
+    }
139 139
 
140
-	/**
141
-	 * Whether or not this controller is "simple", i.e. does not use validation etc.
142
-	 *
143
-	 * @return     bool true, if this controller should act in simple mode, or false.
144
-	 *
145
-	 * @author     David Zülke <[email protected]>
146
-	 * @since      0.11.0
147
-	 */
148
-	public function isSimple()
149
-	{
150
-		return false;
151
-	}
140
+    /**
141
+     * Whether or not this controller is "simple", i.e. does not use validation etc.
142
+     *
143
+     * @return     bool true, if this controller should act in simple mode, or false.
144
+     *
145
+     * @author     David Zülke <[email protected]>
146
+     * @since      0.11.0
147
+     */
148
+    public function isSimple()
149
+    {
150
+        return false;
151
+    }
152 152
 
153
-	/**
154
-	 * Manually register validators for this controller.
155
-	 *
156
-	 * @author     Sean Kerr <[email protected]>
157
-	 * @since      0.9.0
158
-	 */
159
-	public function registerValidators()
160
-	{
161
-	}
153
+    /**
154
+     * Manually register validators for this controller.
155
+     *
156
+     * @author     Sean Kerr <[email protected]>
157
+     * @since      0.9.0
158
+     */
159
+    public function registerValidators()
160
+    {
161
+    }
162 162
 
163
-	/**
164
-	 * Manually validate files and parameters.
165
-	 *
166
-	 * @param      RequestDataHolder $rd The controller's request data holder.
167
-	 *
168
-	 * @return     bool true, if validation completed successfully, otherwise
169
-	 *                  false.
170
-	 *
171
-	 * @author     Sean Kerr <[email protected]>
172
-	 * @author     David Zülke <[email protected]>
173
-	 * @since      0.9.0
174
-	 */
175
-	public function validate(RequestDataHolder $rd)
176
-	{
177
-		return true;
178
-	}
163
+    /**
164
+     * Manually validate files and parameters.
165
+     *
166
+     * @param      RequestDataHolder $rd The controller's request data holder.
167
+     *
168
+     * @return     bool true, if validation completed successfully, otherwise
169
+     *                  false.
170
+     *
171
+     * @author     Sean Kerr <[email protected]>
172
+     * @author     David Zülke <[email protected]>
173
+     * @since      0.9.0
174
+     */
175
+    public function validate(RequestDataHolder $rd)
176
+    {
177
+        return true;
178
+    }
179 179
 
180
-	/**
181
-	 * Get the default View name if this Controller doesn't serve the Request method.
182
-	 *
183
-	 * @return     mixed A string containing the view name associated with this
184
-	 *                   controller.
185
-	 *                   Or an array with the following indices:
186
-	 *                   - The parent module of the view that will be executed.
187
-	 *                   - The view that will be executed.
188
-	 *
189
-	 * @author     David Zülke <[email protected]>
190
-	 * @since      0.11.0
191
-	 */
192
-	public function getDefaultViewName()
193
-	{
194
-		return 'Input';
195
-	}
180
+    /**
181
+     * Get the default View name if this Controller doesn't serve the Request method.
182
+     *
183
+     * @return     mixed A string containing the view name associated with this
184
+     *                   controller.
185
+     *                   Or an array with the following indices:
186
+     *                   - The parent module of the view that will be executed.
187
+     *                   - The view that will be executed.
188
+     *
189
+     * @author     David Zülke <[email protected]>
190
+     * @since      0.11.0
191
+     */
192
+    public function getDefaultViewName()
193
+    {
194
+        return 'Input';
195
+    }
196 196
 
197
-	/**
198
-	 * @see        AttributeHolder::clearAttributes()
199
-	 *
200
-	 * @author     David Zülke <[email protected]>
201
-	 * @since      0.9.0
202
-	 */
203
-	public function clearAttributes()
204
-	{
205
-		$this->container->clearAttributes();
206
-	}
197
+    /**
198
+     * @see        AttributeHolder::clearAttributes()
199
+     *
200
+     * @author     David Zülke <[email protected]>
201
+     * @since      0.9.0
202
+     */
203
+    public function clearAttributes()
204
+    {
205
+        $this->container->clearAttributes();
206
+    }
207 207
 
208
-	/**
209
-	 * @see        AttributeHolder::getAttribute()
210
-	 *
211
-	 * @author     David Zülke <[email protected]>
212
-	 * @since      0.9.0
213
-	 */
214
-	public function &getAttribute($name, $default = null)
215
-	{
216
-		return $this->container->getAttribute($name, null, $default);
217
-	}
208
+    /**
209
+     * @see        AttributeHolder::getAttribute()
210
+     *
211
+     * @author     David Zülke <[email protected]>
212
+     * @since      0.9.0
213
+     */
214
+    public function &getAttribute($name, $default = null)
215
+    {
216
+        return $this->container->getAttribute($name, null, $default);
217
+    }
218 218
 
219
-	/**
220
-	 * @see        AttributeHolder::getAttributeNames()
221
-	 *
222
-	 * @author     David Zülke <[email protected]>
223
-	 * @since      0.9.0
224
-	 */
225
-	public function getAttributeNames()
226
-	{
227
-		return $this->container->getAttributeNames();
228
-	}
219
+    /**
220
+     * @see        AttributeHolder::getAttributeNames()
221
+     *
222
+     * @author     David Zülke <[email protected]>
223
+     * @since      0.9.0
224
+     */
225
+    public function getAttributeNames()
226
+    {
227
+        return $this->container->getAttributeNames();
228
+    }
229 229
 
230
-	/**
231
-	 * @see        AttributeHolder::getAttributes()
232
-	 *
233
-	 * @author     David Zülke <[email protected]>
234
-	 * @since      0.11.0
235
-	 */
236
-	public function &getAttributes()
237
-	{
238
-		return $this->container->getAttributes();
239
-	}
230
+    /**
231
+     * @see        AttributeHolder::getAttributes()
232
+     *
233
+     * @author     David Zülke <[email protected]>
234
+     * @since      0.11.0
235
+     */
236
+    public function &getAttributes()
237
+    {
238
+        return $this->container->getAttributes();
239
+    }
240 240
 
241
-	/**
242
-	 * @see        AttributeHolder::hasAttribute()
243
-	 *
244
-	 * @author     David Zülke <[email protected]>
245
-	 * @since      0.9.0
246
-	 */
247
-	public function hasAttribute($name)
248
-	{
249
-		return $this->container->hasAttribute($name);
250
-	}
241
+    /**
242
+     * @see        AttributeHolder::hasAttribute()
243
+     *
244
+     * @author     David Zülke <[email protected]>
245
+     * @since      0.9.0
246
+     */
247
+    public function hasAttribute($name)
248
+    {
249
+        return $this->container->hasAttribute($name);
250
+    }
251 251
 
252
-	/**
253
-	 * @see        AttributeHolder::removeAttribute()
254
-	 *
255
-	 * @author     David Zülke <[email protected]>
256
-	 * @since      0.9.0
257
-	 */
258
-	public function &removeAttribute($name)
259
-	{
260
-		return $this->container->removeAttribute($name);
261
-	}
252
+    /**
253
+     * @see        AttributeHolder::removeAttribute()
254
+     *
255
+     * @author     David Zülke <[email protected]>
256
+     * @since      0.9.0
257
+     */
258
+    public function &removeAttribute($name)
259
+    {
260
+        return $this->container->removeAttribute($name);
261
+    }
262 262
 
263
-	/**
264
-	 * @see        AttributeHolder::setAttribute()
265
-	 *
266
-	 * @author     David Zülke <[email protected]>
267
-	 * @since      0.9.0
268
-	 */
269
-	public function setAttribute($name, $value)
270
-	{
271
-		$this->container->setAttribute($name, $value);
272
-	}
263
+    /**
264
+     * @see        AttributeHolder::setAttribute()
265
+     *
266
+     * @author     David Zülke <[email protected]>
267
+     * @since      0.9.0
268
+     */
269
+    public function setAttribute($name, $value)
270
+    {
271
+        $this->container->setAttribute($name, $value);
272
+    }
273 273
 
274
-	/**
275
-	 * @see        AttributeHolder::appendAttribute()
276
-	 *
277
-	 * @author     David Zülke <[email protected]>
278
-	 * @since      0.10.0
279
-	 */
280
-	public function appendAttribute($name, $value)
281
-	{
282
-		$this->container->appendAttribute($name, $value);
283
-	}
274
+    /**
275
+     * @see        AttributeHolder::appendAttribute()
276
+     *
277
+     * @author     David Zülke <[email protected]>
278
+     * @since      0.10.0
279
+     */
280
+    public function appendAttribute($name, $value)
281
+    {
282
+        $this->container->appendAttribute($name, $value);
283
+    }
284 284
 
285
-	/**
286
-	 * @see        AttributeHolder::setAttributeByRef()
287
-	 *
288
-	 * @author     David Zülke <[email protected]>
289
-	 * @since      0.9.0
290
-	 */
291
-	public function setAttributeByRef($name, &$value)
292
-	{
293
-		$this->container->setAttributeByRef($name, $value);
294
-	}
285
+    /**
286
+     * @see        AttributeHolder::setAttributeByRef()
287
+     *
288
+     * @author     David Zülke <[email protected]>
289
+     * @since      0.9.0
290
+     */
291
+    public function setAttributeByRef($name, &$value)
292
+    {
293
+        $this->container->setAttributeByRef($name, $value);
294
+    }
295 295
 
296
-	/**
297
-	 * @see        AttributeHolder::appendAttributeByRef()
298
-	 *
299
-	 * @author     David Zülke <[email protected]>
300
-	 * @since      0.10.0
301
-	 */
302
-	public function appendAttributeByRef($name, &$value)
303
-	{
304
-		$this->container->appendAttributeByRef($name, $value);
305
-	}
296
+    /**
297
+     * @see        AttributeHolder::appendAttributeByRef()
298
+     *
299
+     * @author     David Zülke <[email protected]>
300
+     * @since      0.10.0
301
+     */
302
+    public function appendAttributeByRef($name, &$value)
303
+    {
304
+        $this->container->appendAttributeByRef($name, $value);
305
+    }
306 306
 
307
-	/**
308
-	 * @see        AttributeHolder::setAttributes()
309
-	 *
310
-	 * @author     David Zülke <[email protected]>
311
-	 * @since      0.9.0
312
-	 */
313
-	public function setAttributes(array $attributes)
314
-	{
315
-		$this->container->setAttributes($attributes);
316
-	}
307
+    /**
308
+     * @see        AttributeHolder::setAttributes()
309
+     *
310
+     * @author     David Zülke <[email protected]>
311
+     * @since      0.9.0
312
+     */
313
+    public function setAttributes(array $attributes)
314
+    {
315
+        $this->container->setAttributes($attributes);
316
+    }
317 317
 
318
-	/**
319
-	 * @see        AttributeHolder::setAttributesByRef()
320
-	 *
321
-	 * @author     David Zülke <[email protected]>
322
-	 * @since      0.9.0
323
-	 */
324
-	public function setAttributesByRef(array &$attributes)
325
-	{
326
-		$this->container->setAttributesByRef($attributes);
327
-	}
318
+    /**
319
+     * @see        AttributeHolder::setAttributesByRef()
320
+     *
321
+     * @author     David Zülke <[email protected]>
322
+     * @since      0.9.0
323
+     */
324
+    public function setAttributesByRef(array &$attributes)
325
+    {
326
+        $this->container->setAttributesByRef($attributes);
327
+    }
328 328
 }
329 329
 
330 330
 ?>
331 331
\ No newline at end of file
Please login to merge, or discard this patch.
src/response/SoapResponse.class.php 1 patch
Indentation   +267 added lines, -267 removed lines patch added patch discarded remove patch
@@ -30,294 +30,294 @@
 block discarded – undo
30 30
  */
31 31
 class SoapResponse extends Response
32 32
 {
33
-	/**
34
-	 * @var        mixed The content to send back with this response.
35
-	 */
36
-	protected $content = null;
33
+    /**
34
+     * @var        mixed The content to send back with this response.
35
+     */
36
+    protected $content = null;
37 37
 	
38
-	/**
39
-	 * @var        array An array of SOAP headers to send with the response.
40
-	 */
41
-	protected $soapHeaders = array();
38
+    /**
39
+     * @var        array An array of SOAP headers to send with the response.
40
+     */
41
+    protected $soapHeaders = array();
42 42
 	
43
-	/**
44
-	 * Import response metadata (SOAP headers) from another response.
45
-	 *
46
-	 * @param      Response $otherResponse The other response to import information from.
47
-	 *
48
-	 * @author     David Zülke <[email protected]>
49
-	 * @since      0.11.0
50
-	 */
51
-	public function merge(Response $otherResponse)
52
-	{
53
-		parent::merge($otherResponse);
43
+    /**
44
+     * Import response metadata (SOAP headers) from another response.
45
+     *
46
+     * @param      Response $otherResponse The other response to import information from.
47
+     *
48
+     * @author     David Zülke <[email protected]>
49
+     * @since      0.11.0
50
+     */
51
+    public function merge(Response $otherResponse)
52
+    {
53
+        parent::merge($otherResponse);
54 54
 		
55
-		if($otherResponse instanceof SoapResponse) {
56
-			foreach($otherResponse->getSoapHeaders() as $soapHeader) {
57
-				if(!$this->hasSoapHeader($soapHeader->namespace, $soapHeader->name)) {
58
-					$this->addSoapHeader($soapHeader);
59
-				}
60
-			}
61
-		}
62
-	}
55
+        if($otherResponse instanceof SoapResponse) {
56
+            foreach($otherResponse->getSoapHeaders() as $soapHeader) {
57
+                if(!$this->hasSoapHeader($soapHeader->namespace, $soapHeader->name)) {
58
+                    $this->addSoapHeader($soapHeader);
59
+                }
60
+            }
61
+        }
62
+    }
63 63
 	
64
-	/**
65
-	 * Redirect externally. Not implemented here.
66
-	 *
67
-	 * @param      mixed $to Where to redirect.
68
-	 *
69
-	 * @throws     \BadMethodCallException
70
-	 *
71
-	 * @author     David Zülke <[email protected]>
72
-	 * @since      0.11.0
73
-	 */
74
-	public function setRedirect($to)
75
-	{
76
-		throw new \BadMethodCallException('Redirects are not implemented for SOAP.');
77
-	}
64
+    /**
65
+     * Redirect externally. Not implemented here.
66
+     *
67
+     * @param      mixed $to Where to redirect.
68
+     *
69
+     * @throws     \BadMethodCallException
70
+     *
71
+     * @author     David Zülke <[email protected]>
72
+     * @since      0.11.0
73
+     */
74
+    public function setRedirect($to)
75
+    {
76
+        throw new \BadMethodCallException('Redirects are not implemented for SOAP.');
77
+    }
78 78
 	
79
-	/**
80
-	 * Get info about the set redirect. Not implemented here.
81
-	 *
82
-	 * @return     array An assoc array of redirect info, or null if none set.
83
-	 *
84
-	 * @throws     \BadMethodCallException
85
-	 *
86
-	 * @author     David Zülke <[email protected]>
87
-	 * @since      0.11.0
88
-	 */
89
-	public function getRedirect()
90
-	{
91
-		throw new \BadMethodCallException('Redirects are not implemented for SOAP.');
92
-	}
79
+    /**
80
+     * Get info about the set redirect. Not implemented here.
81
+     *
82
+     * @return     array An assoc array of redirect info, or null if none set.
83
+     *
84
+     * @throws     \BadMethodCallException
85
+     *
86
+     * @author     David Zülke <[email protected]>
87
+     * @since      0.11.0
88
+     */
89
+    public function getRedirect()
90
+    {
91
+        throw new \BadMethodCallException('Redirects are not implemented for SOAP.');
92
+    }
93 93
 
94
-	/**
95
-	 * Check if a redirect is set. Not implemented here.
96
-	 *
97
-	 * @return     bool true, if a redirect is set, otherwise false
98
-	 *
99
-	 * @throws     \BadMethodCallException
100
-	 *
101
-	 * @author     David Zülke <[email protected]>
102
-	 * @since      0.11.0
103
-	 */
104
-	public function hasRedirect()
105
-	{
106
-		throw new \BadMethodCallException('Redirects are not implemented for SOAP.');
107
-	}
94
+    /**
95
+     * Check if a redirect is set. Not implemented here.
96
+     *
97
+     * @return     bool true, if a redirect is set, otherwise false
98
+     *
99
+     * @throws     \BadMethodCallException
100
+     *
101
+     * @author     David Zülke <[email protected]>
102
+     * @since      0.11.0
103
+     */
104
+    public function hasRedirect()
105
+    {
106
+        throw new \BadMethodCallException('Redirects are not implemented for SOAP.');
107
+    }
108 108
 
109
-	/**
110
-	 * Clear any set redirect information. Not implemented here.
111
-	 *
112
-	 * @throws     \BadMethodCallException
113
-	 *
114
-	 * @author     David Zülke <[email protected]>
115
-	 * @since      0.11.0
116
-	 */
117
-	public function clearRedirect()
118
-	{
119
-		throw new \BadMethodCallException('Redirects are not implemented for SOAP.');
120
-	}
109
+    /**
110
+     * Clear any set redirect information. Not implemented here.
111
+     *
112
+     * @throws     \BadMethodCallException
113
+     *
114
+     * @author     David Zülke <[email protected]>
115
+     * @since      0.11.0
116
+     */
117
+    public function clearRedirect()
118
+    {
119
+        throw new \BadMethodCallException('Redirects are not implemented for SOAP.');
120
+    }
121 121
 	
122
-	/**
123
-	 * @see        Response::isMutable()
124
-	 *
125
-	 * @author     David Zülke <[email protected]>
126
-	 * @since      0.11.0
127
-	 */
128
-	public function isContentMutable()
129
-	{
130
-		return false;
131
-	}
122
+    /**
123
+     * @see        Response::isMutable()
124
+     *
125
+     * @author     David Zülke <[email protected]>
126
+     * @since      0.11.0
127
+     */
128
+    public function isContentMutable()
129
+    {
130
+        return false;
131
+    }
132 132
 	
133
-	/**
134
-	 * Clear the content for this Response
135
-	 *
136
-	 * @return     bool Whether or not the operation was successful.
137
-	 *
138
-	 * @author     David Zülke <[email protected]>
139
-	 * @since      0.11.0
140
-	 */
141
-	public function clearContent()
142
-	{
143
-		$this->content = null;
144
-		return true;
145
-	}
133
+    /**
134
+     * Clear the content for this Response
135
+     *
136
+     * @return     bool Whether or not the operation was successful.
137
+     *
138
+     * @author     David Zülke <[email protected]>
139
+     * @since      0.11.0
140
+     */
141
+    public function clearContent()
142
+    {
143
+        $this->content = null;
144
+        return true;
145
+    }
146 146
 	
147
-	/**
148
-	 * Send all response data to the client.
149
-	 *
150
-	 * @author     David Zülke <[email protected]>
151
-	 * @since      0.11.0
152
-	 */
153
-	public function send(OutputType $outputType = null)
154
-	{
155
-		$this->sendSoapHeaders();
156
-		// don't send content, that's done by returning it from Dispatcher::dispatch(), so SoapServer::handle() deals with the rest
157
-		// $this->sendContent();
158
-	}
147
+    /**
148
+     * Send all response data to the client.
149
+     *
150
+     * @author     David Zülke <[email protected]>
151
+     * @since      0.11.0
152
+     */
153
+    public function send(OutputType $outputType = null)
154
+    {
155
+        $this->sendSoapHeaders();
156
+        // don't send content, that's done by returning it from Dispatcher::dispatch(), so SoapServer::handle() deals with the rest
157
+        // $this->sendContent();
158
+    }
159 159
 	
160
-	/**
161
-	 * Clear all response data.
162
-	 *
163
-	 * @author     David Zülke <[email protected]>
164
-	 * @since      0.11.0
165
-	 */
166
-	public function clear()
167
-	{
168
-		$this->clearContent();
169
-		$this->clearSoapHeaders();
170
-	}
160
+    /**
161
+     * Clear all response data.
162
+     *
163
+     * @author     David Zülke <[email protected]>
164
+     * @since      0.11.0
165
+     */
166
+    public function clear()
167
+    {
168
+        $this->clearContent();
169
+        $this->clearSoapHeaders();
170
+    }
171 171
 	
172
-	/**
173
-	 * Clear all SOAP headers from the response.
174
-	 *
175
-	 * @author     David Zülke <[email protected]>
176
-	 * @since      0.11.0
177
-	 */
178
-	public function clearSoapHeaders()
179
-	{
180
-		$this->soapHeaders = array();
181
-	}
172
+    /**
173
+     * Clear all SOAP headers from the response.
174
+     *
175
+     * @author     David Zülke <[email protected]>
176
+     * @since      0.11.0
177
+     */
178
+    public function clearSoapHeaders()
179
+    {
180
+        $this->soapHeaders = array();
181
+    }
182 182
 	
183
-	/**
184
-	 * Send SOAP Headers.
185
-	 *
186
-	 * @author     David Zülke <[email protected]>
187
-	 * @since      0.11.0
188
-	 */
189
-	public function sendSoapHeaders()
190
-	{
191
-		$server = $this->context->getDispatcher()->getSoapServer();
183
+    /**
184
+     * Send SOAP Headers.
185
+     *
186
+     * @author     David Zülke <[email protected]>
187
+     * @since      0.11.0
188
+     */
189
+    public function sendSoapHeaders()
190
+    {
191
+        $server = $this->context->getDispatcher()->getSoapServer();
192 192
 		
193
-		foreach($this->soapHeaders as $soapHeader) {
194
-			$server->addSoapHeader($soapHeader);
195
-		}
196
-	}
193
+        foreach($this->soapHeaders as $soapHeader) {
194
+            $server->addSoapHeader($soapHeader);
195
+        }
196
+    }
197 197
 	
198
-	/**
199
-	 * Get an array of all SOAP headers set on this response.
200
-	 *
201
-	 * @return     array An array of SoapHeader objects.
202
-	 *
203
-	 * @author     David Zülke <[email protected]>
204
-	 * @since      0.11.0
205
-	 */
206
-	public function getSoapHeaders()
207
-	{
208
-		return $this->soapHeaders;
209
-	}
198
+    /**
199
+     * Get an array of all SOAP headers set on this response.
200
+     *
201
+     * @return     array An array of SoapHeader objects.
202
+     *
203
+     * @author     David Zülke <[email protected]>
204
+     * @since      0.11.0
205
+     */
206
+    public function getSoapHeaders()
207
+    {
208
+        return $this->soapHeaders;
209
+    }
210 210
 	
211
-	/**
212
-	 * Get a SOAP Header from this response based on its namespace and name.
213
-	 *
214
-	 * @param      string $namespace The namespace of the SOAP header element.
215
-	 * @param      string $name The name of the SOAP header element.
216
-	 *
217
-	 * @return     \SoapHeader A SoapHeader, if found, otherwise null.
218
-	 *
219
-	 * @author     David Zülke <[email protected]>
220
-	 * @since      0.11.0
221
-	 */
222
-	public function getSoapHeader($namespace, $name)
223
-	{
224
-		if(($key = $this->searchSoapHeader($namespace, $name)) !== false) {
225
-			return $this->soapHeaders[$key];
226
-		}
227
-	}
211
+    /**
212
+     * Get a SOAP Header from this response based on its namespace and name.
213
+     *
214
+     * @param      string $namespace The namespace of the SOAP header element.
215
+     * @param      string $name The name of the SOAP header element.
216
+     *
217
+     * @return     \SoapHeader A SoapHeader, if found, otherwise null.
218
+     *
219
+     * @author     David Zülke <[email protected]>
220
+     * @since      0.11.0
221
+     */
222
+    public function getSoapHeader($namespace, $name)
223
+    {
224
+        if(($key = $this->searchSoapHeader($namespace, $name)) !== false) {
225
+            return $this->soapHeaders[$key];
226
+        }
227
+    }
228 228
 	
229
-	/**
230
-	 * Add a SOAP Header to this response.
231
-	 *
232
-	 * @param      \SoapHeader $soapHeader The SOAP header to set.
233
-	 *
234
-	 * @author     David Zülke <[email protected]>
235
-	 * @since      0.11.0
236
-	 */
237
-	public function addSoapHeader(\SoapHeader $soapHeader)
238
-	{
239
-		$this->removeSoapHeader($soapHeader->namespace, $soapHeader->name);
240
-		$this->soapHeaders[] = $soapHeader;
241
-	}
229
+    /**
230
+     * Add a SOAP Header to this response.
231
+     *
232
+     * @param      \SoapHeader $soapHeader The SOAP header to set.
233
+     *
234
+     * @author     David Zülke <[email protected]>
235
+     * @since      0.11.0
236
+     */
237
+    public function addSoapHeader(\SoapHeader $soapHeader)
238
+    {
239
+        $this->removeSoapHeader($soapHeader->namespace, $soapHeader->name);
240
+        $this->soapHeaders[] = $soapHeader;
241
+    }
242 242
 	
243
-	/**
244
-	 * Set a SOAP header into this response.
245
-	 *
246
-	 * This method has the same signature as PHP's SoapHeader->__construct().
247
-	 *
248
-	 * @param      string $namespace The namespace of the SOAP header element.
249
-	 * @param      string $name The name of the SOAP header element.
250
-	 * @param      mixed  $data A SOAP header's content. It can be a PHP value or a
251
-	 *                    SoapVar object.
252
-	 * @param      bool   $mustUnderstand Value of the mustUnderstand attribute of the SOAP header
253
-	 *                    element.
254
-	 * @param      mixed  $actor Value of the actor attribute of the SOAP header element.
255
-	 *
256
-	 * @author     David Zülke <[email protected]>
257
-	 * @since      0.11.0
258
-	 */
259
-	public function setSoapHeader($namespace, $name, $data = null, $mustUnderstand = false, $actor = null)
260
-	{
261
-		if($actor === null) {
262
-			$h = new \SoapHeader($namespace, $name, $data, $mustUnderstand);
263
-		} else {
264
-			$h = new \SoapHeader($namespace, $name, $data, $mustUnderstand, $actor);
265
-		}
266
-		$this->addSoapHeader($h);
267
-	}
243
+    /**
244
+     * Set a SOAP header into this response.
245
+     *
246
+     * This method has the same signature as PHP's SoapHeader->__construct().
247
+     *
248
+     * @param      string $namespace The namespace of the SOAP header element.
249
+     * @param      string $name The name of the SOAP header element.
250
+     * @param      mixed  $data A SOAP header's content. It can be a PHP value or a
251
+     *                    SoapVar object.
252
+     * @param      bool   $mustUnderstand Value of the mustUnderstand attribute of the SOAP header
253
+     *                    element.
254
+     * @param      mixed  $actor Value of the actor attribute of the SOAP header element.
255
+     *
256
+     * @author     David Zülke <[email protected]>
257
+     * @since      0.11.0
258
+     */
259
+    public function setSoapHeader($namespace, $name, $data = null, $mustUnderstand = false, $actor = null)
260
+    {
261
+        if($actor === null) {
262
+            $h = new \SoapHeader($namespace, $name, $data, $mustUnderstand);
263
+        } else {
264
+            $h = new \SoapHeader($namespace, $name, $data, $mustUnderstand, $actor);
265
+        }
266
+        $this->addSoapHeader($h);
267
+    }
268 268
 	
269
-	/**
270
-	 * Remove a SOAP Header from this response based on its namespace and name.
271
-	 *
272
-	 * @param      string $namespace The namespace of the SOAP header element.
273
-	 * @param      string $name The name of the SOAP header element.
274
-	 *
275
-	 * @author     David Zülke <[email protected]>
276
-	 * @since      0.11.0
277
-	 */
278
-	public function removeSoapHeader($namespace, $name)
279
-	{
280
-		if(($key = $this->searchSoapHeader($namespace, $name)) !== false) {
281
-			unset($this->soapHeaders[$key]);
282
-		}
283
-	}
269
+    /**
270
+     * Remove a SOAP Header from this response based on its namespace and name.
271
+     *
272
+     * @param      string $namespace The namespace of the SOAP header element.
273
+     * @param      string $name The name of the SOAP header element.
274
+     *
275
+     * @author     David Zülke <[email protected]>
276
+     * @since      0.11.0
277
+     */
278
+    public function removeSoapHeader($namespace, $name)
279
+    {
280
+        if(($key = $this->searchSoapHeader($namespace, $name)) !== false) {
281
+            unset($this->soapHeaders[$key]);
282
+        }
283
+    }
284 284
 	
285
-	/**
286
-	 * Check if a SOAP Header has been set based on its namespace and name.
287
-	 *
288
-	 * @param      string $namespace The namespace of the SOAP header element.
289
-	 * @param      string $name The name of the SOAP header element.
290
-	 *
291
-	 * @return     bool true, if this SOAP header has been set, false otherwise.
292
-	 *
293
-	 * @author     David Zülke <[email protected]>
294
-	 * @since      0.11.0
295
-	 */
296
-	public function hasSoapHeader($namespace, $name)
297
-	{
298
-		return $this->searchSoapHeader($namespace, $name) !== false;
299
-	}
285
+    /**
286
+     * Check if a SOAP Header has been set based on its namespace and name.
287
+     *
288
+     * @param      string $namespace The namespace of the SOAP header element.
289
+     * @param      string $name The name of the SOAP header element.
290
+     *
291
+     * @return     bool true, if this SOAP header has been set, false otherwise.
292
+     *
293
+     * @author     David Zülke <[email protected]>
294
+     * @since      0.11.0
295
+     */
296
+    public function hasSoapHeader($namespace, $name)
297
+    {
298
+        return $this->searchSoapHeader($namespace, $name) !== false;
299
+    }
300 300
 	
301
-	/**
302
-	 * Find the key of a SOAP Header based on its namespace and name.
303
-	 *
304
-	 * @param      string $namespace The namespace of the SOAP header element.
305
-	 * @param      string $name The name of the SOAP header element.
306
-	 *
307
-	 * @return     int The key of the SOAP header in the array, otherwise false.
308
-	 *
309
-	 * @author     David Zülke <[email protected]>
310
-	 * @since      0.11.0
311
-	 */
312
-	protected function searchSoapHeader($namespace, $name)
313
-	{
314
-		foreach($this->soapHeaders as $key => $soapHeader) {
315
-			if($soapHeader->namespace == $namespace && $soapHeader->name == $name) {
316
-				return $key;
317
-			}
318
-		}
319
-		return false;
320
-	}
301
+    /**
302
+     * Find the key of a SOAP Header based on its namespace and name.
303
+     *
304
+     * @param      string $namespace The namespace of the SOAP header element.
305
+     * @param      string $name The name of the SOAP header element.
306
+     *
307
+     * @return     int The key of the SOAP header in the array, otherwise false.
308
+     *
309
+     * @author     David Zülke <[email protected]>
310
+     * @since      0.11.0
311
+     */
312
+    protected function searchSoapHeader($namespace, $name)
313
+    {
314
+        foreach($this->soapHeaders as $key => $soapHeader) {
315
+            if($soapHeader->namespace == $namespace && $soapHeader->name == $name) {
316
+                return $key;
317
+            }
318
+        }
319
+        return false;
320
+    }
321 321
 }
322 322
 
323 323
 ?>
324 324
\ No newline at end of file
Please login to merge, or discard this patch.
src/response/Response.class.php 1 patch
Indentation   +314 added lines, -314 removed lines patch added patch discarded remove patch
@@ -34,351 +34,351 @@
 block discarded – undo
34 34
  */
35 35
 abstract class Response extends AttributeHolder
36 36
 {
37
-	/**
38
-	 * @var        Context An Context instance.
39
-	 */
40
-	protected $context = null;
37
+    /**
38
+     * @var        Context An Context instance.
39
+     */
40
+    protected $context = null;
41 41
 	
42
-	/**
43
-	 * @var        mixed The content to send back to the client.
44
-	 */
45
-	protected $content = null;
42
+    /**
43
+     * @var        mixed The content to send back to the client.
44
+     */
45
+    protected $content = null;
46 46
 	
47
-	/**
48
-	 * @var        OutputType The output type of this response.
49
-	 */
50
-	protected $outputType = null;
47
+    /**
48
+     * @var        OutputType The output type of this response.
49
+     */
50
+    protected $outputType = null;
51 51
 	
52
-	/**
53
-	 * Pre-serialization callback.
54
-	 *
55
-	 * Will set the name of the context and exclude the instance from serializing.
56
-	 *
57
-	 * @author     David Zülke <[email protected]>
58
-	 * @since      0.11.0
59
-	 */
60
-	public function __sleep()
61
-	{
62
-		$vars = get_object_vars($this);
63
-		$also = array();
52
+    /**
53
+     * Pre-serialization callback.
54
+     *
55
+     * Will set the name of the context and exclude the instance from serializing.
56
+     *
57
+     * @author     David Zülke <[email protected]>
58
+     * @since      0.11.0
59
+     */
60
+    public function __sleep()
61
+    {
62
+        $vars = get_object_vars($this);
63
+        $also = array();
64 64
 		
65
-		$this->contextName = $this->context->getName();
66
-		unset($vars['context']);
67
-		$also[] = 'contextName';
65
+        $this->contextName = $this->context->getName();
66
+        unset($vars['context']);
67
+        $also[] = 'contextName';
68 68
 		
69
-		if($this->outputType) {
70
-			$this->outputTypeName = $this->outputType->getName();
71
-			unset($vars['outputType']);
72
-			$also[] = 'outputTypeName';
73
-		}
69
+        if($this->outputType) {
70
+            $this->outputTypeName = $this->outputType->getName();
71
+            unset($vars['outputType']);
72
+            $also[] = 'outputTypeName';
73
+        }
74 74
 		
75
-		if(is_resource($this->content)) {
76
-			$this->contentStreamMeta = stream_get_meta_data($this->content);
77
-			unset($vars['content']);
78
-			$also[] = 'contentStreamMeta';
79
-		}
75
+        if(is_resource($this->content)) {
76
+            $this->contentStreamMeta = stream_get_meta_data($this->content);
77
+            unset($vars['content']);
78
+            $also[] = 'contentStreamMeta';
79
+        }
80 80
 		
81
-		return array_merge(array_keys($vars), $also);
82
-	}
81
+        return array_merge(array_keys($vars), $also);
82
+    }
83 83
 	
84
-	/**
85
-	 * Post-unserialization callback.
86
-	 *
87
-	 * Will restore the context based on the names set by __sleep.
88
-	 *
89
-	 * @author     David Zülke <[email protected]>
90
-	 * @since      0.11.0
91
-	 */
92
-	public function __wakeup()
93
-	{
94
-		$this->context = Context::getInstance($this->contextName);
95
-		unset($this->contextName);
84
+    /**
85
+     * Post-unserialization callback.
86
+     *
87
+     * Will restore the context based on the names set by __sleep.
88
+     *
89
+     * @author     David Zülke <[email protected]>
90
+     * @since      0.11.0
91
+     */
92
+    public function __wakeup()
93
+    {
94
+        $this->context = Context::getInstance($this->contextName);
95
+        unset($this->contextName);
96 96
 		
97
-		if(isset($this->outputTypeName)) {
98
-			$this->outputType = $this->context->getDispatcher()->getOutputType($this->outputTypeName);
99
-			unset($this->outputTypeName);
100
-		}
97
+        if(isset($this->outputTypeName)) {
98
+            $this->outputType = $this->context->getDispatcher()->getOutputType($this->outputTypeName);
99
+            unset($this->outputTypeName);
100
+        }
101 101
 		
102
-		if(isset($this->contentStreamMeta)) {
103
-			// contrary to what the documentation says, stream_get_meta_data() will not return a list of filters attached to the stream, so we cannot restore these, unfortunately.
104
-			$this->content = fopen($this->contentStreamMeta['uri'], $this->contentStreamMeta['mode']);
105
-			unset($this->contentStreamMeta);
106
-		}
107
-	}
102
+        if(isset($this->contentStreamMeta)) {
103
+            // contrary to what the documentation says, stream_get_meta_data() will not return a list of filters attached to the stream, so we cannot restore these, unfortunately.
104
+            $this->content = fopen($this->contentStreamMeta['uri'], $this->contentStreamMeta['mode']);
105
+            unset($this->contentStreamMeta);
106
+        }
107
+    }
108 108
 	
109
-	/**
110
-	 * Retrieve the Context instance this Response object belongs to.
111
-	 *
112
-	 * @return     Context An Context instance.
113
-	 *
114
-	 * @author     David Zülke <[email protected]>
115
-	 * @since      0.11.0
116
-	 */
117
-	public final function getContext()
118
-	{
119
-		return $this->context;
120
-	}
109
+    /**
110
+     * Retrieve the Context instance this Response object belongs to.
111
+     *
112
+     * @return     Context An Context instance.
113
+     *
114
+     * @author     David Zülke <[email protected]>
115
+     * @since      0.11.0
116
+     */
117
+    public final function getContext()
118
+    {
119
+        return $this->context;
120
+    }
121 121
 	
122
-	/**
123
-	 * Initialize this Response.
124
-	 *
125
-	 * @param      Context $context    An Context instance.
126
-	 * @param      array   $parameters An array of initialization parameters.
127
-	 *
128
-	 * @author     David Zülke <[email protected]>
129
-	 * @since      0.11.0
130
-	 */
131
-	public function initialize(Context $context, array $parameters = array())
132
-	{
133
-		$this->context = $context;
134
-		$this->setParameters($parameters);
135
-	}
122
+    /**
123
+     * Initialize this Response.
124
+     *
125
+     * @param      Context $context    An Context instance.
126
+     * @param      array   $parameters An array of initialization parameters.
127
+     *
128
+     * @author     David Zülke <[email protected]>
129
+     * @since      0.11.0
130
+     */
131
+    public function initialize(Context $context, array $parameters = array())
132
+    {
133
+        $this->context = $context;
134
+        $this->setParameters($parameters);
135
+    }
136 136
 	
137
-	/**
138
-	 * Get the Output Type to use with this response.
139
-	 *
140
-	 * @return     OutputType The Output Type instance associated with.
141
-	 *
142
-	 * @author     David Zülke <[email protected]>
143
-	 * @since      0.11.1
144
-	 */
145
-	public function getOutputType()
146
-	{
147
-		return $this->outputType;
148
-	}
137
+    /**
138
+     * Get the Output Type to use with this response.
139
+     *
140
+     * @return     OutputType The Output Type instance associated with.
141
+     *
142
+     * @author     David Zülke <[email protected]>
143
+     * @since      0.11.1
144
+     */
145
+    public function getOutputType()
146
+    {
147
+        return $this->outputType;
148
+    }
149 149
 	
150
-	/**
151
-	 * Set the Output Type to use with this response.
152
-	 *
153
-	 * @param      OutputType $outputType The Output Type instance to associate with.
154
-	 *
155
-	 * @author     David Zülke <[email protected]>
156
-	 * @since      0.11.1
157
-	 */
158
-	public function setOutputType(OutputType $outputType)
159
-	{
160
-		$this->outputType = $outputType;
161
-	}
150
+    /**
151
+     * Set the Output Type to use with this response.
152
+     *
153
+     * @param      OutputType $outputType The Output Type instance to associate with.
154
+     *
155
+     * @author     David Zülke <[email protected]>
156
+     * @since      0.11.1
157
+     */
158
+    public function setOutputType(OutputType $outputType)
159
+    {
160
+        $this->outputType = $outputType;
161
+    }
162 162
 	
163
-	/**
164
-	 * Clear the Output Type to use with this response.
165
-	 *
166
-	 * @author     David Zülke <[email protected]>
167
-	 * @since      0.11.1
168
-	 */
169
-	public function clearOutputType()
170
-	{
171
-		$this->outputType = null;
172
-	}
163
+    /**
164
+     * Clear the Output Type to use with this response.
165
+     *
166
+     * @author     David Zülke <[email protected]>
167
+     * @since      0.11.1
168
+     */
169
+    public function clearOutputType()
170
+    {
171
+        $this->outputType = null;
172
+    }
173 173
 	
174
-	/**
175
-	 * Retrieve the content set for this Response.
176
-	 *
177
-	 * @return     mixed The content set in this Response.
178
-	 *
179
-	 * @author     David Zülke <[email protected]>
180
-	 * @since      0.11.0
181
-	 */
182
-	public function getContent()
183
-	{
184
-		return $this->content;
185
-	}
174
+    /**
175
+     * Retrieve the content set for this Response.
176
+     *
177
+     * @return     mixed The content set in this Response.
178
+     *
179
+     * @author     David Zülke <[email protected]>
180
+     * @since      0.11.0
181
+     */
182
+    public function getContent()
183
+    {
184
+        return $this->content;
185
+    }
186 186
 	
187
-	/**
188
-	 * Check whether or not some content is set.
189
-	 *
190
-	 * @return     bool If any content is set, false otherwise.
191
-	 *
192
-	 * @author     David Zülke <[email protected]>
193
-	 * @since      0.11.6
194
-	 */
195
-	public function hasContent()
196
-	{
197
-		return $this->content !== null;
198
-	}
187
+    /**
188
+     * Check whether or not some content is set.
189
+     *
190
+     * @return     bool If any content is set, false otherwise.
191
+     *
192
+     * @author     David Zülke <[email protected]>
193
+     * @since      0.11.6
194
+     */
195
+    public function hasContent()
196
+    {
197
+        return $this->content !== null;
198
+    }
199 199
 	
200
-	/**
201
-	 * Retrieve the size (in bytes) of the content set for this Response.
202
-	 *
203
-	 * @return     int The content size in bytes.
204
-	 *
205
-	 * @author     David Zülke <[email protected]>
206
-	 * @since      0.11.0
207
-	 */
208
-	public function getContentSize()
209
-	{
210
-		if(is_resource($this->content)) {
211
-			if(($stat = fstat($this->content)) !== false) {
212
-				return $stat['size'];
213
-			} else {
214
-				return false;
215
-			}
216
-		} else {
217
-			return strlen($this->content);
218
-		}
219
-	}
200
+    /**
201
+     * Retrieve the size (in bytes) of the content set for this Response.
202
+     *
203
+     * @return     int The content size in bytes.
204
+     *
205
+     * @author     David Zülke <[email protected]>
206
+     * @since      0.11.0
207
+     */
208
+    public function getContentSize()
209
+    {
210
+        if(is_resource($this->content)) {
211
+            if(($stat = fstat($this->content)) !== false) {
212
+                return $stat['size'];
213
+            } else {
214
+                return false;
215
+            }
216
+        } else {
217
+            return strlen($this->content);
218
+        }
219
+    }
220 220
 	
221
-	/**
222
-	 * Set the content for this Response.
223
-	 *
224
-	 * @param      mixed $content The content to be sent in this Response.
225
-	 *
226
-	 * @author     David Zülke <[email protected]>
227
-	 * @since      0.11.0
228
-	 */
229
-	public function setContent($content)
230
-	{
231
-		$this->content = $content;
232
-	}
221
+    /**
222
+     * Set the content for this Response.
223
+     *
224
+     * @param      mixed $content The content to be sent in this Response.
225
+     *
226
+     * @author     David Zülke <[email protected]>
227
+     * @since      0.11.0
228
+     */
229
+    public function setContent($content)
230
+    {
231
+        $this->content = $content;
232
+    }
233 233
 	
234
-	/**
235
-	 * Prepend content to the existing content for this Response.
236
-	 *
237
-	 * @param      mixed $content The content to be prepended to this Response.
238
-	 *
239
-	 * @author     David Zülke <[email protected]>
240
-	 * @since      0.11.0
241
-	 */
242
-	public function prependContent($content)
243
-	{
244
-		$this->setContent($content . $this->getContent());
245
-	}
234
+    /**
235
+     * Prepend content to the existing content for this Response.
236
+     *
237
+     * @param      mixed $content The content to be prepended to this Response.
238
+     *
239
+     * @author     David Zülke <[email protected]>
240
+     * @since      0.11.0
241
+     */
242
+    public function prependContent($content)
243
+    {
244
+        $this->setContent($content . $this->getContent());
245
+    }
246 246
 	
247
-	/**
248
-	 * Append content to the existing content for this Response.
249
-	 *
250
-	 * @param      mixed $content The content to be appended to this Response.
251
-	 *
252
-	 * @author     David Zülke <[email protected]>
253
-	 * @since      0.11.0
254
-	 */
255
-	public function appendContent($content)
256
-	{
257
-		$this->setContent($this->getContent() . $content);
258
-	}
247
+    /**
248
+     * Append content to the existing content for this Response.
249
+     *
250
+     * @param      mixed $content The content to be appended to this Response.
251
+     *
252
+     * @author     David Zülke <[email protected]>
253
+     * @since      0.11.0
254
+     */
255
+    public function appendContent($content)
256
+    {
257
+        $this->setContent($this->getContent() . $content);
258
+    }
259 259
 	
260
-	/**
261
-	 * Clear the content for this Response
262
-	 *
263
-	 * @author     David Zülke <[email protected]>
264
-	 * @since      0.11.0
265
-	 */
266
-	public function clearContent()
267
-	{
268
-		$this->content = null;
269
-	}
260
+    /**
261
+     * Clear the content for this Response
262
+     *
263
+     * @author     David Zülke <[email protected]>
264
+     * @since      0.11.0
265
+     */
266
+    public function clearContent()
267
+    {
268
+        $this->content = null;
269
+    }
270 270
 	
271
-	/**
272
-	 * Redirect externally.
273
-	 *
274
-	 * @param      mixed $to Where to redirect.
275
-	 *
276
-	 * @author     David Zülke <[email protected]>
277
-	 * @since      0.11.0
278
-	 */
279
-	abstract public function setRedirect($to);
271
+    /**
272
+     * Redirect externally.
273
+     *
274
+     * @param      mixed $to Where to redirect.
275
+     *
276
+     * @author     David Zülke <[email protected]>
277
+     * @since      0.11.0
278
+     */
279
+    abstract public function setRedirect($to);
280 280
 
281
-	/**
282
-	 * Get info about the set redirect.
283
-	 *
284
-	 * @return     array An assoc array of redirect info, or null if none set.
285
-	 *
286
-	 * @author     David Zülke <[email protected]>
287
-	 * @since      0.11.0
288
-	 */
289
-	abstract public function getRedirect();
281
+    /**
282
+     * Get info about the set redirect.
283
+     *
284
+     * @return     array An assoc array of redirect info, or null if none set.
285
+     *
286
+     * @author     David Zülke <[email protected]>
287
+     * @since      0.11.0
288
+     */
289
+    abstract public function getRedirect();
290 290
 
291
-	/**
292
-	 * Check if a redirect is set.
293
-	 *
294
-	 * @return     bool true, if a redirect is set, otherwise false
295
-	 *
296
-	 * @author     David Zülke <[email protected]>
297
-	 * @since      0.11.0
298
-	 */
299
-	abstract public function hasRedirect();
291
+    /**
292
+     * Check if a redirect is set.
293
+     *
294
+     * @return     bool true, if a redirect is set, otherwise false
295
+     *
296
+     * @author     David Zülke <[email protected]>
297
+     * @since      0.11.0
298
+     */
299
+    abstract public function hasRedirect();
300 300
 
301
-	/**
302
-	 * Clear any set redirect information.
303
-	 *
304
-	 * @author     David Zülke <[email protected]>
305
-	 * @since      0.11.0
306
-	 */
307
-	abstract public function clearRedirect();
301
+    /**
302
+     * Clear any set redirect information.
303
+     *
304
+     * @author     David Zülke <[email protected]>
305
+     * @since      0.11.0
306
+     */
307
+    abstract public function clearRedirect();
308 308
 
309
-	/**
310
-	 * Import response metadata from another response.
311
-	 *
312
-	 * @param      Response $otherResponse The other response to import information from.
313
-	 *
314
-	 * @author     David Zülke <[email protected]>
315
-	 * @since      0.11.0
316
-	 */
317
-	public function merge(Response $otherResponse)
318
-	{
319
-		foreach($otherResponse->getAttributeNamespaces() as $namespace) {
320
-			foreach($otherResponse->getAttributes($namespace) as $name => $value) {
321
-				if(!$this->hasAttribute($name, $namespace)) {
322
-					$this->setAttribute($name, $value, $namespace);
323
-				} elseif(is_array($value)) {
324
-					$thisAttribute =& $this->getAttribute($name, $namespace);
325
-					if(is_array($thisAttribute)) {
326
-						$thisAttribute = array_merge($value, $thisAttribute);
327
-					}
328
-				}
329
-			}
330
-		}
331
-	}
309
+    /**
310
+     * Import response metadata from another response.
311
+     *
312
+     * @param      Response $otherResponse The other response to import information from.
313
+     *
314
+     * @author     David Zülke <[email protected]>
315
+     * @since      0.11.0
316
+     */
317
+    public function merge(Response $otherResponse)
318
+    {
319
+        foreach($otherResponse->getAttributeNamespaces() as $namespace) {
320
+            foreach($otherResponse->getAttributes($namespace) as $name => $value) {
321
+                if(!$this->hasAttribute($name, $namespace)) {
322
+                    $this->setAttribute($name, $value, $namespace);
323
+                } elseif(is_array($value)) {
324
+                    $thisAttribute =& $this->getAttribute($name, $namespace);
325
+                    if(is_array($thisAttribute)) {
326
+                        $thisAttribute = array_merge($value, $thisAttribute);
327
+                    }
328
+                }
329
+            }
330
+        }
331
+    }
332 332
 	
333
-	/**
334
-	 * Clear all data for this Response.
335
-	 *
336
-	 * @author     David Zülke <[email protected]>
337
-	 * @since      0.11.0
338
-	 */
339
-	abstract public function clear();
333
+    /**
334
+     * Clear all data for this Response.
335
+     *
336
+     * @author     David Zülke <[email protected]>
337
+     * @since      0.11.0
338
+     */
339
+    abstract public function clear();
340 340
 	
341
-	/**
342
-	 * Send all response data to the client.
343
-	 *
344
-	 * @param      OutputType $outputType An optional Output Type object with information
345
-	 *                                    the response can use to send additional data.
346
-	 *
347
-	 * @author     David Zülke <[email protected]>
348
-	 * @since      0.11.0
349
-	 */
350
-	abstract public function send(OutputType $outputType = null);
341
+    /**
342
+     * Send all response data to the client.
343
+     *
344
+     * @param      OutputType $outputType An optional Output Type object with information
345
+     *                                    the response can use to send additional data.
346
+     *
347
+     * @author     David Zülke <[email protected]>
348
+     * @since      0.11.0
349
+     */
350
+    abstract public function send(OutputType $outputType = null);
351 351
 	
352
-	/**
353
-	 * Determine whether the content in the response may be modified by appending
354
-	 * or prepending data using string operations. Typically false for streams, 
355
-	 * and for responses like XMLRPC where the content is an array.
356
-	 *
357
-	 * @return     bool If the content can be treated as / changed like a string.
358
-	 *
359
-	 * @author     David Zülke <[email protected]>
360
-	 * @since      0.11.0
361
-	 */
362
-	public function isContentMutable()
363
-	{
364
-		return !$this->hasRedirect() && !is_resource($this->content);
365
-	}
352
+    /**
353
+     * Determine whether the content in the response may be modified by appending
354
+     * or prepending data using string operations. Typically false for streams, 
355
+     * and for responses like XMLRPC where the content is an array.
356
+     *
357
+     * @return     bool If the content can be treated as / changed like a string.
358
+     *
359
+     * @author     David Zülke <[email protected]>
360
+     * @since      0.11.0
361
+     */
362
+    public function isContentMutable()
363
+    {
364
+        return !$this->hasRedirect() && !is_resource($this->content);
365
+    }
366 366
 	
367
-	/**
368
-	 * Send the content for this response
369
-	 *
370
-	 * @author     David Zülke <[email protected]>
371
-	 * @since      0.11.0
372
-	 */
373
-	protected function sendContent()
374
-	{
375
-		if(is_resource($this->content)) {
376
-			fpassthru($this->content);
377
-			fclose($this->content);
378
-		} else {
379
-			echo $this->content;
380
-		}
381
-	}
367
+    /**
368
+     * Send the content for this response
369
+     *
370
+     * @author     David Zülke <[email protected]>
371
+     * @since      0.11.0
372
+     */
373
+    protected function sendContent()
374
+    {
375
+        if(is_resource($this->content)) {
376
+            fpassthru($this->content);
377
+            fclose($this->content);
378
+        } else {
379
+            echo $this->content;
380
+        }
381
+    }
382 382
 }
383 383
 
384 384
 ?>
385 385
\ No newline at end of file
Please login to merge, or discard this patch.
src/routing/WebRouting.class.php 2 patches
Indentation   +398 added lines, -398 removed lines patch added patch discarded remove patch
@@ -34,412 +34,412 @@
 block discarded – undo
34 34
  */
35 35
 class WebRouting extends Routing
36 36
 {
37
-	/**
38
-	 * @var        string The path to the application's root with trailing slash.
39
-	 */
40
-	protected $basePath = '';
41
-
42
-	/**
43
-	 * @var        string The URL to the application's root with trailing slash.
44
-	 */
45
-	protected $baseHref = '';
46
-
47
-	/**
48
-	 * @var        array The GET parameters that were passed in the URL.
49
-	 */
50
-	protected $inputParameters = array();
51
-
52
-	/**
53
-	 * @var        array arg_separator.input as defined in php.ini, exploded
54
-	 */
55
-	protected $argSeparatorInput = array('&');
56
-
57
-	/**
58
-	 * @var        string arg_separator.output as defined in php.ini
59
-	 */
60
-	protected $argSeparatorOutput = '&amp;';
61
-
62
-	/**
63
-	 * Constructor.
64
-	 *
65
-	 * @author     David Zülke <[email protected]>
66
-	 * @since      0.11.0
67
-	 */
68
-	public function __construct()
69
-	{
70
-		parent::__construct();
71
-
72
-		$this->defaultGenOptions = array_merge($this->defaultGenOptions, array(
73
-			// separator, typically &amp; for HTML, & otherwise
74
-			'separator' => '&amp;',
75
-			// whether or not to append the SID if necessary
76
-			'use_trans_sid' => false,
77
-			// scheme, or true to include, or false to block
78
-			'scheme' => null,
79
-			// authority, or true to include, or false to block
80
-			'authority' => null,
81
-			// host, or true to include, or false to block
82
-			'host' => null,
83
-			// port, or true to include, or false to block
84
-			'port' => null,
85
-			// fragment identifier (#foo)
86
-			'fragment' => null,
87
-		));
37
+    /**
38
+     * @var        string The path to the application's root with trailing slash.
39
+     */
40
+    protected $basePath = '';
41
+
42
+    /**
43
+     * @var        string The URL to the application's root with trailing slash.
44
+     */
45
+    protected $baseHref = '';
46
+
47
+    /**
48
+     * @var        array The GET parameters that were passed in the URL.
49
+     */
50
+    protected $inputParameters = array();
51
+
52
+    /**
53
+     * @var        array arg_separator.input as defined in php.ini, exploded
54
+     */
55
+    protected $argSeparatorInput = array('&');
56
+
57
+    /**
58
+     * @var        string arg_separator.output as defined in php.ini
59
+     */
60
+    protected $argSeparatorOutput = '&amp;';
61
+
62
+    /**
63
+     * Constructor.
64
+     *
65
+     * @author     David Zülke <[email protected]>
66
+     * @since      0.11.0
67
+     */
68
+    public function __construct()
69
+    {
70
+        parent::__construct();
71
+
72
+        $this->defaultGenOptions = array_merge($this->defaultGenOptions, array(
73
+            // separator, typically &amp; for HTML, & otherwise
74
+            'separator' => '&amp;',
75
+            // whether or not to append the SID if necessary
76
+            'use_trans_sid' => false,
77
+            // scheme, or true to include, or false to block
78
+            'scheme' => null,
79
+            // authority, or true to include, or false to block
80
+            'authority' => null,
81
+            // host, or true to include, or false to block
82
+            'host' => null,
83
+            // port, or true to include, or false to block
84
+            'port' => null,
85
+            // fragment identifier (#foo)
86
+            'fragment' => null,
87
+        ));
88 88
 		
89
-		$this->argSeparatorInput = str_split(ini_get('arg_separator.input'));
90
-		$this->argSeparatorOutput = ini_get('arg_separator.output');
91
-	}
92
-
93
-	/**
94
-	 * Initialize the routing instance.
95
-	 *
96
-	 * @param      Context $context The Context.
97
-	 * @param      array   $parameters An array of initialization parameters.
98
-	 *
99
-	 * @author     David Zülke <[email protected]>
100
-	 * @author     Veikko Mäkinen <[email protected]>
101
-	 * @author     Dominik del Bondio <[email protected]>
102
-	 * @since      0.11.0
103
-	 */
104
-	public function initialize(Context $context, array $parameters = array())
105
-	{
106
-		parent::initialize($context, $parameters);
107
-
108
-		/** @var WebRequest $rq */
109
-		$rq = $this->context->getRequest();
110
-
111
-		/** @var RequestDataHolder $rd */
112
-		$rd = $rq->getRequestData();
113
-
114
-		// 'scheme://authority' is necessary so parse_url doesn't stumble over '://' in the request URI
115
-		$ru = array_merge(array('path' => '', 'query' => ''), parse_url('scheme://authority' . $rq->getRequestUri()));
116
-
117
-		if(isset($_SERVER['QUERY_STRING'])) {
118
-			$qs = $_SERVER['QUERY_STRING'];
119
-		} else {
120
-			$qs = '';
121
-		}
122
-
123
-		// when rewriting, apache strips one (not all) trailing ampersand from the end of QUERY_STRING... normalize:
124
-		$rewritten = (preg_replace('/&+$/D', '', $qs) !== preg_replace('/&+$/D', '', $ru['query']));
125
-
126
-		if($this->isEnabled() && $rewritten) {
127
-			// strip the one trailing ampersand, see above
128
-			$queryWasEmptied = false;
129
-			if($ru['query'] !== '' && isset($_SERVER['SERVER_SOFTWARE']) && strpos($_SERVER['SERVER_SOFTWARE'], 'Apache') !== false) {
130
-				$ru['query'] = preg_replace('/&$/D', '', $ru['query']);
131
-				if($ru['query'] == '') {
132
-					$queryWasEmptied = true;
133
-				}
134
-			}
135
-
136
-			$stripFromQuery = '&' . $ru['query'];
137
-			if($ru['query'] == '' && !$queryWasEmptied && isset($_SERVER['SERVER_SOFTWARE']) && strpos($_SERVER['SERVER_SOFTWARE'], 'Apache') !== false) {
138
-				// if the query is empty, simply give apache2 nothing instead of an "&", since that could kill a real trailing ampersand in the path, as Apache strips those from the query string (which has the rewritten path), but not the request uri
139
-				$stripFromQuery = '';
140
-			}
141
-			$this->input = preg_replace('/' . preg_quote($stripFromQuery, '/') . '$/D', '', $qs);
142
-
143
-			if(isset($_SERVER['SERVER_SOFTWARE']) && strpos($_SERVER['SERVER_SOFTWARE'], 'Apache/2') !== false) {
144
-				$sru = $_SERVER['REQUEST_URI'];
89
+        $this->argSeparatorInput = str_split(ini_get('arg_separator.input'));
90
+        $this->argSeparatorOutput = ini_get('arg_separator.output');
91
+    }
92
+
93
+    /**
94
+     * Initialize the routing instance.
95
+     *
96
+     * @param      Context $context The Context.
97
+     * @param      array   $parameters An array of initialization parameters.
98
+     *
99
+     * @author     David Zülke <[email protected]>
100
+     * @author     Veikko Mäkinen <[email protected]>
101
+     * @author     Dominik del Bondio <[email protected]>
102
+     * @since      0.11.0
103
+     */
104
+    public function initialize(Context $context, array $parameters = array())
105
+    {
106
+        parent::initialize($context, $parameters);
107
+
108
+        /** @var WebRequest $rq */
109
+        $rq = $this->context->getRequest();
110
+
111
+        /** @var RequestDataHolder $rd */
112
+        $rd = $rq->getRequestData();
113
+
114
+        // 'scheme://authority' is necessary so parse_url doesn't stumble over '://' in the request URI
115
+        $ru = array_merge(array('path' => '', 'query' => ''), parse_url('scheme://authority' . $rq->getRequestUri()));
116
+
117
+        if(isset($_SERVER['QUERY_STRING'])) {
118
+            $qs = $_SERVER['QUERY_STRING'];
119
+        } else {
120
+            $qs = '';
121
+        }
122
+
123
+        // when rewriting, apache strips one (not all) trailing ampersand from the end of QUERY_STRING... normalize:
124
+        $rewritten = (preg_replace('/&+$/D', '', $qs) !== preg_replace('/&+$/D', '', $ru['query']));
125
+
126
+        if($this->isEnabled() && $rewritten) {
127
+            // strip the one trailing ampersand, see above
128
+            $queryWasEmptied = false;
129
+            if($ru['query'] !== '' && isset($_SERVER['SERVER_SOFTWARE']) && strpos($_SERVER['SERVER_SOFTWARE'], 'Apache') !== false) {
130
+                $ru['query'] = preg_replace('/&$/D', '', $ru['query']);
131
+                if($ru['query'] == '') {
132
+                    $queryWasEmptied = true;
133
+                }
134
+            }
135
+
136
+            $stripFromQuery = '&' . $ru['query'];
137
+            if($ru['query'] == '' && !$queryWasEmptied && isset($_SERVER['SERVER_SOFTWARE']) && strpos($_SERVER['SERVER_SOFTWARE'], 'Apache') !== false) {
138
+                // if the query is empty, simply give apache2 nothing instead of an "&", since that could kill a real trailing ampersand in the path, as Apache strips those from the query string (which has the rewritten path), but not the request uri
139
+                $stripFromQuery = '';
140
+            }
141
+            $this->input = preg_replace('/' . preg_quote($stripFromQuery, '/') . '$/D', '', $qs);
142
+
143
+            if(isset($_SERVER['SERVER_SOFTWARE']) && strpos($_SERVER['SERVER_SOFTWARE'], 'Apache/2') !== false) {
144
+                $sru = $_SERVER['REQUEST_URI'];
145 145
 				
146
-				if(($fqmp = strpos($sru, '?')) !== false && ($fqmp == strlen($sru)-1)) {
147
-					// strip a trailing question mark, but only if it really is the query string separator (i.e. the only question mark in the URI)
148
-					$sru = substr($sru, 0, -1);
149
-				} elseif($ru['query'] !== '' || $queryWasEmptied) {
150
-					// if there is a trailing ampersand (in query string or path, whatever ends the URL), strip it (but just one)
151
-					$sru = preg_replace('/&$/D', '', $sru);
152
-				}
146
+                if(($fqmp = strpos($sru, '?')) !== false && ($fqmp == strlen($sru)-1)) {
147
+                    // strip a trailing question mark, but only if it really is the query string separator (i.e. the only question mark in the URI)
148
+                    $sru = substr($sru, 0, -1);
149
+                } elseif($ru['query'] !== '' || $queryWasEmptied) {
150
+                    // if there is a trailing ampersand (in query string or path, whatever ends the URL), strip it (but just one)
151
+                    $sru = preg_replace('/&$/D', '', $sru);
152
+                }
153 153
 				
154
-				// multiple consecutive slashes got lost in our input thanks to an apache bug
155
-				// let's fix that
156
-				$cqs = preg_replace('#/{2,}#', '/', rawurldecode($ru['query']));
157
-				$cru = preg_replace('#/{2,}#', '/', rawurldecode($sru));
158
-				$tmp = preg_replace('/' . preg_quote($this->input . (($cqs != '' || $queryWasEmptied) ? '?' . $cqs : ''), '/') . '$/D', '', $cru);
159
-				$input = preg_replace('/^' . preg_quote($tmp, '/') . '/', '', $sru);
160
-				if($ru['query'] !== '' || $queryWasEmptied) {
161
-					$input = preg_replace('/' . preg_quote('?' . $ru['query'], '/') . '$/D', '', $input);
162
-				}
163
-				$this->input = $input;
164
-			}
165
-
166
-			if(!(isset($_SERVER['SERVER_SOFTWARE']) && (strpos($_SERVER['SERVER_SOFTWARE'], 'Apache/1') !== false || (strpos($_SERVER['SERVER_SOFTWARE'], 'Microsoft-IIS') !== false && isset($_SERVER['UNENCODED_URL']))))) {
167
-				// don't do that for Apache 1 or IIS 7 with URL Rewrite Module, it's already rawurldecode()d there
168
-				$this->input = rawurldecode($this->input);
169
-			}
170
-
171
-			$this->basePath = $this->prefix = preg_replace('/' . preg_quote($this->input, '/') . '$/D', '', rawurldecode($ru['path']));
172
-
173
-			// that was easy. now clean up $_GET and the Request
174
-			$parsedRuQuery = $parsedInput = '';
175
-			parse_str($ru['query'], $parsedRuQuery);
176
-			parse_str($this->input, $parsedInput);
177
-			if(get_magic_quotes_gpc()) {
178
-				$parsedRuQuery = WebRequest::clearMagicQuotes($parsedRuQuery);
179
-				$parsedInput = WebRequest::clearMagicQuotes($parsedInput, false /* start on the first level */);
180
-			}
181
-			foreach(array_diff(array_keys($parsedInput), array_keys($parsedRuQuery)) as $unset) {
182
-				// our element is in $_GET
183
-				unset($_GET[$unset]);
184
-				unset($GLOBALS['HTTP_GET_VARS'][$unset]);
185
-				// if it is not also in $_POST, then we need to remove it from the request params
186
-				if(!isset($_POST[$unset])) {
187
-					$rd->removeParameter($unset);
188
-					// and from $_REQUEST, too!
189
-					unset($_REQUEST[$unset]);
190
-				}
191
-			}
192
-		} else {
193
-			$sn = $_SERVER['SCRIPT_NAME'];
194
-			$path = rawurldecode($ru['path']);
195
-
196
-			$appendFrom = 0;
197
-			$this->prefix = Toolkit::stringBase($sn, $path, $appendFrom);
198
-			$this->prefix .= substr($sn, $appendFrom);
199
-
200
-			$this->input = substr($path, $appendFrom);
201
-			if(!isset($_SERVER['SERVER_SOFTWARE']) || strpos($_SERVER['SERVER_SOFTWARE'], 'Microsoft-IIS') === false || isset($_SERVER['HTTP_X_REWRITE_URL']) || !isset($_SERVER['GATEWAY_INTERFACE']) || strpos($_SERVER['GATEWAY_INTERFACE'], 'CGI') === false) {
202
-				// don't do that for IIS-CGI, it's already rawurldecode()d there
203
-				$this->input = rawurldecode($this->input);
204
-			}
205
-
206
-			$this->basePath = str_replace('\\', '/', dirname($this->prefix));
207
-		}
208
-
209
-		$this->inputParameters = $_GET;
210
-
211
-		if(!$this->input) {
212
-			$this->input = "/";
213
-		}
214
-
215
-		if(substr($this->basePath, -1, 1) != '/') {
216
-			$this->basePath .= '/';
217
-		}
218
-
219
-		$this->baseHref = $rq->getUrlScheme() . '://' . $rq->getUrlAuthority() . $this->basePath;
220
-	}
221
-
222
-	/**
223
-	 * Retrieve the base path where the application's root sits
224
-	 *
225
-	 * @return     string A path string, including a trailing slash.
226
-	 *
227
-	 * @author     David Zülke <[email protected]>
228
-	 * @since      0.11.0
229
-	 */
230
-	public function getBasePath()
231
-	{
232
-		return $this->basePath;
233
-	}
234
-
235
-	/**
236
-	 * Retrieve the full URL to the application's root.
237
-	 *
238
-	 * @return     string A URL string, including the protocol, the server port
239
-	  *                   (if necessary) and the path including a trailing slash.
240
-	 *
241
-	 * @author     David Zülke <[email protected]>
242
-	 * @since      0.11.0
243
-	 */
244
-	public function getBaseHref()
245
-	{
246
-		return $this->baseHref;
247
-	}
154
+                // multiple consecutive slashes got lost in our input thanks to an apache bug
155
+                // let's fix that
156
+                $cqs = preg_replace('#/{2,}#', '/', rawurldecode($ru['query']));
157
+                $cru = preg_replace('#/{2,}#', '/', rawurldecode($sru));
158
+                $tmp = preg_replace('/' . preg_quote($this->input . (($cqs != '' || $queryWasEmptied) ? '?' . $cqs : ''), '/') . '$/D', '', $cru);
159
+                $input = preg_replace('/^' . preg_quote($tmp, '/') . '/', '', $sru);
160
+                if($ru['query'] !== '' || $queryWasEmptied) {
161
+                    $input = preg_replace('/' . preg_quote('?' . $ru['query'], '/') . '$/D', '', $input);
162
+                }
163
+                $this->input = $input;
164
+            }
165
+
166
+            if(!(isset($_SERVER['SERVER_SOFTWARE']) && (strpos($_SERVER['SERVER_SOFTWARE'], 'Apache/1') !== false || (strpos($_SERVER['SERVER_SOFTWARE'], 'Microsoft-IIS') !== false && isset($_SERVER['UNENCODED_URL']))))) {
167
+                // don't do that for Apache 1 or IIS 7 with URL Rewrite Module, it's already rawurldecode()d there
168
+                $this->input = rawurldecode($this->input);
169
+            }
170
+
171
+            $this->basePath = $this->prefix = preg_replace('/' . preg_quote($this->input, '/') . '$/D', '', rawurldecode($ru['path']));
172
+
173
+            // that was easy. now clean up $_GET and the Request
174
+            $parsedRuQuery = $parsedInput = '';
175
+            parse_str($ru['query'], $parsedRuQuery);
176
+            parse_str($this->input, $parsedInput);
177
+            if(get_magic_quotes_gpc()) {
178
+                $parsedRuQuery = WebRequest::clearMagicQuotes($parsedRuQuery);
179
+                $parsedInput = WebRequest::clearMagicQuotes($parsedInput, false /* start on the first level */);
180
+            }
181
+            foreach(array_diff(array_keys($parsedInput), array_keys($parsedRuQuery)) as $unset) {
182
+                // our element is in $_GET
183
+                unset($_GET[$unset]);
184
+                unset($GLOBALS['HTTP_GET_VARS'][$unset]);
185
+                // if it is not also in $_POST, then we need to remove it from the request params
186
+                if(!isset($_POST[$unset])) {
187
+                    $rd->removeParameter($unset);
188
+                    // and from $_REQUEST, too!
189
+                    unset($_REQUEST[$unset]);
190
+                }
191
+            }
192
+        } else {
193
+            $sn = $_SERVER['SCRIPT_NAME'];
194
+            $path = rawurldecode($ru['path']);
195
+
196
+            $appendFrom = 0;
197
+            $this->prefix = Toolkit::stringBase($sn, $path, $appendFrom);
198
+            $this->prefix .= substr($sn, $appendFrom);
199
+
200
+            $this->input = substr($path, $appendFrom);
201
+            if(!isset($_SERVER['SERVER_SOFTWARE']) || strpos($_SERVER['SERVER_SOFTWARE'], 'Microsoft-IIS') === false || isset($_SERVER['HTTP_X_REWRITE_URL']) || !isset($_SERVER['GATEWAY_INTERFACE']) || strpos($_SERVER['GATEWAY_INTERFACE'], 'CGI') === false) {
202
+                // don't do that for IIS-CGI, it's already rawurldecode()d there
203
+                $this->input = rawurldecode($this->input);
204
+            }
205
+
206
+            $this->basePath = str_replace('\\', '/', dirname($this->prefix));
207
+        }
208
+
209
+        $this->inputParameters = $_GET;
210
+
211
+        if(!$this->input) {
212
+            $this->input = "/";
213
+        }
214
+
215
+        if(substr($this->basePath, -1, 1) != '/') {
216
+            $this->basePath .= '/';
217
+        }
218
+
219
+        $this->baseHref = $rq->getUrlScheme() . '://' . $rq->getUrlAuthority() . $this->basePath;
220
+    }
221
+
222
+    /**
223
+     * Retrieve the base path where the application's root sits
224
+     *
225
+     * @return     string A path string, including a trailing slash.
226
+     *
227
+     * @author     David Zülke <[email protected]>
228
+     * @since      0.11.0
229
+     */
230
+    public function getBasePath()
231
+    {
232
+        return $this->basePath;
233
+    }
234
+
235
+    /**
236
+     * Retrieve the full URL to the application's root.
237
+     *
238
+     * @return     string A URL string, including the protocol, the server port
239
+     *                   (if necessary) and the path including a trailing slash.
240
+     *
241
+     * @author     David Zülke <[email protected]>
242
+     * @since      0.11.0
243
+     */
244
+    public function getBaseHref()
245
+    {
246
+        return $this->baseHref;
247
+    }
248 248
 	
249
-	/**
250
-	 * Generate a formatted Agavi URL.
251
-	 *
252
-	 * @param      string $route A route name.
253
-	 * @param      array  $params An associative array of parameters.
254
-	 * @param      mixed  $options An array of options, or the name of an options preset.
255
-	 *
256
-	 * @return     string The generated URL.
257
-	 *
258
-	 * @author     David Zülke <[email protected]>
259
-	 * @since      0.11.0
260
-	 */
261
-	public function gen($route, array $params = array(), $options = array())
262
-	{
263
-		/** @var WebRequest $req */
264
-		$req = $this->context->getRequest();
265
-
266
-		if(substr($route, -1) == '*') {
267
-			$options['refill_all_parameters'] = true;
268
-			$route = substr($route, 0, -1);
269
-		}
270
-
271
-		$options = $this->resolveGenOptions($options);
272
-
273
-		$aso = $this->argSeparatorOutput;
274
-		if($options['separator'] != $aso) {
275
-			$aso = $options['separator'];
276
-		}
277
-
278
-		if($options['use_trans_sid'] === true && defined('SID') && SID !== '') {
279
-			$params = array_merge($params, array(session_name() => session_id()));
280
-		}
281
-
282
-		if($route === null && empty($params)) {
283
-			$retval = $req->getRequestUri();
284
-			$retval = str_replace(array('[', ']', '\''), array('%5B', '%5D', '%27'), $retval);
285
-			// much quicker than str_replace($this->argSeparatorInput, array_fill(0, count($this->argSeparatorInput), $aso), $retval)
286
-			foreach($this->argSeparatorInput as $char) {
287
-				$retval = str_replace($char, $aso, $retval);
288
-			}
289
-		} else {
290
-			if($this->isEnabled()) {
291
-				// the route exists and routing is enabled, the parent method handles it
292
-
293
-				$append = '';
294
-
295
-				list($path, $usedParams, $options, $extraParams, $isNullRoute) = parent::gen($route, $params, $options);
249
+    /**
250
+     * Generate a formatted Agavi URL.
251
+     *
252
+     * @param      string $route A route name.
253
+     * @param      array  $params An associative array of parameters.
254
+     * @param      mixed  $options An array of options, or the name of an options preset.
255
+     *
256
+     * @return     string The generated URL.
257
+     *
258
+     * @author     David Zülke <[email protected]>
259
+     * @since      0.11.0
260
+     */
261
+    public function gen($route, array $params = array(), $options = array())
262
+    {
263
+        /** @var WebRequest $req */
264
+        $req = $this->context->getRequest();
265
+
266
+        if(substr($route, -1) == '*') {
267
+            $options['refill_all_parameters'] = true;
268
+            $route = substr($route, 0, -1);
269
+        }
270
+
271
+        $options = $this->resolveGenOptions($options);
272
+
273
+        $aso = $this->argSeparatorOutput;
274
+        if($options['separator'] != $aso) {
275
+            $aso = $options['separator'];
276
+        }
277
+
278
+        if($options['use_trans_sid'] === true && defined('SID') && SID !== '') {
279
+            $params = array_merge($params, array(session_name() => session_id()));
280
+        }
281
+
282
+        if($route === null && empty($params)) {
283
+            $retval = $req->getRequestUri();
284
+            $retval = str_replace(array('[', ']', '\''), array('%5B', '%5D', '%27'), $retval);
285
+            // much quicker than str_replace($this->argSeparatorInput, array_fill(0, count($this->argSeparatorInput), $aso), $retval)
286
+            foreach($this->argSeparatorInput as $char) {
287
+                $retval = str_replace($char, $aso, $retval);
288
+            }
289
+        } else {
290
+            if($this->isEnabled()) {
291
+                // the route exists and routing is enabled, the parent method handles it
292
+
293
+                $append = '';
294
+
295
+                list($path, $usedParams, $options, $extraParams, $isNullRoute) = parent::gen($route, $params, $options);
296 296
 				
297
-				if($isNullRoute) {
298
-					// add the incoming parameters from the request uri for gen(null) and friends
299
-					$extraParams = array_merge($this->inputParameters, $extraParams);
300
-				}
301
-				if(count($extraParams) > 0) {
302
-					$append = http_build_query($extraParams, '', $aso);
303
-					if($append !== '') {
304
-					  $append = '?' . $append;
305
-					}
306
-				}
307
-			} else {
308
-				// the route exists, but we must create a normal index.php?foo=bar URL.
309
-
310
-				$isNullRoute = false;
311
-				$routes = $this->getAffectedRoutes($route, $isNullRoute);
312
-				if($isNullRoute) {
313
-					$params = array_merge($this->inputParameters, $params);
314
-				}
315
-				if(count($routes) == 0) {
316
-					$path = $route;
317
-				}
318
-
319
-				// we collect the default parameters from the route and make sure
320
-				// new parameters don't overwrite already defined parameters
321
-				$defaults = array();
322
-
323
-				$ma = $req->getParameter('module_accessor');
324
-				$aa = $req->getParameter('controller_accessor');
325
-
326
-				foreach($routes as $route) {
327
-					if(isset($this->routes[$route])) {
328
-						$r = $this->routes[$route];
329
-						$myDefaults = array();
330
-
331
-						foreach($r['opt']['defaults'] as $key => $default) {
332
-							$myDefaults[$key] = $default->getValue();
333
-						}
334
-						if($r['opt']['module']) {
335
-							$myDefaults[$ma] = $r['opt']['module'];
336
-						}
337
-						if($r['opt']['controller']) {
338
-							$myDefaults[$aa] = $r['opt']['controller'];
339
-						}
340
-
341
-						$defaults = array_merge($myDefaults, $defaults);
342
-					}
343
-				}
344
-
345
-				$params = array_merge($defaults, $params);
346
-			}
297
+                if($isNullRoute) {
298
+                    // add the incoming parameters from the request uri for gen(null) and friends
299
+                    $extraParams = array_merge($this->inputParameters, $extraParams);
300
+                }
301
+                if(count($extraParams) > 0) {
302
+                    $append = http_build_query($extraParams, '', $aso);
303
+                    if($append !== '') {
304
+                        $append = '?' . $append;
305
+                    }
306
+                }
307
+            } else {
308
+                // the route exists, but we must create a normal index.php?foo=bar URL.
309
+
310
+                $isNullRoute = false;
311
+                $routes = $this->getAffectedRoutes($route, $isNullRoute);
312
+                if($isNullRoute) {
313
+                    $params = array_merge($this->inputParameters, $params);
314
+                }
315
+                if(count($routes) == 0) {
316
+                    $path = $route;
317
+                }
318
+
319
+                // we collect the default parameters from the route and make sure
320
+                // new parameters don't overwrite already defined parameters
321
+                $defaults = array();
322
+
323
+                $ma = $req->getParameter('module_accessor');
324
+                $aa = $req->getParameter('controller_accessor');
325
+
326
+                foreach($routes as $route) {
327
+                    if(isset($this->routes[$route])) {
328
+                        $r = $this->routes[$route];
329
+                        $myDefaults = array();
330
+
331
+                        foreach($r['opt']['defaults'] as $key => $default) {
332
+                            $myDefaults[$key] = $default->getValue();
333
+                        }
334
+                        if($r['opt']['module']) {
335
+                            $myDefaults[$ma] = $r['opt']['module'];
336
+                        }
337
+                        if($r['opt']['controller']) {
338
+                            $myDefaults[$aa] = $r['opt']['controller'];
339
+                        }
340
+
341
+                        $defaults = array_merge($myDefaults, $defaults);
342
+                    }
343
+                }
344
+
345
+                $params = array_merge($defaults, $params);
346
+            }
347 347
 			
348
-			if(!isset($path)) {
349
-				// the route does not exist. we generate a normal index.php?foo=bar URL.
350
-				$path = $_SERVER['SCRIPT_NAME'];
351
-			}
348
+            if(!isset($path)) {
349
+                // the route does not exist. we generate a normal index.php?foo=bar URL.
350
+                $path = $_SERVER['SCRIPT_NAME'];
351
+            }
352 352
 			
353
-			if(!isset($path)) {
354
-				// routing was off; the name of the route is the input
355
-			}
356
-			if(!isset($append)) {
357
-				$append = '?' . http_build_query($params, '', $aso);
358
-			}
359
-
360
-			$retval = $path . $append;
361
-		}
362
-
363
-		if(
364
-			!$options['relative'] ||
365
-			($options['relative'] && (
366
-				$options['scheme'] !== null ||
367
-				$options['authority'] !== null ||
368
-				$options['host'] !== null ||
369
-				$options['port'] !== null
370
-			))
371
-		) {
372
-			$scheme = false;
373
-			if($options['scheme'] !== false) {
374
-				$scheme = ($options['scheme'] === null ? $req->getUrlScheme() : $options['scheme']);
375
-			}
376
-
377
-			$authority = '';
378
-
379
-			if($options['authority'] === null) {
380
-				if($options['host'] !== null && $options['host'] !== false) {
381
-					$authority = $options['host'];
382
-				} elseif($options['host'] === false) {
383
-					$authority = '';
384
-				} else {
385
-					$authority = $req->getUrlHost();
386
-				}
387
-				$port = null;
388
-				if($options['port'] !== null && $options['port'] !== false) {
389
-					if(Toolkit::isPortNecessary($options['scheme'] !== null && $options['scheme'] !== false ? $options['scheme'] : $req->getUrlScheme(), $options['port'])) {
390
-						$port = $options['port'];
391
-					} else {
392
-						$port = null;
393
-					}
394
-				} elseif($options['port'] === false) {
395
-					$port = null;
396
-				} elseif($options['scheme'] === null) {
397
-					if(!Toolkit::isPortNecessary($req->getUrlScheme(), $port = $req->getUrlPort())) {
398
-						$port = null;
399
-					}
400
-				}
401
-				if($port !== null) {
402
-					$authority .= ':' . $port;
403
-				}
404
-			} elseif($options['authority'] !== false) {
405
-				$authority = $options['authority'];
406
-			}
407
-
408
-			if($scheme === false) {
409
-				// nothing at all, e.g. when displaying a URL without the "http://" prefix
410
-				$scheme = '';
411
-			} elseif(trim($scheme) === '') {
412
-				// a protocol-relative URL (see #1224)
413
-				$scheme = '//';
414
-			} else {
415
-				// given scheme plus "://"
416
-				$scheme = $scheme . '://';
417
-			}
353
+            if(!isset($path)) {
354
+                // routing was off; the name of the route is the input
355
+            }
356
+            if(!isset($append)) {
357
+                $append = '?' . http_build_query($params, '', $aso);
358
+            }
359
+
360
+            $retval = $path . $append;
361
+        }
362
+
363
+        if(
364
+            !$options['relative'] ||
365
+            ($options['relative'] && (
366
+                $options['scheme'] !== null ||
367
+                $options['authority'] !== null ||
368
+                $options['host'] !== null ||
369
+                $options['port'] !== null
370
+            ))
371
+        ) {
372
+            $scheme = false;
373
+            if($options['scheme'] !== false) {
374
+                $scheme = ($options['scheme'] === null ? $req->getUrlScheme() : $options['scheme']);
375
+            }
376
+
377
+            $authority = '';
378
+
379
+            if($options['authority'] === null) {
380
+                if($options['host'] !== null && $options['host'] !== false) {
381
+                    $authority = $options['host'];
382
+                } elseif($options['host'] === false) {
383
+                    $authority = '';
384
+                } else {
385
+                    $authority = $req->getUrlHost();
386
+                }
387
+                $port = null;
388
+                if($options['port'] !== null && $options['port'] !== false) {
389
+                    if(Toolkit::isPortNecessary($options['scheme'] !== null && $options['scheme'] !== false ? $options['scheme'] : $req->getUrlScheme(), $options['port'])) {
390
+                        $port = $options['port'];
391
+                    } else {
392
+                        $port = null;
393
+                    }
394
+                } elseif($options['port'] === false) {
395
+                    $port = null;
396
+                } elseif($options['scheme'] === null) {
397
+                    if(!Toolkit::isPortNecessary($req->getUrlScheme(), $port = $req->getUrlPort())) {
398
+                        $port = null;
399
+                    }
400
+                }
401
+                if($port !== null) {
402
+                    $authority .= ':' . $port;
403
+                }
404
+            } elseif($options['authority'] !== false) {
405
+                $authority = $options['authority'];
406
+            }
407
+
408
+            if($scheme === false) {
409
+                // nothing at all, e.g. when displaying a URL without the "http://" prefix
410
+                $scheme = '';
411
+            } elseif(trim($scheme) === '') {
412
+                // a protocol-relative URL (see #1224)
413
+                $scheme = '//';
414
+            } else {
415
+                // given scheme plus "://"
416
+                $scheme = $scheme . '://';
417
+            }
418 418
 			
419
-			$retval = $scheme . $authority . $retval;
420
-		}
421
-
422
-		if($options['fragment'] !== null) {
423
-			$retval .= '#' . $options['fragment'];
424
-		}
425
-
426
-		return $retval;
427
-	}
428
-
429
-	/**
430
-	 * Escapes an argument to be used in an generated route.
431
-	 *
432
-	 * @param      string $string The argument to be escaped.
433
-	 *
434
-	 * @return     string The escaped argument.
435
-	 *
436
-	 * @author     Dominik del Bondio <[email protected]>
437
-	 * @since      0.11.0
438
-	 */
439
-	public function escapeOutputParameter($string)
440
-	{
441
-		return rawurlencode($string);
442
-	}
419
+            $retval = $scheme . $authority . $retval;
420
+        }
421
+
422
+        if($options['fragment'] !== null) {
423
+            $retval .= '#' . $options['fragment'];
424
+        }
425
+
426
+        return $retval;
427
+    }
428
+
429
+    /**
430
+     * Escapes an argument to be used in an generated route.
431
+     *
432
+     * @param      string $string The argument to be escaped.
433
+     *
434
+     * @return     string The escaped argument.
435
+     *
436
+     * @author     Dominik del Bondio <[email protected]>
437
+     * @since      0.11.0
438
+     */
439
+    public function escapeOutputParameter($string)
440
+    {
441
+        return rawurlencode($string);
442
+    }
443 443
 
444 444
 }
445 445
 
Please login to merge, or discard this patch.
Spacing   +50 added lines, -50 removed lines patch added patch discarded remove patch
@@ -114,7 +114,7 @@  discard block
 block discarded – undo
114 114
 		// 'scheme://authority' is necessary so parse_url doesn't stumble over '://' in the request URI
115 115
 		$ru = array_merge(array('path' => '', 'query' => ''), parse_url('scheme://authority' . $rq->getRequestUri()));
116 116
 
117
-		if(isset($_SERVER['QUERY_STRING'])) {
117
+		if (isset($_SERVER['QUERY_STRING'])) {
118 118
 			$qs = $_SERVER['QUERY_STRING'];
119 119
 		} else {
120 120
 			$qs = '';
@@ -123,30 +123,30 @@  discard block
 block discarded – undo
123 123
 		// when rewriting, apache strips one (not all) trailing ampersand from the end of QUERY_STRING... normalize:
124 124
 		$rewritten = (preg_replace('/&+$/D', '', $qs) !== preg_replace('/&+$/D', '', $ru['query']));
125 125
 
126
-		if($this->isEnabled() && $rewritten) {
126
+		if ($this->isEnabled() && $rewritten) {
127 127
 			// strip the one trailing ampersand, see above
128 128
 			$queryWasEmptied = false;
129
-			if($ru['query'] !== '' && isset($_SERVER['SERVER_SOFTWARE']) && strpos($_SERVER['SERVER_SOFTWARE'], 'Apache') !== false) {
129
+			if ($ru['query'] !== '' && isset($_SERVER['SERVER_SOFTWARE']) && strpos($_SERVER['SERVER_SOFTWARE'], 'Apache') !== false) {
130 130
 				$ru['query'] = preg_replace('/&$/D', '', $ru['query']);
131
-				if($ru['query'] == '') {
131
+				if ($ru['query'] == '') {
132 132
 					$queryWasEmptied = true;
133 133
 				}
134 134
 			}
135 135
 
136 136
 			$stripFromQuery = '&' . $ru['query'];
137
-			if($ru['query'] == '' && !$queryWasEmptied && isset($_SERVER['SERVER_SOFTWARE']) && strpos($_SERVER['SERVER_SOFTWARE'], 'Apache') !== false) {
137
+			if ($ru['query'] == '' && !$queryWasEmptied && isset($_SERVER['SERVER_SOFTWARE']) && strpos($_SERVER['SERVER_SOFTWARE'], 'Apache') !== false) {
138 138
 				// if the query is empty, simply give apache2 nothing instead of an "&", since that could kill a real trailing ampersand in the path, as Apache strips those from the query string (which has the rewritten path), but not the request uri
139 139
 				$stripFromQuery = '';
140 140
 			}
141 141
 			$this->input = preg_replace('/' . preg_quote($stripFromQuery, '/') . '$/D', '', $qs);
142 142
 
143
-			if(isset($_SERVER['SERVER_SOFTWARE']) && strpos($_SERVER['SERVER_SOFTWARE'], 'Apache/2') !== false) {
143
+			if (isset($_SERVER['SERVER_SOFTWARE']) && strpos($_SERVER['SERVER_SOFTWARE'], 'Apache/2') !== false) {
144 144
 				$sru = $_SERVER['REQUEST_URI'];
145 145
 				
146
-				if(($fqmp = strpos($sru, '?')) !== false && ($fqmp == strlen($sru)-1)) {
146
+				if (($fqmp = strpos($sru, '?')) !== false && ($fqmp == strlen($sru) - 1)) {
147 147
 					// strip a trailing question mark, but only if it really is the query string separator (i.e. the only question mark in the URI)
148 148
 					$sru = substr($sru, 0, -1);
149
-				} elseif($ru['query'] !== '' || $queryWasEmptied) {
149
+				} elseif ($ru['query'] !== '' || $queryWasEmptied) {
150 150
 					// if there is a trailing ampersand (in query string or path, whatever ends the URL), strip it (but just one)
151 151
 					$sru = preg_replace('/&$/D', '', $sru);
152 152
 				}
@@ -157,13 +157,13 @@  discard block
 block discarded – undo
157 157
 				$cru = preg_replace('#/{2,}#', '/', rawurldecode($sru));
158 158
 				$tmp = preg_replace('/' . preg_quote($this->input . (($cqs != '' || $queryWasEmptied) ? '?' . $cqs : ''), '/') . '$/D', '', $cru);
159 159
 				$input = preg_replace('/^' . preg_quote($tmp, '/') . '/', '', $sru);
160
-				if($ru['query'] !== '' || $queryWasEmptied) {
160
+				if ($ru['query'] !== '' || $queryWasEmptied) {
161 161
 					$input = preg_replace('/' . preg_quote('?' . $ru['query'], '/') . '$/D', '', $input);
162 162
 				}
163 163
 				$this->input = $input;
164 164
 			}
165 165
 
166
-			if(!(isset($_SERVER['SERVER_SOFTWARE']) && (strpos($_SERVER['SERVER_SOFTWARE'], 'Apache/1') !== false || (strpos($_SERVER['SERVER_SOFTWARE'], 'Microsoft-IIS') !== false && isset($_SERVER['UNENCODED_URL']))))) {
166
+			if (!(isset($_SERVER['SERVER_SOFTWARE']) && (strpos($_SERVER['SERVER_SOFTWARE'], 'Apache/1') !== false || (strpos($_SERVER['SERVER_SOFTWARE'], 'Microsoft-IIS') !== false && isset($_SERVER['UNENCODED_URL']))))) {
167 167
 				// don't do that for Apache 1 or IIS 7 with URL Rewrite Module, it's already rawurldecode()d there
168 168
 				$this->input = rawurldecode($this->input);
169 169
 			}
@@ -174,16 +174,16 @@  discard block
 block discarded – undo
174 174
 			$parsedRuQuery = $parsedInput = '';
175 175
 			parse_str($ru['query'], $parsedRuQuery);
176 176
 			parse_str($this->input, $parsedInput);
177
-			if(get_magic_quotes_gpc()) {
177
+			if (get_magic_quotes_gpc()) {
178 178
 				$parsedRuQuery = WebRequest::clearMagicQuotes($parsedRuQuery);
179 179
 				$parsedInput = WebRequest::clearMagicQuotes($parsedInput, false /* start on the first level */);
180 180
 			}
181
-			foreach(array_diff(array_keys($parsedInput), array_keys($parsedRuQuery)) as $unset) {
181
+			foreach (array_diff(array_keys($parsedInput), array_keys($parsedRuQuery)) as $unset) {
182 182
 				// our element is in $_GET
183 183
 				unset($_GET[$unset]);
184 184
 				unset($GLOBALS['HTTP_GET_VARS'][$unset]);
185 185
 				// if it is not also in $_POST, then we need to remove it from the request params
186
-				if(!isset($_POST[$unset])) {
186
+				if (!isset($_POST[$unset])) {
187 187
 					$rd->removeParameter($unset);
188 188
 					// and from $_REQUEST, too!
189 189
 					unset($_REQUEST[$unset]);
@@ -198,7 +198,7 @@  discard block
 block discarded – undo
198 198
 			$this->prefix .= substr($sn, $appendFrom);
199 199
 
200 200
 			$this->input = substr($path, $appendFrom);
201
-			if(!isset($_SERVER['SERVER_SOFTWARE']) || strpos($_SERVER['SERVER_SOFTWARE'], 'Microsoft-IIS') === false || isset($_SERVER['HTTP_X_REWRITE_URL']) || !isset($_SERVER['GATEWAY_INTERFACE']) || strpos($_SERVER['GATEWAY_INTERFACE'], 'CGI') === false) {
201
+			if (!isset($_SERVER['SERVER_SOFTWARE']) || strpos($_SERVER['SERVER_SOFTWARE'], 'Microsoft-IIS') === false || isset($_SERVER['HTTP_X_REWRITE_URL']) || !isset($_SERVER['GATEWAY_INTERFACE']) || strpos($_SERVER['GATEWAY_INTERFACE'], 'CGI') === false) {
202 202
 				// don't do that for IIS-CGI, it's already rawurldecode()d there
203 203
 				$this->input = rawurldecode($this->input);
204 204
 			}
@@ -208,11 +208,11 @@  discard block
 block discarded – undo
208 208
 
209 209
 		$this->inputParameters = $_GET;
210 210
 
211
-		if(!$this->input) {
211
+		if (!$this->input) {
212 212
 			$this->input = "/";
213 213
 		}
214 214
 
215
-		if(substr($this->basePath, -1, 1) != '/') {
215
+		if (substr($this->basePath, -1, 1) != '/') {
216 216
 			$this->basePath .= '/';
217 217
 		}
218 218
 
@@ -263,7 +263,7 @@  discard block
 block discarded – undo
263 263
 		/** @var WebRequest $req */
264 264
 		$req = $this->context->getRequest();
265 265
 
266
-		if(substr($route, -1) == '*') {
266
+		if (substr($route, -1) == '*') {
267 267
 			$options['refill_all_parameters'] = true;
268 268
 			$route = substr($route, 0, -1);
269 269
 		}
@@ -271,36 +271,36 @@  discard block
 block discarded – undo
271 271
 		$options = $this->resolveGenOptions($options);
272 272
 
273 273
 		$aso = $this->argSeparatorOutput;
274
-		if($options['separator'] != $aso) {
274
+		if ($options['separator'] != $aso) {
275 275
 			$aso = $options['separator'];
276 276
 		}
277 277
 
278
-		if($options['use_trans_sid'] === true && defined('SID') && SID !== '') {
278
+		if ($options['use_trans_sid'] === true && defined('SID') && SID !== '') {
279 279
 			$params = array_merge($params, array(session_name() => session_id()));
280 280
 		}
281 281
 
282
-		if($route === null && empty($params)) {
282
+		if ($route === null && empty($params)) {
283 283
 			$retval = $req->getRequestUri();
284 284
 			$retval = str_replace(array('[', ']', '\''), array('%5B', '%5D', '%27'), $retval);
285 285
 			// much quicker than str_replace($this->argSeparatorInput, array_fill(0, count($this->argSeparatorInput), $aso), $retval)
286
-			foreach($this->argSeparatorInput as $char) {
286
+			foreach ($this->argSeparatorInput as $char) {
287 287
 				$retval = str_replace($char, $aso, $retval);
288 288
 			}
289 289
 		} else {
290
-			if($this->isEnabled()) {
290
+			if ($this->isEnabled()) {
291 291
 				// the route exists and routing is enabled, the parent method handles it
292 292
 
293 293
 				$append = '';
294 294
 
295 295
 				list($path, $usedParams, $options, $extraParams, $isNullRoute) = parent::gen($route, $params, $options);
296 296
 				
297
-				if($isNullRoute) {
297
+				if ($isNullRoute) {
298 298
 					// add the incoming parameters from the request uri for gen(null) and friends
299 299
 					$extraParams = array_merge($this->inputParameters, $extraParams);
300 300
 				}
301
-				if(count($extraParams) > 0) {
301
+				if (count($extraParams) > 0) {
302 302
 					$append = http_build_query($extraParams, '', $aso);
303
-					if($append !== '') {
303
+					if ($append !== '') {
304 304
 					  $append = '?' . $append;
305 305
 					}
306 306
 				}
@@ -309,10 +309,10 @@  discard block
 block discarded – undo
309 309
 
310 310
 				$isNullRoute = false;
311 311
 				$routes = $this->getAffectedRoutes($route, $isNullRoute);
312
-				if($isNullRoute) {
312
+				if ($isNullRoute) {
313 313
 					$params = array_merge($this->inputParameters, $params);
314 314
 				}
315
-				if(count($routes) == 0) {
315
+				if (count($routes) == 0) {
316 316
 					$path = $route;
317 317
 				}
318 318
 
@@ -323,18 +323,18 @@  discard block
 block discarded – undo
323 323
 				$ma = $req->getParameter('module_accessor');
324 324
 				$aa = $req->getParameter('controller_accessor');
325 325
 
326
-				foreach($routes as $route) {
327
-					if(isset($this->routes[$route])) {
326
+				foreach ($routes as $route) {
327
+					if (isset($this->routes[$route])) {
328 328
 						$r = $this->routes[$route];
329 329
 						$myDefaults = array();
330 330
 
331
-						foreach($r['opt']['defaults'] as $key => $default) {
331
+						foreach ($r['opt']['defaults'] as $key => $default) {
332 332
 							$myDefaults[$key] = $default->getValue();
333 333
 						}
334
-						if($r['opt']['module']) {
334
+						if ($r['opt']['module']) {
335 335
 							$myDefaults[$ma] = $r['opt']['module'];
336 336
 						}
337
-						if($r['opt']['controller']) {
337
+						if ($r['opt']['controller']) {
338 338
 							$myDefaults[$aa] = $r['opt']['controller'];
339 339
 						}
340 340
 
@@ -345,22 +345,22 @@  discard block
 block discarded – undo
345 345
 				$params = array_merge($defaults, $params);
346 346
 			}
347 347
 			
348
-			if(!isset($path)) {
348
+			if (!isset($path)) {
349 349
 				// the route does not exist. we generate a normal index.php?foo=bar URL.
350 350
 				$path = $_SERVER['SCRIPT_NAME'];
351 351
 			}
352 352
 			
353
-			if(!isset($path)) {
353
+			if (!isset($path)) {
354 354
 				// routing was off; the name of the route is the input
355 355
 			}
356
-			if(!isset($append)) {
356
+			if (!isset($append)) {
357 357
 				$append = '?' . http_build_query($params, '', $aso);
358 358
 			}
359 359
 
360 360
 			$retval = $path . $append;
361 361
 		}
362 362
 
363
-		if(
363
+		if (
364 364
 			!$options['relative'] ||
365 365
 			($options['relative'] && (
366 366
 				$options['scheme'] !== null ||
@@ -370,45 +370,45 @@  discard block
 block discarded – undo
370 370
 			))
371 371
 		) {
372 372
 			$scheme = false;
373
-			if($options['scheme'] !== false) {
373
+			if ($options['scheme'] !== false) {
374 374
 				$scheme = ($options['scheme'] === null ? $req->getUrlScheme() : $options['scheme']);
375 375
 			}
376 376
 
377 377
 			$authority = '';
378 378
 
379
-			if($options['authority'] === null) {
380
-				if($options['host'] !== null && $options['host'] !== false) {
379
+			if ($options['authority'] === null) {
380
+				if ($options['host'] !== null && $options['host'] !== false) {
381 381
 					$authority = $options['host'];
382
-				} elseif($options['host'] === false) {
382
+				} elseif ($options['host'] === false) {
383 383
 					$authority = '';
384 384
 				} else {
385 385
 					$authority = $req->getUrlHost();
386 386
 				}
387 387
 				$port = null;
388
-				if($options['port'] !== null && $options['port'] !== false) {
389
-					if(Toolkit::isPortNecessary($options['scheme'] !== null && $options['scheme'] !== false ? $options['scheme'] : $req->getUrlScheme(), $options['port'])) {
388
+				if ($options['port'] !== null && $options['port'] !== false) {
389
+					if (Toolkit::isPortNecessary($options['scheme'] !== null && $options['scheme'] !== false ? $options['scheme'] : $req->getUrlScheme(), $options['port'])) {
390 390
 						$port = $options['port'];
391 391
 					} else {
392 392
 						$port = null;
393 393
 					}
394
-				} elseif($options['port'] === false) {
394
+				} elseif ($options['port'] === false) {
395 395
 					$port = null;
396
-				} elseif($options['scheme'] === null) {
397
-					if(!Toolkit::isPortNecessary($req->getUrlScheme(), $port = $req->getUrlPort())) {
396
+				} elseif ($options['scheme'] === null) {
397
+					if (!Toolkit::isPortNecessary($req->getUrlScheme(), $port = $req->getUrlPort())) {
398 398
 						$port = null;
399 399
 					}
400 400
 				}
401
-				if($port !== null) {
401
+				if ($port !== null) {
402 402
 					$authority .= ':' . $port;
403 403
 				}
404
-			} elseif($options['authority'] !== false) {
404
+			} elseif ($options['authority'] !== false) {
405 405
 				$authority = $options['authority'];
406 406
 			}
407 407
 
408
-			if($scheme === false) {
408
+			if ($scheme === false) {
409 409
 				// nothing at all, e.g. when displaying a URL without the "http://" prefix
410 410
 				$scheme = '';
411
-			} elseif(trim($scheme) === '') {
411
+			} elseif (trim($scheme) === '') {
412 412
 				// a protocol-relative URL (see #1224)
413 413
 				$scheme = '//';
414 414
 			} else {
@@ -419,7 +419,7 @@  discard block
 block discarded – undo
419 419
 			$retval = $scheme . $authority . $retval;
420 420
 		}
421 421
 
422
-		if($options['fragment'] !== null) {
422
+		if ($options['fragment'] !== null) {
423 423
 			$retval .= '#' . $options['fragment'];
424 424
 		}
425 425
 
Please login to merge, or discard this patch.
src/routing/Routing.class.php 2 patches
Indentation   +1651 added lines, -1651 removed lines patch added patch discarded remove patch
@@ -42,1194 +42,1194 @@  discard block
 block discarded – undo
42 42
  */
43 43
 abstract class Routing extends ParameterHolder
44 44
 {
45
-	const ANCHOR_NONE = 0;
46
-	const ANCHOR_START = 1;
47
-	const ANCHOR_END = 2;
48
-
49
-	/**
50
-	 * @var        array An array of route information
51
-	 */
52
-	protected $routes = array();
53
-
54
-	/**
55
-	 * @var        Context A Context instance.
56
-	 */
57
-	protected $context = null;
58
-
59
-	/**
60
-	 * @var        string Route input.
61
-	 */
62
-	protected $input = null;
63
-
64
-	/**
65
-	 * @var        RoutingArraySource[] An array of RoutingArraySource.
66
-	 */
67
-	protected $sources = array();
68
-
69
-	/**
70
-	 * @var        string Route prefix to use with gen()
71
-	 */
72
-	protected $prefix = '';
73
-
74
-	/**
75
-	 * @var        array An array of default options for gen()
76
-	 */
77
-	protected $defaultGenOptions = array();
78
-
79
-	/**
80
-	 * @var        array An array of default options presets for gen()
81
-	 */
82
-	protected $genOptionsPresets = array();
83
-
84
-	/**
85
-	 * Constructor.
86
-	 *
87
-	 * @author     David Zülke <[email protected]>
88
-	 * @since      0.11.0
89
-	 */
90
-	public function __construct()
91
-	{
92
-		// for now, we still use this setting as default.
93
-		// will be removed in 1.1
94
-		$this->setParameter('enabled', Config::get('core.use_routing', true));
45
+    const ANCHOR_NONE = 0;
46
+    const ANCHOR_START = 1;
47
+    const ANCHOR_END = 2;
48
+
49
+    /**
50
+     * @var        array An array of route information
51
+     */
52
+    protected $routes = array();
53
+
54
+    /**
55
+     * @var        Context A Context instance.
56
+     */
57
+    protected $context = null;
58
+
59
+    /**
60
+     * @var        string Route input.
61
+     */
62
+    protected $input = null;
63
+
64
+    /**
65
+     * @var        RoutingArraySource[] An array of RoutingArraySource.
66
+     */
67
+    protected $sources = array();
68
+
69
+    /**
70
+     * @var        string Route prefix to use with gen()
71
+     */
72
+    protected $prefix = '';
73
+
74
+    /**
75
+     * @var        array An array of default options for gen()
76
+     */
77
+    protected $defaultGenOptions = array();
78
+
79
+    /**
80
+     * @var        array An array of default options presets for gen()
81
+     */
82
+    protected $genOptionsPresets = array();
83
+
84
+    /**
85
+     * Constructor.
86
+     *
87
+     * @author     David Zülke <[email protected]>
88
+     * @since      0.11.0
89
+     */
90
+    public function __construct()
91
+    {
92
+        // for now, we still use this setting as default.
93
+        // will be removed in 1.1
94
+        $this->setParameter('enabled', Config::get('core.use_routing', true));
95 95
 		
96
-		$this->defaultGenOptions = array_merge($this->defaultGenOptions, array(
97
-			'relative' => true,
98
-			'refill_all_parameters' => false,
99
-			'omit_defaults' => false,
100
-		));
101
-	}
96
+        $this->defaultGenOptions = array_merge($this->defaultGenOptions, array(
97
+            'relative' => true,
98
+            'refill_all_parameters' => false,
99
+            'omit_defaults' => false,
100
+        ));
101
+    }
102 102
 	
103
-	/**
104
-	 * Initialize the routing instance.
105
-	 *
106
-	 * @param      Context $context    The Context.
107
-	 * @param      array   $parameters An array of initialization parameters.
108
-	 *
109
-	 * @author     Dominik del Bondio <[email protected]>
110
-	 * @author     David Zülke <[email protected]>
111
-	 * @since      0.11.0
112
-	 */
113
-	public function initialize(Context $context, array $parameters = array())
114
-	{
115
-		$this->context = $context;
116
-
117
-		$this->setParameters($parameters);
118
-
119
-		$this->defaultGenOptions = array_merge(
120
-			$this->defaultGenOptions,
121
-			$this->getParameter('default_gen_options', array())
122
-		);
123
-
124
-		$this->genOptionsPresets = array_merge(
125
-			$this->genOptionsPresets,
126
-			$this->getParameter('gen_options_presets', array())
127
-		);
103
+    /**
104
+     * Initialize the routing instance.
105
+     *
106
+     * @param      Context $context    The Context.
107
+     * @param      array   $parameters An array of initialization parameters.
108
+     *
109
+     * @author     Dominik del Bondio <[email protected]>
110
+     * @author     David Zülke <[email protected]>
111
+     * @since      0.11.0
112
+     */
113
+    public function initialize(Context $context, array $parameters = array())
114
+    {
115
+        $this->context = $context;
116
+
117
+        $this->setParameters($parameters);
118
+
119
+        $this->defaultGenOptions = array_merge(
120
+            $this->defaultGenOptions,
121
+            $this->getParameter('default_gen_options', array())
122
+        );
123
+
124
+        $this->genOptionsPresets = array_merge(
125
+            $this->genOptionsPresets,
126
+            $this->getParameter('gen_options_presets', array())
127
+        );
128 128
 		
129
-		// and load the config.
130
-		$this->loadConfig();
131
-	}
132
-
133
-	/**
134
-	 * Load the routing.xml configuration file.
135
-	 *
136
-	 * @author     David Zülke <[email protected]>
137
-	 * @since      0.11.0
138
-	 */
139
-	protected function loadConfig()
140
-	{
141
-		$cfg = Config::get('core.config_dir') . '/routing.xml';
142
-		// allow missing routing.xml when routing is not enabled
143
-		if($this->isEnabled() || is_readable($cfg)) {
144
-			$this->importRoutes(unserialize(file_get_contents(ConfigCache::checkConfig($cfg, $this->context->getName()))));
145
-		}
146
-	}
147
-
148
-	/**
149
-	 * Do any necessary startup work after initialization.
150
-	 *
151
-	 * This method is not called directly after initialize().
152
-	 *
153
-	 * @author     David Zülke <[email protected]>
154
-	 * @since      0.11.0
155
-	 */
156
-	public function startup()
157
-	{
158
-		$this->sources['_ENV'] = new RoutingArraySource($_ENV);
159
-
160
-		$this->sources['_SERVER'] = new RoutingArraySource($_SERVER);
161
-
162
-		if(Config::get('core.use_security')) {
163
-			$this->sources['user'] = new RoutingUserSource($this->context->getUser());
164
-		}
165
-	}
166
-
167
-	/**
168
-	 * Execute the shutdown procedure.
169
-	 *
170
-	 * @author     David Zülke <[email protected]>
171
-	 * @since      0.11.0
172
-	 */
173
-	public function shutdown()
174
-	{
175
-	}
176
-
177
-	/**
178
-	 * Check if this routing instance is enabled.
179
-	 *
180
-	 * @return     bool Whether or not routing is enabled.
181
-	 *
182
-	 * @author     David Zülke <[email protected]>
183
-	 * @since      1.0.0
184
-	 */
185
-	public function isEnabled()
186
-	{
187
-		return $this->getParameter('enabled') === true;
188
-	}
189
-
190
-	/**
191
-	 * Retrieve the current application context.
192
-	 *
193
-	 * @return     Context A Context instance.
194
-	 *
195
-	 * @author     Dominik del Bondio <[email protected]>
196
-	 * @since      0.11.0
197
-	 */
198
-	public final function getContext()
199
-	{
200
-		return $this->context;
201
-	}
202
-
203
-	/**
204
-	 * Retrieve the info about a named route for this routing instance.
205
-	 *
206
-	 * @return     mixed The route info or null if the route doesn't exist.
207
-	 *
208
-	 * @author     Dominik del Bondio <[email protected]>
209
-	 * @since      0.11.0
210
-	 */
211
-	public final function getRoute($name)
212
-	{
213
-		if(!isset($this->routes[$name])) {
214
-			return null;
215
-		}
216
-		return $this->routes[$name];
217
-	}
218
-
219
-	/**
220
-	 * Retrieve the input for this routing instance.
221
-	 *
222
-	 * @return     string The input.
223
-	 *
224
-	 * @author     Dominik del Bondio <[email protected]>
225
-	 * @since      0.11.0
226
-	 */
227
-	public final function getInput()
228
-	{
229
-		return $this->input;
230
-	}
231
-
232
-	/**
233
-	 * Retrieve the prefix for this routing instance.
234
-	 *
235
-	 * @return     string The prefix.
236
-	 *
237
-	 * @author     Dominik del Bondio <[email protected]>
238
-	 * @since      0.11.0
239
-	 */
240
-	public final function getPrefix()
241
-	{
242
-		return $this->prefix;
243
-	}
244
-
245
-	/**
246
-	 * Adds a route to this routing instance.
247
-	 *
248
-	 * @param      string $route   A string with embedded regexp.
249
-	 * @param      array  $options An array with options. The array can contain following
250
-	 *                   items:
251
-	 *                   <ul>
252
-	 *                    <li>name</li>
253
-	 *                    <li>stop</li>
254
-	 *                    <li>output_type</li>
255
-	 *                    <li>module</li>
256
-	 *                    <li>controller</li>
257
-	 *                    <li>parameters</li>
258
-	 *                    <li>ignores</li>
259
-	 *                    <li>defaults</li>
260
-	 *                    <li>childs</li>
261
-	 *                    <li>callbacks</li>
262
-	 *                    <li>imply</li>
263
-	 *                    <li>cut</li>
264
-	 *                    <li>source</li>
265
-	 *                   </ul>
266
-	 * @param      string $parent   The name of the parent route (if any).
267
-	 *
268
-	 * @return     string The name of the route.
269
-	 *
270
-	 * @author     Dominik del Bondio <[email protected]>
271
-	 * @since      0.11.0
272
-	 */
273
-	public function addRoute($route, array $options = array(), $parent = null)
274
-	{
275
-		// catch the old options from the route which has to be overwritten
276
-		if(isset($options['name']) && isset($this->routes[$options['name']])) {
277
-			$defaultOpts = $this->routes[$options['name']]['opt'];
278
-
279
-			// when the parent is set and differs from the parent of the route to be overwritten bail out
280
-			if($parent !== null && $defaultOpts['parent'] != $parent) {
281
-				throw new AgaviException('You are trying to overwrite a route but are not staying in the same hierarchy');
282
-			}
283
-
284
-			if($parent === null) {
285
-				$parent = $defaultOpts['parent'];
286
-			} else {
287
-				$defaultOpts['parent'] = $parent;
288
-			}
289
-		} else {
290
-			$defaultOpts = array('name' => Toolkit::uniqid(), 'stop' => true, 'output_type' => null, 'module' => null, 'controller' => null, 'parameters' => array(), 'ignores' => array(), 'defaults' => array(), 'childs' => array(), 'callbacks' => array(), 'imply' => false, 'cut' => null, 'source' => null, 'method' => null, 'constraint' => array(), 'locale' => null, 'pattern_parameters' => array(), 'optional_parameters' => array(), 'parent' => $parent, 'reverseStr' => '', 'nostops' => array(), 'anchor' => self::ANCHOR_NONE);
291
-		}
292
-		// retain backwards compatibility to 0.11
293
-		if(isset($options['callback'])) {
294
-			$options['callbacks'] = array(array('class' => $options['callback'], 'parameters' => array()));
295
-			unset($options['callback']);
296
-		}
297
-
298
-		if(isset($options['defaults'])) {
299
-			foreach($options['defaults'] as $name => &$value) {
300
-				$val = $pre = $post = null;
301
-				if(preg_match('#(.*)\{(.*)\}(.*)#', $value, $match)) {
302
-					$pre = $match[1];
303
-					$val = $match[2];
304
-					$post = $match[3];
305
-				} else {
306
-					$val = $value;
307
-				}
308
-
309
-				$value = $this->createValue($val)->setPrefix($pre)->setPostfix($post);
310
-			}
311
-		}
312
-
313
-		// set the default options + user opts
314
-		$options = array_merge($defaultOpts, $options);
315
-		list($regexp, $options['reverseStr'], $routeParams, $options['anchor']) = $this->parseRouteString($route);
316
-
317
-		$params = array();
318
-
319
-		// transfer the parameters and fill available automatic defaults
320
-		foreach($routeParams as $name => $param) {
321
-			$params[] = $name;
322
-
323
-			if($param['is_optional']) {
324
-				$options['optional_parameters'][$name] = true;
325
-			}
326
-
327
-			if(!isset($options['defaults'][$name]) && ($param['pre'] || $param['val'] || $param['post'])) {
328
-				unset($param['is_optional']);
329
-				$options['defaults'][$name] = $this->createValue($param['val'])->setPrefix($param['pre'])->setPostfix($param['post']);
330
-			}
331
-		}
332
-
333
-		$options['pattern_parameters'] = $params;
334
-
335
-		// remove all ignore from the parameters in the route
336
-		foreach($options['ignores'] as $ignore) {
337
-			if(($key = array_search($ignore, $params)) !== false) {
338
-				unset($params[$key]);
339
-			}
340
-		}
341
-
342
-		$routeName = $options['name'];
343
-
344
-		// parse all the setting values for dynamic variables
345
-		// check if 2 nodes with the same name in the same execution tree exist
346
-		foreach($this->routes as $name => $route) {
347
-			// if a route with this route as parent exist check if its really a child of our route
348
-			if($route['opt']['parent'] == $routeName && !in_array($name, $options['childs'])) {
349
-				throw new AgaviException('The route ' . $routeName . ' specifies a child route with the same name');
350
-			}
351
-		}
352
-
353
-		// direct childs/parents with the same name aren't caught by the above check
354
-		if($routeName == $parent) {
355
-			throw new AgaviException('The route ' . $routeName . ' specifies a child route with the same name');
356
-		}
357
-
358
-		// if we are a child route, we need add this route as a child to the parent
359
-		if($parent !== null) {
360
-			foreach($this->routes[$parent]['opt']['childs'] as $name) {
361
-				if($name == $routeName) {
362
-					// we're overwriting a route, so unlike when first adding the route, there are more routes after this that might also be non-stopping, but we obviously don't want those, so we need to bail out at this point
363
-					break;
364
-				}
365
-				$route = $this->routes[$name];
366
-				if(!$route['opt']['stop']) {
367
-					$options['nostops'][] = $name;
368
-				}
369
-			}
370
-			$this->routes[$parent]['opt']['childs'][] = $routeName;
371
-		} else {
372
-			foreach($this->routes as $name => $route) {
373
-				if($name == $routeName) {
374
-					// we're overwriting a route, so unlike when first adding the route, there are more routes after this that might also be non-stopping, but we obviously don't want those, so we need to bail out at this point
375
-					break;
376
-				}
377
-				if(!$route['opt']['stop'] && !$route['opt']['parent']) {
378
-					$options['nostops'][] = $name;
379
-				}
380
-			}
381
-		}
129
+        // and load the config.
130
+        $this->loadConfig();
131
+    }
132
+
133
+    /**
134
+     * Load the routing.xml configuration file.
135
+     *
136
+     * @author     David Zülke <[email protected]>
137
+     * @since      0.11.0
138
+     */
139
+    protected function loadConfig()
140
+    {
141
+        $cfg = Config::get('core.config_dir') . '/routing.xml';
142
+        // allow missing routing.xml when routing is not enabled
143
+        if($this->isEnabled() || is_readable($cfg)) {
144
+            $this->importRoutes(unserialize(file_get_contents(ConfigCache::checkConfig($cfg, $this->context->getName()))));
145
+        }
146
+    }
147
+
148
+    /**
149
+     * Do any necessary startup work after initialization.
150
+     *
151
+     * This method is not called directly after initialize().
152
+     *
153
+     * @author     David Zülke <[email protected]>
154
+     * @since      0.11.0
155
+     */
156
+    public function startup()
157
+    {
158
+        $this->sources['_ENV'] = new RoutingArraySource($_ENV);
159
+
160
+        $this->sources['_SERVER'] = new RoutingArraySource($_SERVER);
161
+
162
+        if(Config::get('core.use_security')) {
163
+            $this->sources['user'] = new RoutingUserSource($this->context->getUser());
164
+        }
165
+    }
166
+
167
+    /**
168
+     * Execute the shutdown procedure.
169
+     *
170
+     * @author     David Zülke <[email protected]>
171
+     * @since      0.11.0
172
+     */
173
+    public function shutdown()
174
+    {
175
+    }
176
+
177
+    /**
178
+     * Check if this routing instance is enabled.
179
+     *
180
+     * @return     bool Whether or not routing is enabled.
181
+     *
182
+     * @author     David Zülke <[email protected]>
183
+     * @since      1.0.0
184
+     */
185
+    public function isEnabled()
186
+    {
187
+        return $this->getParameter('enabled') === true;
188
+    }
189
+
190
+    /**
191
+     * Retrieve the current application context.
192
+     *
193
+     * @return     Context A Context instance.
194
+     *
195
+     * @author     Dominik del Bondio <[email protected]>
196
+     * @since      0.11.0
197
+     */
198
+    public final function getContext()
199
+    {
200
+        return $this->context;
201
+    }
202
+
203
+    /**
204
+     * Retrieve the info about a named route for this routing instance.
205
+     *
206
+     * @return     mixed The route info or null if the route doesn't exist.
207
+     *
208
+     * @author     Dominik del Bondio <[email protected]>
209
+     * @since      0.11.0
210
+     */
211
+    public final function getRoute($name)
212
+    {
213
+        if(!isset($this->routes[$name])) {
214
+            return null;
215
+        }
216
+        return $this->routes[$name];
217
+    }
218
+
219
+    /**
220
+     * Retrieve the input for this routing instance.
221
+     *
222
+     * @return     string The input.
223
+     *
224
+     * @author     Dominik del Bondio <[email protected]>
225
+     * @since      0.11.0
226
+     */
227
+    public final function getInput()
228
+    {
229
+        return $this->input;
230
+    }
231
+
232
+    /**
233
+     * Retrieve the prefix for this routing instance.
234
+     *
235
+     * @return     string The prefix.
236
+     *
237
+     * @author     Dominik del Bondio <[email protected]>
238
+     * @since      0.11.0
239
+     */
240
+    public final function getPrefix()
241
+    {
242
+        return $this->prefix;
243
+    }
244
+
245
+    /**
246
+     * Adds a route to this routing instance.
247
+     *
248
+     * @param      string $route   A string with embedded regexp.
249
+     * @param      array  $options An array with options. The array can contain following
250
+     *                   items:
251
+     *                   <ul>
252
+     *                    <li>name</li>
253
+     *                    <li>stop</li>
254
+     *                    <li>output_type</li>
255
+     *                    <li>module</li>
256
+     *                    <li>controller</li>
257
+     *                    <li>parameters</li>
258
+     *                    <li>ignores</li>
259
+     *                    <li>defaults</li>
260
+     *                    <li>childs</li>
261
+     *                    <li>callbacks</li>
262
+     *                    <li>imply</li>
263
+     *                    <li>cut</li>
264
+     *                    <li>source</li>
265
+     *                   </ul>
266
+     * @param      string $parent   The name of the parent route (if any).
267
+     *
268
+     * @return     string The name of the route.
269
+     *
270
+     * @author     Dominik del Bondio <[email protected]>
271
+     * @since      0.11.0
272
+     */
273
+    public function addRoute($route, array $options = array(), $parent = null)
274
+    {
275
+        // catch the old options from the route which has to be overwritten
276
+        if(isset($options['name']) && isset($this->routes[$options['name']])) {
277
+            $defaultOpts = $this->routes[$options['name']]['opt'];
278
+
279
+            // when the parent is set and differs from the parent of the route to be overwritten bail out
280
+            if($parent !== null && $defaultOpts['parent'] != $parent) {
281
+                throw new AgaviException('You are trying to overwrite a route but are not staying in the same hierarchy');
282
+            }
283
+
284
+            if($parent === null) {
285
+                $parent = $defaultOpts['parent'];
286
+            } else {
287
+                $defaultOpts['parent'] = $parent;
288
+            }
289
+        } else {
290
+            $defaultOpts = array('name' => Toolkit::uniqid(), 'stop' => true, 'output_type' => null, 'module' => null, 'controller' => null, 'parameters' => array(), 'ignores' => array(), 'defaults' => array(), 'childs' => array(), 'callbacks' => array(), 'imply' => false, 'cut' => null, 'source' => null, 'method' => null, 'constraint' => array(), 'locale' => null, 'pattern_parameters' => array(), 'optional_parameters' => array(), 'parent' => $parent, 'reverseStr' => '', 'nostops' => array(), 'anchor' => self::ANCHOR_NONE);
291
+        }
292
+        // retain backwards compatibility to 0.11
293
+        if(isset($options['callback'])) {
294
+            $options['callbacks'] = array(array('class' => $options['callback'], 'parameters' => array()));
295
+            unset($options['callback']);
296
+        }
297
+
298
+        if(isset($options['defaults'])) {
299
+            foreach($options['defaults'] as $name => &$value) {
300
+                $val = $pre = $post = null;
301
+                if(preg_match('#(.*)\{(.*)\}(.*)#', $value, $match)) {
302
+                    $pre = $match[1];
303
+                    $val = $match[2];
304
+                    $post = $match[3];
305
+                } else {
306
+                    $val = $value;
307
+                }
308
+
309
+                $value = $this->createValue($val)->setPrefix($pre)->setPostfix($post);
310
+            }
311
+        }
312
+
313
+        // set the default options + user opts
314
+        $options = array_merge($defaultOpts, $options);
315
+        list($regexp, $options['reverseStr'], $routeParams, $options['anchor']) = $this->parseRouteString($route);
316
+
317
+        $params = array();
318
+
319
+        // transfer the parameters and fill available automatic defaults
320
+        foreach($routeParams as $name => $param) {
321
+            $params[] = $name;
322
+
323
+            if($param['is_optional']) {
324
+                $options['optional_parameters'][$name] = true;
325
+            }
326
+
327
+            if(!isset($options['defaults'][$name]) && ($param['pre'] || $param['val'] || $param['post'])) {
328
+                unset($param['is_optional']);
329
+                $options['defaults'][$name] = $this->createValue($param['val'])->setPrefix($param['pre'])->setPostfix($param['post']);
330
+            }
331
+        }
332
+
333
+        $options['pattern_parameters'] = $params;
334
+
335
+        // remove all ignore from the parameters in the route
336
+        foreach($options['ignores'] as $ignore) {
337
+            if(($key = array_search($ignore, $params)) !== false) {
338
+                unset($params[$key]);
339
+            }
340
+        }
341
+
342
+        $routeName = $options['name'];
343
+
344
+        // parse all the setting values for dynamic variables
345
+        // check if 2 nodes with the same name in the same execution tree exist
346
+        foreach($this->routes as $name => $route) {
347
+            // if a route with this route as parent exist check if its really a child of our route
348
+            if($route['opt']['parent'] == $routeName && !in_array($name, $options['childs'])) {
349
+                throw new AgaviException('The route ' . $routeName . ' specifies a child route with the same name');
350
+            }
351
+        }
352
+
353
+        // direct childs/parents with the same name aren't caught by the above check
354
+        if($routeName == $parent) {
355
+            throw new AgaviException('The route ' . $routeName . ' specifies a child route with the same name');
356
+        }
357
+
358
+        // if we are a child route, we need add this route as a child to the parent
359
+        if($parent !== null) {
360
+            foreach($this->routes[$parent]['opt']['childs'] as $name) {
361
+                if($name == $routeName) {
362
+                    // we're overwriting a route, so unlike when first adding the route, there are more routes after this that might also be non-stopping, but we obviously don't want those, so we need to bail out at this point
363
+                    break;
364
+                }
365
+                $route = $this->routes[$name];
366
+                if(!$route['opt']['stop']) {
367
+                    $options['nostops'][] = $name;
368
+                }
369
+            }
370
+            $this->routes[$parent]['opt']['childs'][] = $routeName;
371
+        } else {
372
+            foreach($this->routes as $name => $route) {
373
+                if($name == $routeName) {
374
+                    // we're overwriting a route, so unlike when first adding the route, there are more routes after this that might also be non-stopping, but we obviously don't want those, so we need to bail out at this point
375
+                    break;
376
+                }
377
+                if(!$route['opt']['stop'] && !$route['opt']['parent']) {
378
+                    $options['nostops'][] = $name;
379
+                }
380
+            }
381
+        }
382 382
 		
383
-		// make sure we have no duplicates in the nostops (can happen when a route is overwritten)
384
-		$options['nostops'] = array_unique($options['nostops']);
385
-
386
-		$route = array('rxp' => $regexp, 'par' => $params, 'opt' => $options, 'matches' => array());
387
-		$this->routes[$routeName] = $route;
388
-
389
-		return $routeName;
390
-	}
391
-
392
-	/**
393
-	 * Retrieve the internal representation of the route info.
394
-	 *
395
-	 * @return     array The info about all routes.
396
-	 *
397
-	 * @author     Dominik del Bondio <[email protected]>
398
-	 * @since      0.11.0
399
-	 */
400
-	public function exportRoutes()
401
-	{
402
-		return $this->routes;
403
-	}
404
-
405
-	/**
406
-	 * Sets the internal representation of the route info.
407
-	 *
408
-	 * @param      array $route The info about all routes.
409
-	 *
410
-	 * @author     Dominik del Bondio <[email protected]>
411
-	 * @since      0.11.0
412
-	 */
413
-	public function importRoutes(array $routes)
414
-	{
415
-		$this->routes = $routes;
416
-	}
417
-
418
-	/**
419
-	 * Retrieves the routes which need to be taken into account when generating
420
-	 * the reverse string of a routing to be generated.
421
-	 *
422
-	 * @param      string $route       The route name(s, delimited by +) to calculate.
423
-	 * @param      bool   $isNullRoute Set to true if the requested route was 'null' or
424
-	 *                                 'null' + 'xxx'
425
-	 *
426
-	 * @return     array A list of names of affected routes.
427
-	 *
428
-	 * @author     Dominik del Bondio <[email protected]>
429
-	 * @since      0.11.0
430
-	 */
431
-	public function getAffectedRoutes($route, &$isNullRoute = false)
432
-	{
433
-		$includedRoutes = array();
434
-		$excludedRoutes = array();
383
+        // make sure we have no duplicates in the nostops (can happen when a route is overwritten)
384
+        $options['nostops'] = array_unique($options['nostops']);
385
+
386
+        $route = array('rxp' => $regexp, 'par' => $params, 'opt' => $options, 'matches' => array());
387
+        $this->routes[$routeName] = $route;
388
+
389
+        return $routeName;
390
+    }
391
+
392
+    /**
393
+     * Retrieve the internal representation of the route info.
394
+     *
395
+     * @return     array The info about all routes.
396
+     *
397
+     * @author     Dominik del Bondio <[email protected]>
398
+     * @since      0.11.0
399
+     */
400
+    public function exportRoutes()
401
+    {
402
+        return $this->routes;
403
+    }
404
+
405
+    /**
406
+     * Sets the internal representation of the route info.
407
+     *
408
+     * @param      array $route The info about all routes.
409
+     *
410
+     * @author     Dominik del Bondio <[email protected]>
411
+     * @since      0.11.0
412
+     */
413
+    public function importRoutes(array $routes)
414
+    {
415
+        $this->routes = $routes;
416
+    }
417
+
418
+    /**
419
+     * Retrieves the routes which need to be taken into account when generating
420
+     * the reverse string of a routing to be generated.
421
+     *
422
+     * @param      string $route       The route name(s, delimited by +) to calculate.
423
+     * @param      bool   $isNullRoute Set to true if the requested route was 'null' or
424
+     *                                 'null' + 'xxx'
425
+     *
426
+     * @return     array A list of names of affected routes.
427
+     *
428
+     * @author     Dominik del Bondio <[email protected]>
429
+     * @since      0.11.0
430
+     */
431
+    public function getAffectedRoutes($route, &$isNullRoute = false)
432
+    {
433
+        $includedRoutes = array();
434
+        $excludedRoutes = array();
435 435
 		
436
-		if($route === null) {
437
-			$includedRoutes = array_reverse($this->getContext()->getRequest()->getAttribute('matched_routes', 'org.agavi.routing', array()));
438
-			$isNullRoute = true;
439
-		} elseif(strlen($route) > 0) {
440
-			if($route[0] == '-' || $route[0] == '+') {
441
-				$includedRoutes = array_reverse($this->getContext()->getRequest()->getAttribute('matched_routes', 'org.agavi.routing', array()));
442
-				$isNullRoute = true;
443
-			}
436
+        if($route === null) {
437
+            $includedRoutes = array_reverse($this->getContext()->getRequest()->getAttribute('matched_routes', 'org.agavi.routing', array()));
438
+            $isNullRoute = true;
439
+        } elseif(strlen($route) > 0) {
440
+            if($route[0] == '-' || $route[0] == '+') {
441
+                $includedRoutes = array_reverse($this->getContext()->getRequest()->getAttribute('matched_routes', 'org.agavi.routing', array()));
442
+                $isNullRoute = true;
443
+            }
444 444
 			
445
-			$routeParts = preg_split('#(-|\+)#', $route, -1, PREG_SPLIT_DELIM_CAPTURE);
446
-			$prevDelimiter = '+';
447
-			foreach($routeParts as $part) {
448
-				if($part == '+' || $part == '-') {
449
-					$prevDelimiter = $part;
450
-				}
445
+            $routeParts = preg_split('#(-|\+)#', $route, -1, PREG_SPLIT_DELIM_CAPTURE);
446
+            $prevDelimiter = '+';
447
+            foreach($routeParts as $part) {
448
+                if($part == '+' || $part == '-') {
449
+                    $prevDelimiter = $part;
450
+                }
451 451
 				
452
-				if($prevDelimiter == '+') {
453
-					$includedRoutes[] = $part;
454
-				} else { // $prevDelimiter == '-'
455
-					$excludedRoutes[] = $part;
456
-				}
457
-			}
458
-		}
452
+                if($prevDelimiter == '+') {
453
+                    $includedRoutes[] = $part;
454
+                } else { // $prevDelimiter == '-'
455
+                    $excludedRoutes[] = $part;
456
+                }
457
+            }
458
+        }
459 459
 		
460
-		$excludedRoutes = array_flip($excludedRoutes);
460
+        $excludedRoutes = array_flip($excludedRoutes);
461 461
 
462
-		if($includedRoutes) {
463
-			$route = $includedRoutes[0];
464
-			// TODO: useful comment here
465
-			unset($includedRoutes[0]);
466
-		}
462
+        if($includedRoutes) {
463
+            $route = $includedRoutes[0];
464
+            // TODO: useful comment here
465
+            unset($includedRoutes[0]);
466
+        }
467 467
 		
468
-		$myRoutes = array();
469
-		foreach($includedRoutes as $r) {
470
-			$myRoutes[$r] = true;
471
-		}
472
-
473
-		$affectedRoutes = array();
474
-
475
-		if(isset($this->routes[$route])) {
476
-			$parent = $route;
477
-			do {
478
-				if(!isset($excludedRoutes[$parent])) {
479
-					$affectedRoutes[] = $parent;
480
-				}
481
-				$r = $this->routes[$parent];
482
-
483
-				foreach(array_reverse($r['opt']['nostops']) as $noStop) {
484
-					$myR = $this->routes[$noStop];
485
-					if(isset($myRoutes[$noStop])) {
486
-						unset($myRoutes[$noStop]);
487
-					} elseif(!$myR['opt']['imply']) {
488
-						continue;
489
-					}
490
-
491
-					if(!isset($excludedRoutes[$noStop])) {
492
-						$affectedRoutes[] = $noStop;
493
-					}
494
-				}
495
-
496
-				$parent = $r['opt']['parent'];
497
-
498
-			} while($parent);
499
-		} else {
500
-			// TODO: error handling - route with the given name does not exist
501
-		}
502
-
503
-		if(count($myRoutes)) {
504
-			// TODO: error handling - we couldn't find some of the nonstopping rules
505
-		}
506
-
507
-		return $affectedRoutes;
508
-	}
468
+        $myRoutes = array();
469
+        foreach($includedRoutes as $r) {
470
+            $myRoutes[$r] = true;
471
+        }
472
+
473
+        $affectedRoutes = array();
474
+
475
+        if(isset($this->routes[$route])) {
476
+            $parent = $route;
477
+            do {
478
+                if(!isset($excludedRoutes[$parent])) {
479
+                    $affectedRoutes[] = $parent;
480
+                }
481
+                $r = $this->routes[$parent];
482
+
483
+                foreach(array_reverse($r['opt']['nostops']) as $noStop) {
484
+                    $myR = $this->routes[$noStop];
485
+                    if(isset($myRoutes[$noStop])) {
486
+                        unset($myRoutes[$noStop]);
487
+                    } elseif(!$myR['opt']['imply']) {
488
+                        continue;
489
+                    }
490
+
491
+                    if(!isset($excludedRoutes[$noStop])) {
492
+                        $affectedRoutes[] = $noStop;
493
+                    }
494
+                }
495
+
496
+                $parent = $r['opt']['parent'];
497
+
498
+            } while($parent);
499
+        } else {
500
+            // TODO: error handling - route with the given name does not exist
501
+        }
502
+
503
+        if(count($myRoutes)) {
504
+            // TODO: error handling - we couldn't find some of the nonstopping rules
505
+        }
506
+
507
+        return $affectedRoutes;
508
+    }
509 509
 	
510
-	/**
511
-	 * Get a list of all parameter matches which where matched in execute()
512
-	 * in the given routes. 
513
-	 *
514
-	 * @param      array $routeNames An array of route names.
515
-	 *
516
-	 * @return     array The matched parameters as name => value.
517
-	 *
518
-	 * @author     Dominik del Bondio <[email protected]>
519
-	 * @since      1.0.0
520
-	 */
521
-	public function getMatchedParameters(array $routeNames)
522
-	{
523
-		$params = array();
524
-		foreach($routeNames as $name) {
525
-			if(isset($this->routes[$name])) {
526
-				$route = $this->routes[$name];
527
-				$params = array_merge($params, $route['matches']);
528
-			}
529
-		}
530
-		return $params;
531
-	}
510
+    /**
511
+     * Get a list of all parameter matches which where matched in execute()
512
+     * in the given routes. 
513
+     *
514
+     * @param      array $routeNames An array of route names.
515
+     *
516
+     * @return     array The matched parameters as name => value.
517
+     *
518
+     * @author     Dominik del Bondio <[email protected]>
519
+     * @since      1.0.0
520
+     */
521
+    public function getMatchedParameters(array $routeNames)
522
+    {
523
+        $params = array();
524
+        foreach($routeNames as $name) {
525
+            if(isset($this->routes[$name])) {
526
+                $route = $this->routes[$name];
527
+                $params = array_merge($params, $route['matches']);
528
+            }
529
+        }
530
+        return $params;
531
+    }
532 532
 	
533
-	/**
534
-	 * Get a complete list of gen() options based on the given, probably
535
-	 * incomplete, options array, and/or options preset name(s).
536
-	 *
537
-	 * @param      mixed $input An array of gen options and names of options presets
538
-	 *                   or just the name of a single option preset.
539
-	 *
540
-	 * @return     array A complete array of options.
541
-	 *
542
-	 * @throws     \Exception If the given preset name doesn't exist.
543
-	 *
544
-	 * @author     David Zülke <[email protected]>
545
-	 * @since      0.11.0
546
-	 */
547
-	protected function resolveGenOptions($input = array())
548
-	{
549
-		if(is_string($input)) {
550
-			// A single option preset was given
551
-			if(isset($this->genOptionsPresets[$input])) {
552
-				return array_merge($this->defaultGenOptions, $this->genOptionsPresets[$input]);
553
-			}
554
-		} elseif(is_array($input)) {
555
-			$genOptions = $this->defaultGenOptions;
556
-			foreach($input as $key => $value) {
557
-				if(is_numeric($key)) {
558
-					// Numeric key – it's an option preset
559
-					if(isset($this->genOptionsPresets[$value])) {
560
-						$genOptions = array_merge($genOptions, $this->genOptionsPresets[$value]);
561
-					} else {
562
-						throw new AgaviException('Undefined Routing gen() options preset "' . $value . '"');
563
-					}
564
-				} else {
565
-					// String key – it's an option
566
-					$genOptions[$key] = $value;
567
-				}
568
-			}
569
-			return $genOptions;
570
-		}
571
-		throw new AgaviException('Unexpected type "' . gettype($input) . '" used as Routing gen() option preset identifier');
572
-	}
533
+    /**
534
+     * Get a complete list of gen() options based on the given, probably
535
+     * incomplete, options array, and/or options preset name(s).
536
+     *
537
+     * @param      mixed $input An array of gen options and names of options presets
538
+     *                   or just the name of a single option preset.
539
+     *
540
+     * @return     array A complete array of options.
541
+     *
542
+     * @throws     \Exception If the given preset name doesn't exist.
543
+     *
544
+     * @author     David Zülke <[email protected]>
545
+     * @since      0.11.0
546
+     */
547
+    protected function resolveGenOptions($input = array())
548
+    {
549
+        if(is_string($input)) {
550
+            // A single option preset was given
551
+            if(isset($this->genOptionsPresets[$input])) {
552
+                return array_merge($this->defaultGenOptions, $this->genOptionsPresets[$input]);
553
+            }
554
+        } elseif(is_array($input)) {
555
+            $genOptions = $this->defaultGenOptions;
556
+            foreach($input as $key => $value) {
557
+                if(is_numeric($key)) {
558
+                    // Numeric key – it's an option preset
559
+                    if(isset($this->genOptionsPresets[$value])) {
560
+                        $genOptions = array_merge($genOptions, $this->genOptionsPresets[$value]);
561
+                    } else {
562
+                        throw new AgaviException('Undefined Routing gen() options preset "' . $value . '"');
563
+                    }
564
+                } else {
565
+                    // String key – it's an option
566
+                    $genOptions[$key] = $value;
567
+                }
568
+            }
569
+            return $genOptions;
570
+        }
571
+        throw new AgaviException('Unexpected type "' . gettype($input) . '" used as Routing gen() option preset identifier');
572
+    }
573 573
 	
574
-	/**
575
-	 * Adds the matched parameters from the 'null' routes to the given parameters
576
-	 * (without overwriting existing ones)
577
-	 * 
578
-	 * @param      array $routeNames The route names
579
-	 * @param      array $params     The parameters
580
-	 * 
581
-	 * @return     array The new parameters
582
-	 * 
583
-	 * @author     Dominik del Bondio <[email protected]>
584
-	 * @since      1.0.0
585
-	 */
586
-	public function fillGenNullParameters(array $routeNames, array $params)
587
-	{
588
-		return array_merge($this->getMatchedParameters($routeNames), $params);
589
-	}
574
+    /**
575
+     * Adds the matched parameters from the 'null' routes to the given parameters
576
+     * (without overwriting existing ones)
577
+     * 
578
+     * @param      array $routeNames The route names
579
+     * @param      array $params     The parameters
580
+     * 
581
+     * @return     array The new parameters
582
+     * 
583
+     * @author     Dominik del Bondio <[email protected]>
584
+     * @since      1.0.0
585
+     */
586
+    public function fillGenNullParameters(array $routeNames, array $params)
587
+    {
588
+        return array_merge($this->getMatchedParameters($routeNames), $params);
589
+    }
590 590
 	
591
-	/**
592
-	 * Builds the routing information (result string, all kinds of parameters)
593
-	 * for the given routes.
594
-	 * 
595
-	 * @param      array $options    The options
596
-	 * @param      array $routeNames The names of the routes to generate
597
-	 * @param      array $params     The parameters supplied by the user
598
-	 * 
599
-	 * @return     array
600
-	 * 
601
-	 * @author     Dominik del Bondio <[email protected]>
602
-	 * @since      1.0.0
603
-	 */
604
-	protected function assembleRoutes(array $options, array $routeNames, array $params)
605
-	{
606
-		$uri = '';
607
-		$defaultParams = array();
608
-		$availableParams = array();
609
-		$matchedParams = array(); // the merged incoming matched params of implied routes
610
-		$optionalParams = array();
611
-		$firstRoute = true;
591
+    /**
592
+     * Builds the routing information (result string, all kinds of parameters)
593
+     * for the given routes.
594
+     * 
595
+     * @param      array $options    The options
596
+     * @param      array $routeNames The names of the routes to generate
597
+     * @param      array $params     The parameters supplied by the user
598
+     * 
599
+     * @return     array
600
+     * 
601
+     * @author     Dominik del Bondio <[email protected]>
602
+     * @since      1.0.0
603
+     */
604
+    protected function assembleRoutes(array $options, array $routeNames, array $params)
605
+    {
606
+        $uri = '';
607
+        $defaultParams = array();
608
+        $availableParams = array();
609
+        $matchedParams = array(); // the merged incoming matched params of implied routes
610
+        $optionalParams = array();
611
+        $firstRoute = true;
612 612
 		
613
-		foreach($routeNames as $routeName) {
614
-			$r = $this->routes[$routeName];
615
-
616
-			$myDefaults = $r['opt']['defaults'];
617
-
618
-			if(count($r['opt']['callbacks']) > 0) {
619
-				if(!isset($r['callback_instances'])) {
620
-					foreach($r['opt']['callbacks'] as $key => $callback) {
621
-						/** @var RoutingCallback $instance */
622
-						$instance = new $callback['class']();
623
-						$instance->setParameters($callback['parameters']);
624
-						$instance->initialize($this->context, $r);
625
-						$r['callback_instances'][$key] = $instance;
626
-					}
627
-				}
628
-				foreach($r['callback_instances'] as $callbackInstance) {
629
-					$paramsCopy = $params;
630
-					$isLegacyCallback = false;
631
-					if($callbackInstance instanceof LegacyRoutingCallbackInterface) {
632
-						$isLegacyCallback = true;
633
-						// convert all routing values to strings so legacy callbacks don't break
634
-						$defaultsCopy = $myDefaults;
635
-						foreach($paramsCopy as &$param) {
636
-							if($param instanceof RoutingValueInterface) {
637
-								$param = $param->getValue();
638
-							}
639
-						}
640
-						foreach($defaultsCopy as &$default) {
641
-							if($default instanceof RoutingValueInterface) {
642
-								$default = array(
643
-									'pre' => $default->getPrefix(),
644
-									'val' => $default->getValue(),
645
-									'post' => $default->getPostfix(),
646
-								);
647
-							}
648
-						}
649
-						$changedParamsCopy = $paramsCopy;
650
-						if(!$callbackInstance->onGenerate($defaultsCopy, $paramsCopy, $options)) {
651
-							continue 2;
652
-						}
653
-						// find all params changed in the callback, but ignore unset() parameters since they will be filled in at a later stage (and doing something the them would prevent default values being inserted after unset()tting of a parameter)
654
-						$diff = array();
655
-						foreach($paramsCopy as $key => $value) {
656
-							if(!array_key_exists($key, $changedParamsCopy) || $changedParamsCopy[$key] !== $value) {
657
-								$diff[$key] = $value;
658
-							}
659
-						}
660
-						// do *not* use this instead, it will segfault in PHP < 5.2.6:
661
-						// $diff = array_udiff_assoc($paramsCopy, $changedParamsCopy, array($this, 'onGenerateParamDiffCallback'));
662
-						// likely caused by http://bugs.php.net/bug.php?id=42838 / http://cvs.php.net/viewvc.cgi/php-src/ext/standard/array.c?r1=1.308.2.21.2.51&r2=1.308.2.21.2.52
663
-					} else {
664
-						if(!$callbackInstance->onGenerate($myDefaults, $params, $options)) {
665
-							continue 2;
666
-						}
667
-						// find all params changed in the callback, but ignore unset() parameters since they will be filled in at a later stage (and doing something the them would prevent default values being inserted after unset()tting of a parameter)
668
-						$diff = array();
669
-						foreach($params as $key => $value) {
670
-							if(!array_key_exists($key, $paramsCopy) || $paramsCopy[$key] !== $value) {
671
-								$diff[$key] = $value;
672
-							}
673
-						}
674
-						// do *not* use this instead, it will segfault in PHP < 5.2.6:
675
-						// $diff = array_udiff_assoc($params, $paramsCopy, array($this, 'onGenerateParamDiffCallback'));
676
-						// likely caused by http://bugs.php.net/bug.php?id=42838 / http://cvs.php.net/viewvc.cgi/php-src/ext/standard/array.c?r1=1.308.2.21.2.51&r2=1.308.2.21.2.52
677
-					}
613
+        foreach($routeNames as $routeName) {
614
+            $r = $this->routes[$routeName];
615
+
616
+            $myDefaults = $r['opt']['defaults'];
617
+
618
+            if(count($r['opt']['callbacks']) > 0) {
619
+                if(!isset($r['callback_instances'])) {
620
+                    foreach($r['opt']['callbacks'] as $key => $callback) {
621
+                        /** @var RoutingCallback $instance */
622
+                        $instance = new $callback['class']();
623
+                        $instance->setParameters($callback['parameters']);
624
+                        $instance->initialize($this->context, $r);
625
+                        $r['callback_instances'][$key] = $instance;
626
+                    }
627
+                }
628
+                foreach($r['callback_instances'] as $callbackInstance) {
629
+                    $paramsCopy = $params;
630
+                    $isLegacyCallback = false;
631
+                    if($callbackInstance instanceof LegacyRoutingCallbackInterface) {
632
+                        $isLegacyCallback = true;
633
+                        // convert all routing values to strings so legacy callbacks don't break
634
+                        $defaultsCopy = $myDefaults;
635
+                        foreach($paramsCopy as &$param) {
636
+                            if($param instanceof RoutingValueInterface) {
637
+                                $param = $param->getValue();
638
+                            }
639
+                        }
640
+                        foreach($defaultsCopy as &$default) {
641
+                            if($default instanceof RoutingValueInterface) {
642
+                                $default = array(
643
+                                    'pre' => $default->getPrefix(),
644
+                                    'val' => $default->getValue(),
645
+                                    'post' => $default->getPostfix(),
646
+                                );
647
+                            }
648
+                        }
649
+                        $changedParamsCopy = $paramsCopy;
650
+                        if(!$callbackInstance->onGenerate($defaultsCopy, $paramsCopy, $options)) {
651
+                            continue 2;
652
+                        }
653
+                        // find all params changed in the callback, but ignore unset() parameters since they will be filled in at a later stage (and doing something the them would prevent default values being inserted after unset()tting of a parameter)
654
+                        $diff = array();
655
+                        foreach($paramsCopy as $key => $value) {
656
+                            if(!array_key_exists($key, $changedParamsCopy) || $changedParamsCopy[$key] !== $value) {
657
+                                $diff[$key] = $value;
658
+                            }
659
+                        }
660
+                        // do *not* use this instead, it will segfault in PHP < 5.2.6:
661
+                        // $diff = array_udiff_assoc($paramsCopy, $changedParamsCopy, array($this, 'onGenerateParamDiffCallback'));
662
+                        // likely caused by http://bugs.php.net/bug.php?id=42838 / http://cvs.php.net/viewvc.cgi/php-src/ext/standard/array.c?r1=1.308.2.21.2.51&r2=1.308.2.21.2.52
663
+                    } else {
664
+                        if(!$callbackInstance->onGenerate($myDefaults, $params, $options)) {
665
+                            continue 2;
666
+                        }
667
+                        // find all params changed in the callback, but ignore unset() parameters since they will be filled in at a later stage (and doing something the them would prevent default values being inserted after unset()tting of a parameter)
668
+                        $diff = array();
669
+                        foreach($params as $key => $value) {
670
+                            if(!array_key_exists($key, $paramsCopy) || $paramsCopy[$key] !== $value) {
671
+                                $diff[$key] = $value;
672
+                            }
673
+                        }
674
+                        // do *not* use this instead, it will segfault in PHP < 5.2.6:
675
+                        // $diff = array_udiff_assoc($params, $paramsCopy, array($this, 'onGenerateParamDiffCallback'));
676
+                        // likely caused by http://bugs.php.net/bug.php?id=42838 / http://cvs.php.net/viewvc.cgi/php-src/ext/standard/array.c?r1=1.308.2.21.2.51&r2=1.308.2.21.2.52
677
+                    }
678 678
 					
679
-					if(count($diff)) {
680
-						$diffKeys = array_keys($diff);
681
-						foreach($diffKeys as $key) {
682
-							// NEVER assign this value as a reference, as PHP will go completely bonkers if we use a reference here (it marks the entry in the array as a reference, so modifying the value in $params in a callback means it gets modified in $paramsCopy as well)
683
-							// if the callback was a legacy callback, the array to read the values from is different (since everything was cast to strings before running the callback)
684
-							$value = $isLegacyCallback ? $paramsCopy[$key] : $params[$key];
685
-							if($value !== null && !($value instanceof RoutingValueInterface)) {
686
-								$routingValue = $this->createValue($value, false);
687
-								if(isset($myDefaults[$key])) {
688
-									if($myDefaults[$key] instanceof RoutingValueInterface) {
689
-										// clone the default value so pre and postfix are preserved
690
-										/** @var RoutingValue $routingValue */
691
-										$routingValue = clone $myDefaults[$key];
692
-										// BC: When setting a value in a callback it was supposed to be already encoded
693
-										$routingValue->setValue($value)->setValueNeedsEncoding(false);
694
-									} else {
695
-										// $myDefaults[$key] can only be an array at this stage
696
-										$routingValue->setPrefix($myDefaults[$key]['pre'])->setPrefixNeedsEncoding(false);
697
-										$routingValue->setPostfix($myDefaults[$key]['post'])->setPostfixNeedsEncoding(false);
698
-									}
699
-								}
700
-								$value = $routingValue;
701
-							}
702
-							// for writing no legacy check mustn't be done, since that would mean the changed value would get lost
703
-							$params[$key] = $value;
704
-						}
705
-					}
706
-				}
707
-			}
708
-
709
-			// if the route has a source we shouldn't put its stuff in the generated string
710
-			if($r['opt']['source']) {
711
-				continue;
712
-			}
713
-
714
-			$matchedParams = array_merge($matchedParams, $r['matches']);
715
-			$optionalParams = array_merge($optionalParams, $r['opt']['optional_parameters']);
716
-
717
-			$availableParams = array_merge($availableParams, array_reverse($r['opt']['pattern_parameters']));
718
-
719
-			if($firstRoute || $r['opt']['cut'] || (count($r['opt']['childs']) && $r['opt']['cut'] === null)) {
720
-				if($r['opt']['anchor'] & self::ANCHOR_START || $r['opt']['anchor'] == self::ANCHOR_NONE) {
721
-					$uri = $r['opt']['reverseStr'] . $uri;
722
-				} else {
723
-					$uri = $uri . $r['opt']['reverseStr'];
724
-				}
725
-			}
726
-
727
-			$defaultParams = array_merge($defaultParams, $myDefaults);
728
-			$firstRoute = false;
729
-		}
679
+                    if(count($diff)) {
680
+                        $diffKeys = array_keys($diff);
681
+                        foreach($diffKeys as $key) {
682
+                            // NEVER assign this value as a reference, as PHP will go completely bonkers if we use a reference here (it marks the entry in the array as a reference, so modifying the value in $params in a callback means it gets modified in $paramsCopy as well)
683
+                            // if the callback was a legacy callback, the array to read the values from is different (since everything was cast to strings before running the callback)
684
+                            $value = $isLegacyCallback ? $paramsCopy[$key] : $params[$key];
685
+                            if($value !== null && !($value instanceof RoutingValueInterface)) {
686
+                                $routingValue = $this->createValue($value, false);
687
+                                if(isset($myDefaults[$key])) {
688
+                                    if($myDefaults[$key] instanceof RoutingValueInterface) {
689
+                                        // clone the default value so pre and postfix are preserved
690
+                                        /** @var RoutingValue $routingValue */
691
+                                        $routingValue = clone $myDefaults[$key];
692
+                                        // BC: When setting a value in a callback it was supposed to be already encoded
693
+                                        $routingValue->setValue($value)->setValueNeedsEncoding(false);
694
+                                    } else {
695
+                                        // $myDefaults[$key] can only be an array at this stage
696
+                                        $routingValue->setPrefix($myDefaults[$key]['pre'])->setPrefixNeedsEncoding(false);
697
+                                        $routingValue->setPostfix($myDefaults[$key]['post'])->setPostfixNeedsEncoding(false);
698
+                                    }
699
+                                }
700
+                                $value = $routingValue;
701
+                            }
702
+                            // for writing no legacy check mustn't be done, since that would mean the changed value would get lost
703
+                            $params[$key] = $value;
704
+                        }
705
+                    }
706
+                }
707
+            }
708
+
709
+            // if the route has a source we shouldn't put its stuff in the generated string
710
+            if($r['opt']['source']) {
711
+                continue;
712
+            }
713
+
714
+            $matchedParams = array_merge($matchedParams, $r['matches']);
715
+            $optionalParams = array_merge($optionalParams, $r['opt']['optional_parameters']);
716
+
717
+            $availableParams = array_merge($availableParams, array_reverse($r['opt']['pattern_parameters']));
718
+
719
+            if($firstRoute || $r['opt']['cut'] || (count($r['opt']['childs']) && $r['opt']['cut'] === null)) {
720
+                if($r['opt']['anchor'] & self::ANCHOR_START || $r['opt']['anchor'] == self::ANCHOR_NONE) {
721
+                    $uri = $r['opt']['reverseStr'] . $uri;
722
+                } else {
723
+                    $uri = $uri . $r['opt']['reverseStr'];
724
+                }
725
+            }
726
+
727
+            $defaultParams = array_merge($defaultParams, $myDefaults);
728
+            $firstRoute = false;
729
+        }
730 730
 		
731
-		$availableParams = array_reverse($availableParams);
731
+        $availableParams = array_reverse($availableParams);
732 732
 		
733
-		return array(
734
-			'uri' => $uri,
735
-			'options' => $options,
736
-			'user_parameters' => $params,
737
-			'available_parameters' => $availableParams,
738
-			'matched_parameters' => $matchedParams,
739
-			'optional_parameters' => $optionalParams,
740
-			'default_parameters' => $defaultParams,
741
-		);
742
-	}
733
+        return array(
734
+            'uri' => $uri,
735
+            'options' => $options,
736
+            'user_parameters' => $params,
737
+            'available_parameters' => $availableParams,
738
+            'matched_parameters' => $matchedParams,
739
+            'optional_parameters' => $optionalParams,
740
+            'default_parameters' => $defaultParams,
741
+        );
742
+    }
743 743
 	
744
-	/**
745
-	 * Adds all matched parameters to the supplied parameters. Will not overwrite
746
-	 * already existing parameters.
747
-	 * 
748
-	 * @param      array $options       The options
749
-	 * @param      array $params        The parameters supplied by the user
750
-	 * @param      array $matchedParams The parameters which matched in execute()
751
-	 * 
752
-	 * @return     array The $params with the added matched parameters
753
-	 * 
754
-	 * @author     Dominik del Bondio <[email protected]>
755
-	 * @since      1.0.0
756
-	 */
757
-	protected function refillAllMatchedParameters(array $options, array $params, array $matchedParams)
758
-	{
759
-		if(!empty($options['refill_all_parameters'])) {
760
-			foreach($matchedParams as $name => $value) {
761
-				if(!(isset($params[$name]) || array_key_exists($name, $params))) {
762
-					$params[$name] = $this->createValue($value, true);
763
-				}
764
-			}
765
-		}
744
+    /**
745
+     * Adds all matched parameters to the supplied parameters. Will not overwrite
746
+     * already existing parameters.
747
+     * 
748
+     * @param      array $options       The options
749
+     * @param      array $params        The parameters supplied by the user
750
+     * @param      array $matchedParams The parameters which matched in execute()
751
+     * 
752
+     * @return     array The $params with the added matched parameters
753
+     * 
754
+     * @author     Dominik del Bondio <[email protected]>
755
+     * @since      1.0.0
756
+     */
757
+    protected function refillAllMatchedParameters(array $options, array $params, array $matchedParams)
758
+    {
759
+        if(!empty($options['refill_all_parameters'])) {
760
+            foreach($matchedParams as $name => $value) {
761
+                if(!(isset($params[$name]) || array_key_exists($name, $params))) {
762
+                    $params[$name] = $this->createValue($value, true);
763
+                }
764
+            }
765
+        }
766 766
 		
767
-		return $params;
768
-	}
767
+        return $params;
768
+    }
769 769
 	
770
-	/**
771
-	 * Adds all parameters which were matched in the incoming routes to the 
772
-	 * generated route up the first user supplied parameter (from left to right)
773
-	 * Also adds the default value for all non optional parameters the user 
774
-	 * didn't supply.
775
-	 * 
776
-	 * @param      array $options The options
777
-	 * @param      array $originalUserParams The parameters originally passed to gen()
778
-	 * @param      array $params The parameters
779
-	 * @param      array $availableParams A list of parameter names available for the route
780
-	 * @param      array $matchedParams The matched parameters from execute() for the route
781
-	 * @param      array $optionalParams the optional parameters for the route
782
-	 * @param      array $defaultParams the default parameters for the route
783
-	 * 
784
-	 * @return     array The 'final' parameters
785
-	 * 
786
-	 * @author     Dominik del Bondio <[email protected]>
787
-	 * @since      1.0.0
788
-	 */
789
-	protected function refillMatchedAndDefaultParameters(array $options, array $originalUserParams, array $params, array $availableParams, array $matchedParams, array $optionalParams, array $defaultParams)
790
-	{
791
-		$refillValue = true;
792
-		$finalParams = array();
793
-		foreach($availableParams as $name) {
794
-			// loop all params and fill all with the matched parameters
795
-			// until a user (not callback) supplied parameter is encountered.
796
-			// After that only check defaults. Parameters supplied from the user
797
-			// or via callback always have precedence
798
-
799
-			// keep track if a user supplied parameter has already been encountered
800
-			if($refillValue && (isset($originalUserParams[$name]) || array_key_exists($name, $originalUserParams))) {
801
-				$refillValue = false;
802
-			}
803
-
804
-			// these 'aliases' are just for readability of the lower block
805
-			$isOptional = isset($optionalParams[$name]);
806
-			$hasMatched = isset($matchedParams[$name]);
807
-			$hasDefault = isset($defaultParams[$name]);
808
-			$hasUserCallbackParam = (isset($params[$name]) || array_key_exists($name, $params));
809
-
810
-			if($hasUserCallbackParam) {
811
-				// anything a user or callback supplied has precedence
812
-				// and since the user params are handled afterwards, skip them here
813
-			} elseif($refillValue && $hasMatched) {
814
-				// Use the matched input
815
-				$finalParams[$name] = $this->createValue($matchedParams[$name], true);
816
-			} elseif($hasDefault) {
817
-				// now we just need to check if there are defaults for this available param and fill them in if applicable
818
-				$default = $defaultParams[$name];
819
-				if(!$isOptional || strlen($default->getValue()) > 0) {
820
-					$finalParams[$name] = clone $default;
821
-				} elseif($isOptional) {
822
-					// there is no default or incoming match for this optional param, so remove it
823
-					$finalParams[$name] = null;
824
-				}
825
-			}
826
-		}
827
-
828
-		return $finalParams;
829
-	}
770
+    /**
771
+     * Adds all parameters which were matched in the incoming routes to the 
772
+     * generated route up the first user supplied parameter (from left to right)
773
+     * Also adds the default value for all non optional parameters the user 
774
+     * didn't supply.
775
+     * 
776
+     * @param      array $options The options
777
+     * @param      array $originalUserParams The parameters originally passed to gen()
778
+     * @param      array $params The parameters
779
+     * @param      array $availableParams A list of parameter names available for the route
780
+     * @param      array $matchedParams The matched parameters from execute() for the route
781
+     * @param      array $optionalParams the optional parameters for the route
782
+     * @param      array $defaultParams the default parameters for the route
783
+     * 
784
+     * @return     array The 'final' parameters
785
+     * 
786
+     * @author     Dominik del Bondio <[email protected]>
787
+     * @since      1.0.0
788
+     */
789
+    protected function refillMatchedAndDefaultParameters(array $options, array $originalUserParams, array $params, array $availableParams, array $matchedParams, array $optionalParams, array $defaultParams)
790
+    {
791
+        $refillValue = true;
792
+        $finalParams = array();
793
+        foreach($availableParams as $name) {
794
+            // loop all params and fill all with the matched parameters
795
+            // until a user (not callback) supplied parameter is encountered.
796
+            // After that only check defaults. Parameters supplied from the user
797
+            // or via callback always have precedence
798
+
799
+            // keep track if a user supplied parameter has already been encountered
800
+            if($refillValue && (isset($originalUserParams[$name]) || array_key_exists($name, $originalUserParams))) {
801
+                $refillValue = false;
802
+            }
803
+
804
+            // these 'aliases' are just for readability of the lower block
805
+            $isOptional = isset($optionalParams[$name]);
806
+            $hasMatched = isset($matchedParams[$name]);
807
+            $hasDefault = isset($defaultParams[$name]);
808
+            $hasUserCallbackParam = (isset($params[$name]) || array_key_exists($name, $params));
809
+
810
+            if($hasUserCallbackParam) {
811
+                // anything a user or callback supplied has precedence
812
+                // and since the user params are handled afterwards, skip them here
813
+            } elseif($refillValue && $hasMatched) {
814
+                // Use the matched input
815
+                $finalParams[$name] = $this->createValue($matchedParams[$name], true);
816
+            } elseif($hasDefault) {
817
+                // now we just need to check if there are defaults for this available param and fill them in if applicable
818
+                $default = $defaultParams[$name];
819
+                if(!$isOptional || strlen($default->getValue()) > 0) {
820
+                    $finalParams[$name] = clone $default;
821
+                } elseif($isOptional) {
822
+                    // there is no default or incoming match for this optional param, so remove it
823
+                    $finalParams[$name] = null;
824
+                }
825
+            }
826
+        }
827
+
828
+        return $finalParams;
829
+    }
830 830
 	
831
-	/**
832
-	 * Adds the user supplied parameters to the 'final' parameters for the route.
833
-	 * 
834
-	 * @param      array $options The options
835
-	 * @param      array $params The user parameters
836
-	 * @param      array $finalParams The 'final' parameters
837
-	 * @param      array $availableParams A list of parameter names available for the route
838
-	 * @param      array $optionalParams the optional parameters for the route
839
-	 * @param      array $defaultParams the default parameters for the route
840
-	 * 
841
-	 * @return     array The 'final' parameters
842
-	 * 
843
-	 * @author     Dominik del Bondio <[email protected]>
844
-	 * @since      1.0.0
845
-	 */
846
-	protected function fillUserParameters(array $options, array $params, array $finalParams, array $availableParams, array $optionalParams, array $defaultParams)
847
-	{
848
-		$availableParamsAsKeys = array_flip($availableParams);
849
-
850
-		foreach($params as $name => $param) {
851
-			if(!(isset($finalParams[$name]) || array_key_exists($name, $finalParams))) {
852
-				if($param === null && isset($optionalParams[$name])) {
853
-					// null was set for an optional parameter
854
-					$finalParams[$name] = $param;
855
-				} else {
856
-					if(isset($defaultParams[$name])) {
857
-						if($param === null || ($param instanceof RoutingValue && $param->getValue() === null)) {
858
-							// the user set the parameter to null, to signal that the default value should be used
859
-							$param = clone $defaultParams[$name];
860
-						}
861
-						$finalParams[$name] = $param;
862
-					} elseif(isset($availableParamsAsKeys[$name])) {
863
-						// when the parameter was available in one of the routes
864
-						$finalParams[$name] = $param;
865
-					}
866
-				}
867
-			}
868
-		}
869
-
870
-		return $finalParams;
871
-	}
872
-
873
-	/**
874
-	 * Adds the user supplied parameters to the 'final' parameters for the route.
875
-	 * 
876
-	 * @param      array $options The options
877
-	 * @param      array $finalParams The 'final' parameters
878
-	 * @param      array $availableParams A list of parameter names available for the route
879
-	 * @param      array $optionalParams the optional parameters for the route
880
-	 * @param      array $defaultParams the default parameters for the route
881
-	 * 
882
-	 * @return     array The 'final' parameters
883
-	 * 
884
-	 * @author     Dominik del Bondio <[email protected]>
885
-	 * @since      1.0.0
886
-	 */
887
-	protected function removeMatchingDefaults(array $options, array $finalParams, array $availableParams, array $optionalParams, array $defaultParams)
888
-	{
889
-		// if omit_defaults is set, we should not put optional values into the result string in case they are equal to their default value - even if they were given as a param
890
-		if(!empty($options['omit_defaults'])) {
891
-			// remove the optional parameters from the pattern beginning from right to the left, in case they are equal to their default
892
-			foreach(array_reverse($availableParams) as $name) {
893
-				if(isset($optionalParams[$name])) {
894
-					// the isset() could be replaced by
895
-					// "!array_key_exists($name, $finalParams) || $finalParams[$name] === null"
896
-					// to clarify that null is explicitly allowed here
897
-					if(!isset($finalParams[$name]) ||
898
-							(
899
-								isset($defaultParams[$name]) && 
900
-								$finalParams[$name]->getValue() == $defaultParams[$name]->getValue() &&
901
-								(!$finalParams[$name]->hasPrefix() || $finalParams[$name]->getPrefix() == $defaultParams[$name]->getPrefix()) && 
902
-								(!$finalParams[$name]->hasPostfix() || $finalParams[$name]->getPostfix() == $defaultParams[$name]->getPostfix())
903
-							)
904
-					) {
905
-						$finalParams[$name] = null;
906
-					} else {
907
-						break;
908
-					}
909
-				} else {
910
-					break;
911
-				}
912
-			}
913
-		}
831
+    /**
832
+     * Adds the user supplied parameters to the 'final' parameters for the route.
833
+     * 
834
+     * @param      array $options The options
835
+     * @param      array $params The user parameters
836
+     * @param      array $finalParams The 'final' parameters
837
+     * @param      array $availableParams A list of parameter names available for the route
838
+     * @param      array $optionalParams the optional parameters for the route
839
+     * @param      array $defaultParams the default parameters for the route
840
+     * 
841
+     * @return     array The 'final' parameters
842
+     * 
843
+     * @author     Dominik del Bondio <[email protected]>
844
+     * @since      1.0.0
845
+     */
846
+    protected function fillUserParameters(array $options, array $params, array $finalParams, array $availableParams, array $optionalParams, array $defaultParams)
847
+    {
848
+        $availableParamsAsKeys = array_flip($availableParams);
849
+
850
+        foreach($params as $name => $param) {
851
+            if(!(isset($finalParams[$name]) || array_key_exists($name, $finalParams))) {
852
+                if($param === null && isset($optionalParams[$name])) {
853
+                    // null was set for an optional parameter
854
+                    $finalParams[$name] = $param;
855
+                } else {
856
+                    if(isset($defaultParams[$name])) {
857
+                        if($param === null || ($param instanceof RoutingValue && $param->getValue() === null)) {
858
+                            // the user set the parameter to null, to signal that the default value should be used
859
+                            $param = clone $defaultParams[$name];
860
+                        }
861
+                        $finalParams[$name] = $param;
862
+                    } elseif(isset($availableParamsAsKeys[$name])) {
863
+                        // when the parameter was available in one of the routes
864
+                        $finalParams[$name] = $param;
865
+                    }
866
+                }
867
+            }
868
+        }
869
+
870
+        return $finalParams;
871
+    }
872
+
873
+    /**
874
+     * Adds the user supplied parameters to the 'final' parameters for the route.
875
+     * 
876
+     * @param      array $options The options
877
+     * @param      array $finalParams The 'final' parameters
878
+     * @param      array $availableParams A list of parameter names available for the route
879
+     * @param      array $optionalParams the optional parameters for the route
880
+     * @param      array $defaultParams the default parameters for the route
881
+     * 
882
+     * @return     array The 'final' parameters
883
+     * 
884
+     * @author     Dominik del Bondio <[email protected]>
885
+     * @since      1.0.0
886
+     */
887
+    protected function removeMatchingDefaults(array $options, array $finalParams, array $availableParams, array $optionalParams, array $defaultParams)
888
+    {
889
+        // if omit_defaults is set, we should not put optional values into the result string in case they are equal to their default value - even if they were given as a param
890
+        if(!empty($options['omit_defaults'])) {
891
+            // remove the optional parameters from the pattern beginning from right to the left, in case they are equal to their default
892
+            foreach(array_reverse($availableParams) as $name) {
893
+                if(isset($optionalParams[$name])) {
894
+                    // the isset() could be replaced by
895
+                    // "!array_key_exists($name, $finalParams) || $finalParams[$name] === null"
896
+                    // to clarify that null is explicitly allowed here
897
+                    if(!isset($finalParams[$name]) ||
898
+                            (
899
+                                isset($defaultParams[$name]) && 
900
+                                $finalParams[$name]->getValue() == $defaultParams[$name]->getValue() &&
901
+                                (!$finalParams[$name]->hasPrefix() || $finalParams[$name]->getPrefix() == $defaultParams[$name]->getPrefix()) && 
902
+                                (!$finalParams[$name]->hasPostfix() || $finalParams[$name]->getPostfix() == $defaultParams[$name]->getPostfix())
903
+                            )
904
+                    ) {
905
+                        $finalParams[$name] = null;
906
+                    } else {
907
+                        break;
908
+                    }
909
+                } else {
910
+                    break;
911
+                }
912
+            }
913
+        }
914 914
 		
915
-		return $finalParams;
916
-	}
915
+        return $finalParams;
916
+    }
917 917
 	
918
-	/**
919
-	 * Updates the pre and postfixes in the final params from the default
920
-	 * pre and postfix if available and if it hasn't been set yet by the user.
921
-	 * 
922
-	 * @param      array $finalParams The 'final' parameters
923
-	 * @param      array $defaultParams the default parameters for the route
924
-	 * 
925
-	 * @return     array The 'final' parameters
926
-	 * 
927
-	 * @author     Dominik del Bondio <[email protected]>
928
-	 * @since      1.0.0
929
-	 */
930
-	protected function updatePrefixAndPostfix(array $finalParams, array $defaultParams)
931
-	{
932
-		foreach($finalParams as $name => $param) {
933
-			if($param === null) {
934
-				continue;
935
-			}
918
+    /**
919
+     * Updates the pre and postfixes in the final params from the default
920
+     * pre and postfix if available and if it hasn't been set yet by the user.
921
+     * 
922
+     * @param      array $finalParams The 'final' parameters
923
+     * @param      array $defaultParams the default parameters for the route
924
+     * 
925
+     * @return     array The 'final' parameters
926
+     * 
927
+     * @author     Dominik del Bondio <[email protected]>
928
+     * @since      1.0.0
929
+     */
930
+    protected function updatePrefixAndPostfix(array $finalParams, array $defaultParams)
931
+    {
932
+        foreach($finalParams as $name => $param) {
933
+            if($param === null) {
934
+                continue;
935
+            }
936 936
 			
937
-			if(isset($defaultParams[$name])) {
938
-				// update the pre- and postfix from the default if they are not set in the routing value
939
-				$default = $defaultParams[$name];
940
-				if(!$param->hasPrefix() && $default->hasPrefix()) {
941
-					$param->setPrefix($default->getPrefix());
942
-				}
943
-				if(!$param->hasPostfix() && $default->hasPostfix()) {
944
-					$param->setPostfix($default->getPostfix());
945
-				}
946
-			}
947
-		}
948
-		return $finalParams;
949
-	}
937
+            if(isset($defaultParams[$name])) {
938
+                // update the pre- and postfix from the default if they are not set in the routing value
939
+                $default = $defaultParams[$name];
940
+                if(!$param->hasPrefix() && $default->hasPrefix()) {
941
+                    $param->setPrefix($default->getPrefix());
942
+                }
943
+                if(!$param->hasPostfix() && $default->hasPostfix()) {
944
+                    $param->setPostfix($default->getPostfix());
945
+                }
946
+            }
947
+        }
948
+        return $finalParams;
949
+    }
950 950
 	
951
-	/**
952
-	 * Encodes all 'final' parameters.
953
-	 * 
954
-	 * @param      array $options The 'final' parameters
955
-	 * @param      array $params The default parameters for the route
956
-	 * 
957
-	 * @return     array The 'final' parameters
958
-	 * 
959
-	 * @author     Dominik del Bondio <[email protected]>
960
-	 * @since      1.0.0
961
-	 */
962
-	protected function encodeParameters(array $options, array $params)
963
-	{
964
-		foreach($params as &$param) {
965
-			$param = $this->encodeParameter($param);
966
-		}
967
-		return $params;
968
-	}
951
+    /**
952
+     * Encodes all 'final' parameters.
953
+     * 
954
+     * @param      array $options The 'final' parameters
955
+     * @param      array $params The default parameters for the route
956
+     * 
957
+     * @return     array The 'final' parameters
958
+     * 
959
+     * @author     Dominik del Bondio <[email protected]>
960
+     * @since      1.0.0
961
+     */
962
+    protected function encodeParameters(array $options, array $params)
963
+    {
964
+        foreach($params as &$param) {
965
+            $param = $this->encodeParameter($param);
966
+        }
967
+        return $params;
968
+    }
969 969
 	
970
-	/**
971
-	 * Encodes a single parameter.
972
-	 * 
973
-	 * @param      mixed $parameter A RoutingValue object or a string
974
-	 * 
975
-	 * @return     string The encoded parameter
976
-	 * 
977
-	 * @author     Dominik del Bondio <[email protected]>
978
-	 * @since      1.0.0
979
-	 */
980
-	protected function encodeParameter($parameter)
981
-	{
982
-		if($parameter instanceof RoutingValue) {
983
-			return sprintf('%s%s%s', 
984
-				$parameter->getPrefixNeedsEncoding()  ? $this->escapeOutputParameter($parameter->getPrefix())  : $parameter->getPrefix(),
985
-				$parameter->getValueNeedsEncoding()   ? $this->escapeOutputParameter($parameter->getValue())   : $parameter->getValue(),
986
-				$parameter->getPostfixNeedsEncoding() ? $this->escapeOutputParameter($parameter->getPostfix()) : $parameter->getPostfix()
987
-			);
988
-		} else {
989
-			return $this->escapeOutputParameter($parameter);
990
-		}
991
-	}
970
+    /**
971
+     * Encodes a single parameter.
972
+     * 
973
+     * @param      mixed $parameter A RoutingValue object or a string
974
+     * 
975
+     * @return     string The encoded parameter
976
+     * 
977
+     * @author     Dominik del Bondio <[email protected]>
978
+     * @since      1.0.0
979
+     */
980
+    protected function encodeParameter($parameter)
981
+    {
982
+        if($parameter instanceof RoutingValue) {
983
+            return sprintf('%s%s%s', 
984
+                $parameter->getPrefixNeedsEncoding()  ? $this->escapeOutputParameter($parameter->getPrefix())  : $parameter->getPrefix(),
985
+                $parameter->getValueNeedsEncoding()   ? $this->escapeOutputParameter($parameter->getValue())   : $parameter->getValue(),
986
+                $parameter->getPostfixNeedsEncoding() ? $this->escapeOutputParameter($parameter->getPostfix()) : $parameter->getPostfix()
987
+            );
988
+        } else {
989
+            return $this->escapeOutputParameter($parameter);
990
+        }
991
+    }
992 992
 	
993
-	/**
994
-	 * Converts all members of an array to AgaviIRoutingValues.
995
-	 * 
996
-	 * @param      array $parameters The parameters
997
-	 * 
998
-	 * @return     array An array containing all parameters as RoutingValues
999
-	 * 
1000
-	 * @author     Dominik del Bondio <[email protected]>
1001
-	 * @since      1.0.0
1002
-	 */
1003
-	protected function convertParametersToRoutingValues(array $parameters)
1004
-	{
1005
-		if(count($parameters)) {
1006
-			// make sure everything in $parameters is a routing value
1007
-			foreach($parameters as &$param) {
1008
-				if(!$param instanceof RoutingValue) {
1009
-					if($param !== null) {
1010
-						$param = $this->createValue($param);
1011
-					}
1012
-				} else {
1013
-					// make sure the routing value the user passed to gen() is not modified
1014
-					$param = clone $param;
1015
-				}
1016
-			}
1017
-			return $parameters;
1018
-		} else {
1019
-			return array();
1020
-		}
1021
-	}
1022
-
1023
-	/**
1024
-	 * Generate a formatted Agavi URL.
1025
-	 *
1026
-	 * @param      string $route   A route name.
1027
-	 * @param      array  $params  An associative array of parameters.
1028
-	 * @param      mixed  $options An array of options, or the name of an options preset.
1029
-	 *
1030
-	 * @return     array An array containing the generated route path, the
1031
-	 *                   (possibly modified) parameters, and the (possibly
1032
-	 *                   modified) options.
1033
-	 *
1034
-	 * @author     Dominik del Bondio <[email protected]>
1035
-	 * @author     David Zülke <[email protected]>
1036
-	 * @since      0.11.0
1037
-	 */
1038
-	public function gen($route, array $params = array(), $options = array())
1039
-	{
1040
-		if(array_key_exists('prefix', $options)) {
1041
-			$prefix = (string) $options['prefix'];
1042
-		} else {
1043
-			$prefix = $this->getPrefix();
1044
-		}
993
+    /**
994
+     * Converts all members of an array to AgaviIRoutingValues.
995
+     * 
996
+     * @param      array $parameters The parameters
997
+     * 
998
+     * @return     array An array containing all parameters as RoutingValues
999
+     * 
1000
+     * @author     Dominik del Bondio <[email protected]>
1001
+     * @since      1.0.0
1002
+     */
1003
+    protected function convertParametersToRoutingValues(array $parameters)
1004
+    {
1005
+        if(count($parameters)) {
1006
+            // make sure everything in $parameters is a routing value
1007
+            foreach($parameters as &$param) {
1008
+                if(!$param instanceof RoutingValue) {
1009
+                    if($param !== null) {
1010
+                        $param = $this->createValue($param);
1011
+                    }
1012
+                } else {
1013
+                    // make sure the routing value the user passed to gen() is not modified
1014
+                    $param = clone $param;
1015
+                }
1016
+            }
1017
+            return $parameters;
1018
+        } else {
1019
+            return array();
1020
+        }
1021
+    }
1022
+
1023
+    /**
1024
+     * Generate a formatted Agavi URL.
1025
+     *
1026
+     * @param      string $route   A route name.
1027
+     * @param      array  $params  An associative array of parameters.
1028
+     * @param      mixed  $options An array of options, or the name of an options preset.
1029
+     *
1030
+     * @return     array An array containing the generated route path, the
1031
+     *                   (possibly modified) parameters, and the (possibly
1032
+     *                   modified) options.
1033
+     *
1034
+     * @author     Dominik del Bondio <[email protected]>
1035
+     * @author     David Zülke <[email protected]>
1036
+     * @since      0.11.0
1037
+     */
1038
+    public function gen($route, array $params = array(), $options = array())
1039
+    {
1040
+        if(array_key_exists('prefix', $options)) {
1041
+            $prefix = (string) $options['prefix'];
1042
+        } else {
1043
+            $prefix = $this->getPrefix();
1044
+        }
1045 1045
 		
1046
-		$isNullRoute = false;
1047
-		$routes = $this->getAffectedRoutes($route, $isNullRoute);
1046
+        $isNullRoute = false;
1047
+        $routes = $this->getAffectedRoutes($route, $isNullRoute);
1048 1048
 		
1049
-		if(count($routes) == 0) {
1050
-			return array($route, array(), $options, $params, $isNullRoute);
1051
-		}
1049
+        if(count($routes) == 0) {
1050
+            return array($route, array(), $options, $params, $isNullRoute);
1051
+        }
1052 1052
 		
1053
-		if($isNullRoute) {
1054
-			// for gen(null) and friends all matched parameters are inserted before the 
1055
-			// supplied params are backuped
1056
-			$params = $this->fillGenNullParameters($routes, $params);
1057
-		}
1053
+        if($isNullRoute) {
1054
+            // for gen(null) and friends all matched parameters are inserted before the 
1055
+            // supplied params are backuped
1056
+            $params = $this->fillGenNullParameters($routes, $params);
1057
+        }
1058 1058
 		
1059
-		$params = $this->convertParametersToRoutingValues($params);
1060
-		// we need to store the original params since we will be trying to fill the
1061
-		// parameters up to the first user supplied parameter
1062
-		$originalParams = $params;
1059
+        $params = $this->convertParametersToRoutingValues($params);
1060
+        // we need to store the original params since we will be trying to fill the
1061
+        // parameters up to the first user supplied parameter
1062
+        $originalParams = $params;
1063 1063
 		
1064
-		$assembledInformation = $this->assembleRoutes($options, $routes, $params);
1064
+        $assembledInformation = $this->assembleRoutes($options, $routes, $params);
1065 1065
 		
1066
-		$options = $assembledInformation['options'];
1066
+        $options = $assembledInformation['options'];
1067 1067
 		
1068
-		$params = $assembledInformation['user_parameters'];
1068
+        $params = $assembledInformation['user_parameters'];
1069 1069
 		
1070
-		$params = $this->refillAllMatchedParameters($options, $params, $assembledInformation['matched_parameters']);
1071
-		$finalParams = $this->refillMatchedAndDefaultParameters($options, $originalParams, $params, $assembledInformation['available_parameters'], $assembledInformation['matched_parameters'], $assembledInformation['optional_parameters'], $assembledInformation['default_parameters']);
1072
-		$finalParams = $this->fillUserParameters($options, $params, $finalParams, $assembledInformation['available_parameters'], $assembledInformation['optional_parameters'], $assembledInformation['default_parameters']);
1073
-		$finalParams = $this->removeMatchingDefaults($options, $finalParams, $assembledInformation['available_parameters'], $assembledInformation['optional_parameters'], $assembledInformation['default_parameters']);
1074
-		$finalParams = $this->updatePrefixAndPostfix($finalParams, $assembledInformation['default_parameters']);
1075
-
1076
-		// remember the params that are not in any pattern (could be extra query params, for example, set by a callback), use the parameter state after the callbacks have been run and defaults have been inserted. We also need to take originalParams into account for the case that a value was unset in a callback (which requires us to restore the old value). The array_merge is safe for this task since everything changed, etc appears in $params and overwrites the values from $originalParams
1077
-		$extras = array_diff_key(array_merge($originalParams, $params), $finalParams);
1078
-		// but since the values are expected as plain values and not routing values, convert the routing values back to 
1079
-		// 'plain' values
1080
-		foreach($extras as &$extra) {
1081
-			$extra = ($extra instanceof RoutingValue) ? $extra->getValue() : $extra;
1082
-		}
1083
-
1084
-		$params = $finalParams;
1085
-
1086
-		$params = $this->encodeParameters($options, $params);
1087
-
1088
-		$from = array();
1089
-		$to = array();
1070
+        $params = $this->refillAllMatchedParameters($options, $params, $assembledInformation['matched_parameters']);
1071
+        $finalParams = $this->refillMatchedAndDefaultParameters($options, $originalParams, $params, $assembledInformation['available_parameters'], $assembledInformation['matched_parameters'], $assembledInformation['optional_parameters'], $assembledInformation['default_parameters']);
1072
+        $finalParams = $this->fillUserParameters($options, $params, $finalParams, $assembledInformation['available_parameters'], $assembledInformation['optional_parameters'], $assembledInformation['default_parameters']);
1073
+        $finalParams = $this->removeMatchingDefaults($options, $finalParams, $assembledInformation['available_parameters'], $assembledInformation['optional_parameters'], $assembledInformation['default_parameters']);
1074
+        $finalParams = $this->updatePrefixAndPostfix($finalParams, $assembledInformation['default_parameters']);
1075
+
1076
+        // remember the params that are not in any pattern (could be extra query params, for example, set by a callback), use the parameter state after the callbacks have been run and defaults have been inserted. We also need to take originalParams into account for the case that a value was unset in a callback (which requires us to restore the old value). The array_merge is safe for this task since everything changed, etc appears in $params and overwrites the values from $originalParams
1077
+        $extras = array_diff_key(array_merge($originalParams, $params), $finalParams);
1078
+        // but since the values are expected as plain values and not routing values, convert the routing values back to 
1079
+        // 'plain' values
1080
+        foreach($extras as &$extra) {
1081
+            $extra = ($extra instanceof RoutingValue) ? $extra->getValue() : $extra;
1082
+        }
1083
+
1084
+        $params = $finalParams;
1085
+
1086
+        $params = $this->encodeParameters($options, $params);
1087
+
1088
+        $from = array();
1089
+        $to = array();
1090 1090
 		
1091 1091
 
1092
-		// remove not specified available parameters
1093
-		foreach(array_unique($assembledInformation['available_parameters']) as $name) {
1094
-			if(!isset($params[$name])) {
1095
-				$from[] = '(:' . $name . ':)';
1096
-				$to[] = '';
1097
-			}
1098
-		}
1099
-
1100
-		foreach($params as $n => $p) {
1101
-			$from[] = '(:' . $n . ':)';
1102
-			$to[] = $p;
1103
-		}
1104
-
1105
-		$uri = str_replace($from, $to, $assembledInformation['uri']);
1106
-		return array($prefix . $uri, $params, $options, $extras, $isNullRoute);
1107
-	}
1092
+        // remove not specified available parameters
1093
+        foreach(array_unique($assembledInformation['available_parameters']) as $name) {
1094
+            if(!isset($params[$name])) {
1095
+                $from[] = '(:' . $name . ':)';
1096
+                $to[] = '';
1097
+            }
1098
+        }
1099
+
1100
+        foreach($params as $n => $p) {
1101
+            $from[] = '(:' . $n . ':)';
1102
+            $to[] = $p;
1103
+        }
1104
+
1105
+        $uri = str_replace($from, $to, $assembledInformation['uri']);
1106
+        return array($prefix . $uri, $params, $options, $extras, $isNullRoute);
1107
+    }
1108 1108
 	
1109 1109
 	
1110
-	/**
1111
-	 * Escapes an argument to be used in an generated route.
1112
-	 *
1113
-	 * @param      string $string The argument to be escaped.
1114
-	 *
1115
-	 * @return     string The escaped argument.
1116
-	 *
1117
-	 * @author     Dominik del Bondio <[email protected]>
1118
-	 * @since      0.11.0
1119
-	 */
1120
-	public function escapeOutputParameter($string)
1121
-	{
1122
-		return (string)$string;
1123
-	}
1124
-
1125
-	/**
1126
-	 * Matches the input against the routing info and sets the info as request
1127
-	 * parameter.
1128
-	 *
1129
-	 * @return     mixed An ExecutionContainer as a result of this execution,
1130
-	 *                   or an AgaviResponse if a callback returned one.
1131
-	 *
1132
-	 * @author     Dominik del Bondio <[email protected]>
1133
-	 * @since      0.11.0
1134
-	 */
1135
-	public function execute()
1136
-	{
1137
-		$rq = $this->context->getRequest();
1138
-
1139
-		$rd = $rq->getRequestData();
1140
-
1141
-		$tm = $this->context->getTranslationManager();
1110
+    /**
1111
+     * Escapes an argument to be used in an generated route.
1112
+     *
1113
+     * @param      string $string The argument to be escaped.
1114
+     *
1115
+     * @return     string The escaped argument.
1116
+     *
1117
+     * @author     Dominik del Bondio <[email protected]>
1118
+     * @since      0.11.0
1119
+     */
1120
+    public function escapeOutputParameter($string)
1121
+    {
1122
+        return (string)$string;
1123
+    }
1124
+
1125
+    /**
1126
+     * Matches the input against the routing info and sets the info as request
1127
+     * parameter.
1128
+     *
1129
+     * @return     mixed An ExecutionContainer as a result of this execution,
1130
+     *                   or an AgaviResponse if a callback returned one.
1131
+     *
1132
+     * @author     Dominik del Bondio <[email protected]>
1133
+     * @since      0.11.0
1134
+     */
1135
+    public function execute()
1136
+    {
1137
+        $rq = $this->context->getRequest();
1138
+
1139
+        $rd = $rq->getRequestData();
1140
+
1141
+        $tm = $this->context->getTranslationManager();
1142 1142
 		
1143
-		$container = $this->context->getDispatcher()->createExecutionContainer();
1143
+        $container = $this->context->getDispatcher()->createExecutionContainer();
1144 1144
 
1145
-		if(!$this->isEnabled()) {
1146
-			// routing disabled, just bail out here
1147
-			return $container;
1148
-		}
1145
+        if(!$this->isEnabled()) {
1146
+            // routing disabled, just bail out here
1147
+            return $container;
1148
+        }
1149 1149
 
1150
-		$matchedRoutes = array();
1150
+        $matchedRoutes = array();
1151 1151
 
1152
-		$input = $this->input;
1152
+        $input = $this->input;
1153 1153
 
1154
-		$vars = array();
1155
-		$ot = null;
1156
-		$locale = null;
1157
-		$method = null;
1154
+        $vars = array();
1155
+        $ot = null;
1156
+        $locale = null;
1157
+        $method = null;
1158 1158
 		
1159
-		$umap = $rq->getParameter('use_module_controller_parameters');
1160
-		$ma = $rq->getParameter('module_accessor');
1161
-		$aa = $rq->getParameter('controller_accessor');
1159
+        $umap = $rq->getParameter('use_module_controller_parameters');
1160
+        $ma = $rq->getParameter('module_accessor');
1161
+        $aa = $rq->getParameter('controller_accessor');
1162 1162
 		
1163
-		$requestMethod = $rq->getMethod();
1164
-
1165
-		$routes = array();
1166
-		// get all top level routes
1167
-		foreach($this->routes as $name => $route) {
1168
-			if(!$route['opt']['parent']) {
1169
-				$routes[] = $name;
1170
-			}
1171
-		}
1172
-
1173
-		// prepare the working stack with the root routes
1174
-		$routeStack = array($routes);
1175
-
1176
-		do {
1177
-			$routes = array_pop($routeStack);
1178
-			foreach($routes as $key) {
1179
-				$route =& $this->routes[$key];
1180
-				$opts =& $route['opt'];
1181
-				if(count($opts['constraint']) == 0 || in_array($requestMethod, $opts['constraint'])) {
1182
-					if(count($opts['callbacks']) > 0 && !isset($route['callback_instances'])) {
1183
-						foreach($opts['callbacks'] as $key => $callback) {
1184
-							/** @var RoutingCallback $instance */
1185
-							$instance = new $callback['class']();
1186
-							$instance->initialize($this->context, $route);
1187
-							$instance->setParameters($callback['parameters']);
1188
-							$route['callback_instances'][$key] = $instance;
1189
-						}
1190
-					}
1191
-
1192
-					$match = array();
1193
-					if($this->parseInput($route, $input, $match)) {
1194
-						$varsBackup = $vars;
1163
+        $requestMethod = $rq->getMethod();
1164
+
1165
+        $routes = array();
1166
+        // get all top level routes
1167
+        foreach($this->routes as $name => $route) {
1168
+            if(!$route['opt']['parent']) {
1169
+                $routes[] = $name;
1170
+            }
1171
+        }
1172
+
1173
+        // prepare the working stack with the root routes
1174
+        $routeStack = array($routes);
1175
+
1176
+        do {
1177
+            $routes = array_pop($routeStack);
1178
+            foreach($routes as $key) {
1179
+                $route =& $this->routes[$key];
1180
+                $opts =& $route['opt'];
1181
+                if(count($opts['constraint']) == 0 || in_array($requestMethod, $opts['constraint'])) {
1182
+                    if(count($opts['callbacks']) > 0 && !isset($route['callback_instances'])) {
1183
+                        foreach($opts['callbacks'] as $key => $callback) {
1184
+                            /** @var RoutingCallback $instance */
1185
+                            $instance = new $callback['class']();
1186
+                            $instance->initialize($this->context, $route);
1187
+                            $instance->setParameters($callback['parameters']);
1188
+                            $route['callback_instances'][$key] = $instance;
1189
+                        }
1190
+                    }
1191
+
1192
+                    $match = array();
1193
+                    if($this->parseInput($route, $input, $match)) {
1194
+                        $varsBackup = $vars;
1195 1195
 						
1196
-						// backup the container, must be done here already
1197
-						if(count($opts['callbacks']) > 0) {
1198
-							$containerBackup = $container;
1199
-							$container = clone $container;
1200
-						}
1196
+                        // backup the container, must be done here already
1197
+                        if(count($opts['callbacks']) > 0) {
1198
+                            $containerBackup = $container;
1199
+                            $container = clone $container;
1200
+                        }
1201 1201
 						
1202
-						$ign = array();
1203
-						if(count($opts['ignores']) > 0) {
1204
-							$ign = array_flip($opts['ignores']);
1205
-						}
1206
-
1207
-						/**
1208
-						 * @var $value RoutingValue;
1209
-						 */
1210
-						foreach($opts['defaults'] as $key => $value) {
1211
-							if(!isset($ign[$key]) && $value->getValue() !== null) {
1212
-								$vars[$key] = $value->getValue();
1213
-							}
1214
-						}
1215
-
1216
-						foreach($route['par'] as $param) {
1217
-							if(isset($match[$param]) && $match[$param][1] != -1) {
1218
-								$vars[$param] = $match[$param][0];
1219
-							}
1220
-						}
1221
-
1222
-						foreach($match as $name => $m) {
1223
-							if(is_string($name) && $m[1] != -1) {
1224
-								$route['matches'][$name] = $m[0];
1225
-							}
1226
-						}
1227
-
1228
-						// /* ! Only use the parameters from this route for expandVariables !
1229
-						// matches are arrays with value and offset due to PREG_OFFSET_CAPTURE, and we want index 0, the value, which reset() will give us. Long story short, this removes the offset from the individual match
1230
-						$matchvals = array_map('reset', $match);
1231
-						// */
1232
-						/* ! Use the parameters from ALL routes for expandVariables !
1202
+                        $ign = array();
1203
+                        if(count($opts['ignores']) > 0) {
1204
+                            $ign = array_flip($opts['ignores']);
1205
+                        }
1206
+
1207
+                        /**
1208
+                         * @var $value RoutingValue;
1209
+                         */
1210
+                        foreach($opts['defaults'] as $key => $value) {
1211
+                            if(!isset($ign[$key]) && $value->getValue() !== null) {
1212
+                                $vars[$key] = $value->getValue();
1213
+                            }
1214
+                        }
1215
+
1216
+                        foreach($route['par'] as $param) {
1217
+                            if(isset($match[$param]) && $match[$param][1] != -1) {
1218
+                                $vars[$param] = $match[$param][0];
1219
+                            }
1220
+                        }
1221
+
1222
+                        foreach($match as $name => $m) {
1223
+                            if(is_string($name) && $m[1] != -1) {
1224
+                                $route['matches'][$name] = $m[0];
1225
+                            }
1226
+                        }
1227
+
1228
+                        // /* ! Only use the parameters from this route for expandVariables !
1229
+                        // matches are arrays with value and offset due to PREG_OFFSET_CAPTURE, and we want index 0, the value, which reset() will give us. Long story short, this removes the offset from the individual match
1230
+                        $matchvals = array_map('reset', $match);
1231
+                        // */
1232
+                        /* ! Use the parameters from ALL routes for expandVariables !
1233 1233
 						$matchvals = $vars;
1234 1234
 						// ignores need of the current route need to be added
1235 1235
 						$foreach($opts['ignores'] as $ignore) {
@@ -1239,532 +1239,532 @@  discard block
 block discarded – undo
1239 1239
 						}
1240 1240
 						// */
1241 1241
 
1242
-						if($opts['module']) {
1243
-							$module = Toolkit::expandVariables($opts['module'], $matchvals);
1244
-							$container->setModuleName($module);
1245
-							if($umap) {
1246
-								$vars[$ma] = $module;
1247
-							}
1248
-						}
1249
-
1250
-						if($opts['controller']) {
1251
-							$controller = Toolkit::expandVariables($opts['controller'], $matchvals);
1252
-							$container->setControllerName($controller);
1253
-							if($umap) {
1254
-								$vars[$aa] = $controller;
1255
-							}
1256
-						}
1257
-
1258
-						if($opts['output_type']) {
1259
-							// set the output type if necessary
1260
-							// here no explicit check is done, since in 0.11 this is compared against null
1261
-							// which can never be the result of expandVariables
1262
-							$ot = Toolkit::expandVariables($opts['output_type'], $matchvals);
1242
+                        if($opts['module']) {
1243
+                            $module = Toolkit::expandVariables($opts['module'], $matchvals);
1244
+                            $container->setModuleName($module);
1245
+                            if($umap) {
1246
+                                $vars[$ma] = $module;
1247
+                            }
1248
+                        }
1249
+
1250
+                        if($opts['controller']) {
1251
+                            $controller = Toolkit::expandVariables($opts['controller'], $matchvals);
1252
+                            $container->setControllerName($controller);
1253
+                            if($umap) {
1254
+                                $vars[$aa] = $controller;
1255
+                            }
1256
+                        }
1257
+
1258
+                        if($opts['output_type']) {
1259
+                            // set the output type if necessary
1260
+                            // here no explicit check is done, since in 0.11 this is compared against null
1261
+                            // which can never be the result of expandVariables
1262
+                            $ot = Toolkit::expandVariables($opts['output_type'], $matchvals);
1263 1263
 							
1264
-							// we need to wrap in try/catch here (but not further down after the callbacks have run) for BC
1265
-							// and because it makes sense - maybe a callback checks or changes the output type name
1266
-							try {
1267
-								$container->setOutputType($this->context->getDispatcher()->getOutputType($ot));
1268
-							} catch(AgaviException $e) {
1269
-							}
1270
-						}
1271
-
1272
-						if($opts['locale']) {
1273
-							$localeBackup = $tm->getCurrentLocaleIdentifier();
1264
+                            // we need to wrap in try/catch here (but not further down after the callbacks have run) for BC
1265
+                            // and because it makes sense - maybe a callback checks or changes the output type name
1266
+                            try {
1267
+                                $container->setOutputType($this->context->getDispatcher()->getOutputType($ot));
1268
+                            } catch(AgaviException $e) {
1269
+                            }
1270
+                        }
1271
+
1272
+                        if($opts['locale']) {
1273
+                            $localeBackup = $tm->getCurrentLocaleIdentifier();
1274 1274
 							
1275
-							// set the locale if necessary
1276
-							if($locale = Toolkit::expandVariables($opts['locale'], $matchvals)) {
1277
-								// the if is here for bc reasons, since if $opts['locale'] only contains variable parts
1278
-								// expandVariables could possibly return an empty string in which case the pre 1.0 routing
1279
-								// didn't set the variable
1275
+                            // set the locale if necessary
1276
+                            if($locale = Toolkit::expandVariables($opts['locale'], $matchvals)) {
1277
+                                // the if is here for bc reasons, since if $opts['locale'] only contains variable parts
1278
+                                // expandVariables could possibly return an empty string in which case the pre 1.0 routing
1279
+                                // didn't set the variable
1280 1280
 								
1281
-								// we need to wrap in try/catch here (but not further down after the callbacks have run) for BC
1282
-								// and because it makes sense - maybe a callback checks or changes the locale name
1283
-								try {
1284
-									$tm->setLocale($locale);
1285
-								} catch(AgaviException $e) {
1286
-								}
1287
-							}
1288
-						} else {
1289
-							// unset it explicitly, so that further down, the isset() check doesn't set back a value from a previous iteration!
1290
-							$localeBackup = null;
1291
-						}
1292
-
1293
-						if($opts['method']) {
1294
-							// set the request method if necessary
1295
-							if($method = Toolkit::expandVariables($opts['method'], $matchvals)) {
1296
-								// the if is here for bc reasons, since if $opts['method'] only contains variable parts
1297
-								// expandVariables could possibly return an empty string in which case the pre 1.0 routing
1298
-								// didn't set the variable
1299
-								$rq->setMethod($method);
1300
-								// and on the already created container, too!
1301
-								$container->setRequestMethod($method);
1302
-							}
1303
-						}
1304
-
1305
-						if(count($opts['callbacks']) > 0) {
1306
-							if(count($opts['ignores']) > 0) {
1307
-								// add ignored variables to the callback vars
1308
-								foreach($vars as $name => &$var) {
1309
-									$vars[$name] =& $var;
1310
-								}
1311
-								foreach($opts['ignores'] as $ignore) {
1312
-									if(isset($match[$ignore]) && $match[$ignore][1] != -1) {
1313
-										$vars[$ignore] = $match[$ignore][0];
1314
-									}
1315
-								}
1316
-							}
1317
-							$callbackSuccess = true;
1318
-							/** @var RoutingCallback $callbackInstance */
1319
-							foreach($route['callback_instances'] as $callbackInstance) {
1320
-								// call onMatched on all callbacks until one of them returns false
1321
-								// then restore state and call onNotMatched on that same callback
1322
-								// after that, call onNotMatched for all remaining callbacks of that route
1323
-								if($callbackSuccess) {
1324
-									// backup stuff which could be changed in the callback so we are 
1325
-									// able to determine which values were changed in the callback
1326
-									$oldModule = $container->getModuleName();
1327
-									$oldController = $container->getControllerName();
1328
-									$oldOutputTypeName = $container->getOutputType() ? $container->getOutputType()->getName() : null;
1329
-									if(null === $tm) {
1330
-										$oldLocale = null;
1331
-									} else {
1332
-										$oldLocale = $tm->getCurrentLocaleIdentifier();
1333
-									}
1334
-									$oldRequestMethod = $rq->getMethod();
1335
-									$oldContainerMethod = $container->getRequestMethod();
1336
-
1337
-									$onMatched = $callbackInstance->onMatched($vars, $container);
1338
-									if($onMatched instanceof Response) {
1339
-										return $onMatched;
1340
-									}
1341
-									if(!$onMatched) {
1342
-										$callbackSuccess = false;
1281
+                                // we need to wrap in try/catch here (but not further down after the callbacks have run) for BC
1282
+                                // and because it makes sense - maybe a callback checks or changes the locale name
1283
+                                try {
1284
+                                    $tm->setLocale($locale);
1285
+                                } catch(AgaviException $e) {
1286
+                                }
1287
+                            }
1288
+                        } else {
1289
+                            // unset it explicitly, so that further down, the isset() check doesn't set back a value from a previous iteration!
1290
+                            $localeBackup = null;
1291
+                        }
1292
+
1293
+                        if($opts['method']) {
1294
+                            // set the request method if necessary
1295
+                            if($method = Toolkit::expandVariables($opts['method'], $matchvals)) {
1296
+                                // the if is here for bc reasons, since if $opts['method'] only contains variable parts
1297
+                                // expandVariables could possibly return an empty string in which case the pre 1.0 routing
1298
+                                // didn't set the variable
1299
+                                $rq->setMethod($method);
1300
+                                // and on the already created container, too!
1301
+                                $container->setRequestMethod($method);
1302
+                            }
1303
+                        }
1304
+
1305
+                        if(count($opts['callbacks']) > 0) {
1306
+                            if(count($opts['ignores']) > 0) {
1307
+                                // add ignored variables to the callback vars
1308
+                                foreach($vars as $name => &$var) {
1309
+                                    $vars[$name] =& $var;
1310
+                                }
1311
+                                foreach($opts['ignores'] as $ignore) {
1312
+                                    if(isset($match[$ignore]) && $match[$ignore][1] != -1) {
1313
+                                        $vars[$ignore] = $match[$ignore][0];
1314
+                                    }
1315
+                                }
1316
+                            }
1317
+                            $callbackSuccess = true;
1318
+                            /** @var RoutingCallback $callbackInstance */
1319
+                            foreach($route['callback_instances'] as $callbackInstance) {
1320
+                                // call onMatched on all callbacks until one of them returns false
1321
+                                // then restore state and call onNotMatched on that same callback
1322
+                                // after that, call onNotMatched for all remaining callbacks of that route
1323
+                                if($callbackSuccess) {
1324
+                                    // backup stuff which could be changed in the callback so we are 
1325
+                                    // able to determine which values were changed in the callback
1326
+                                    $oldModule = $container->getModuleName();
1327
+                                    $oldController = $container->getControllerName();
1328
+                                    $oldOutputTypeName = $container->getOutputType() ? $container->getOutputType()->getName() : null;
1329
+                                    if(null === $tm) {
1330
+                                        $oldLocale = null;
1331
+                                    } else {
1332
+                                        $oldLocale = $tm->getCurrentLocaleIdentifier();
1333
+                                    }
1334
+                                    $oldRequestMethod = $rq->getMethod();
1335
+                                    $oldContainerMethod = $container->getRequestMethod();
1336
+
1337
+                                    $onMatched = $callbackInstance->onMatched($vars, $container);
1338
+                                    if($onMatched instanceof Response) {
1339
+                                        return $onMatched;
1340
+                                    }
1341
+                                    if(!$onMatched) {
1342
+                                        $callbackSuccess = false;
1343 1343
 										
1344
-										// reset the matches array. it must be populated by the time onMatched() is called so matches can be modified in a callback
1345
-										$route['matches'] = array();
1346
-										// restore the variables from the variables which were set before this route matched
1347
-										$vars = $varsBackup;
1348
-										// reset all relevant container data we already set in the container for this (now non matching) route
1349
-										$container = $containerBackup;
1350
-										// restore locale
1351
-										if(isset($localeBackup)) {
1352
-											$tm->setLocale($localeBackup);
1353
-										}
1354
-										// restore request method
1355
-										$rq->setMethod($container->getRequestMethod());
1356
-									}
1357
-								}
1344
+                                        // reset the matches array. it must be populated by the time onMatched() is called so matches can be modified in a callback
1345
+                                        $route['matches'] = array();
1346
+                                        // restore the variables from the variables which were set before this route matched
1347
+                                        $vars = $varsBackup;
1348
+                                        // reset all relevant container data we already set in the container for this (now non matching) route
1349
+                                        $container = $containerBackup;
1350
+                                        // restore locale
1351
+                                        if(isset($localeBackup)) {
1352
+                                            $tm->setLocale($localeBackup);
1353
+                                        }
1354
+                                        // restore request method
1355
+                                        $rq->setMethod($container->getRequestMethod());
1356
+                                    }
1357
+                                }
1358 1358
 								
1359
-								// always call onNotMatched if $callbackSuccess == false, even if we just called onMatched() on the same instance. this is expected behavior
1360
-								if(!$callbackSuccess) {
1361
-									$onNotMatched = $callbackInstance->onNotMatched($container);
1362
-									if($onNotMatched instanceof Response) {
1363
-										return $onNotMatched;
1364
-									}
1359
+                                // always call onNotMatched if $callbackSuccess == false, even if we just called onMatched() on the same instance. this is expected behavior
1360
+                                if(!$callbackSuccess) {
1361
+                                    $onNotMatched = $callbackInstance->onNotMatched($container);
1362
+                                    if($onNotMatched instanceof Response) {
1363
+                                        return $onNotMatched;
1364
+                                    }
1365 1365
 									
1366
-									// continue with the next callback
1367
-									continue;
1368
-								}
1366
+                                    // continue with the next callback
1367
+                                    continue;
1368
+                                }
1369 1369
 								
1370
-								// /* ! Only use the parameters from this route for expandVariables !
1371
-								$expandVars = $vars;
1372
-								$routeParamsAsKey = array_flip($route['par']);
1373
-								// only use parameters which are defined in this route or are new
1374
-								foreach($expandVars as $name => $value) {
1375
-									if(!isset($routeParamsAsKey[$name]) && array_key_exists($name, $varsBackup)) {
1376
-										unset($expandVars[$name]);
1377
-									}
1378
-								} 
1379
-								// */
1380
-								/* ! Use the parameters from ALL routes for expandVariables !
1370
+                                // /* ! Only use the parameters from this route for expandVariables !
1371
+                                $expandVars = $vars;
1372
+                                $routeParamsAsKey = array_flip($route['par']);
1373
+                                // only use parameters which are defined in this route or are new
1374
+                                foreach($expandVars as $name => $value) {
1375
+                                    if(!isset($routeParamsAsKey[$name]) && array_key_exists($name, $varsBackup)) {
1376
+                                        unset($expandVars[$name]);
1377
+                                    }
1378
+                                } 
1379
+                                // */
1380
+                                /* ! Use the parameters from ALL routes for expandVariables !
1381 1381
 								$expandVars = $vars;
1382 1382
 								// */
1383 1383
 								
1384 1384
 								
1385
-								// if the callback didn't change the value, execute expandVariables again since 
1386
-								// the callback could have changed one of the values which expandVariables uses
1387
-								// to evaluate the contents of the attribute in question (e.g. module="${zomg}")
1388
-								if($opts['module'] && $oldModule == $container->getModuleName() && (!$umap || !array_key_exists($ma, $vars) || $oldModule == $vars[$ma])) {
1389
-									$module = Toolkit::expandVariables($opts['module'], $expandVars);
1390
-									$container->setModuleName($module);
1391
-									if($umap) {
1392
-										$vars[$ma] = $module;
1393
-									}
1394
-								}
1395
-								if($opts['controller'] && $oldController == $container->getControllerName() && (!$umap || !array_key_exists($aa, $vars) || $oldController == $vars[$aa])) {
1396
-									$controller = Toolkit::expandVariables($opts['controller'], $expandVars);
1397
-									$container->setControllerName($controller);
1398
-									if($umap) {
1399
-										$vars[$aa] = $controller;
1400
-									}
1401
-								}
1402
-								if($opts['output_type'] && $oldOutputTypeName == ($container->getOutputType() ? $container->getOutputType()->getName() : null)) {
1403
-									$ot = Toolkit::expandVariables($opts['output_type'], $expandVars);
1404
-									$container->setOutputType($this->context->getDispatcher()->getOutputType($ot));
1405
-								}
1406
-								if($opts['locale'] && $oldLocale == $tm->getCurrentLocaleIdentifier()) {
1407
-									if($locale = Toolkit::expandVariables($opts['locale'], $expandVars)) {
1408
-										// see above for the reason of the if
1409
-										$tm->setLocale($locale);
1410
-									}
1411
-								}
1412
-								if($opts['method']) {
1413
-									if($oldRequestMethod == $rq->getMethod() && $oldContainerMethod == $container->getRequestMethod()) {
1414
-										if($method = Toolkit::expandVariables($opts['method'], $expandVars)) {
1415
-											// see above for the reason of the if
1416
-											$rq->setMethod($method);
1417
-											$container->setRequestMethod($method);
1418
-										}
1419
-									} elseif($oldContainerMethod != $container->getRequestMethod()) {
1420
-										// copy the request method to the request (a method set on the container 
1421
-										// in a callback always has precedence over request methods set on the request)
1422
-										$rq->setMethod($container->getRequestMethod());
1423
-									} elseif($oldRequestMethod != $rq->getMethod()) {
1424
-										// copy the request method to the container
1425
-										$container->setRequestMethod($rq->getMethod());
1426
-									}
1427
-								}
1385
+                                // if the callback didn't change the value, execute expandVariables again since 
1386
+                                // the callback could have changed one of the values which expandVariables uses
1387
+                                // to evaluate the contents of the attribute in question (e.g. module="${zomg}")
1388
+                                if($opts['module'] && $oldModule == $container->getModuleName() && (!$umap || !array_key_exists($ma, $vars) || $oldModule == $vars[$ma])) {
1389
+                                    $module = Toolkit::expandVariables($opts['module'], $expandVars);
1390
+                                    $container->setModuleName($module);
1391
+                                    if($umap) {
1392
+                                        $vars[$ma] = $module;
1393
+                                    }
1394
+                                }
1395
+                                if($opts['controller'] && $oldController == $container->getControllerName() && (!$umap || !array_key_exists($aa, $vars) || $oldController == $vars[$aa])) {
1396
+                                    $controller = Toolkit::expandVariables($opts['controller'], $expandVars);
1397
+                                    $container->setControllerName($controller);
1398
+                                    if($umap) {
1399
+                                        $vars[$aa] = $controller;
1400
+                                    }
1401
+                                }
1402
+                                if($opts['output_type'] && $oldOutputTypeName == ($container->getOutputType() ? $container->getOutputType()->getName() : null)) {
1403
+                                    $ot = Toolkit::expandVariables($opts['output_type'], $expandVars);
1404
+                                    $container->setOutputType($this->context->getDispatcher()->getOutputType($ot));
1405
+                                }
1406
+                                if($opts['locale'] && $oldLocale == $tm->getCurrentLocaleIdentifier()) {
1407
+                                    if($locale = Toolkit::expandVariables($opts['locale'], $expandVars)) {
1408
+                                        // see above for the reason of the if
1409
+                                        $tm->setLocale($locale);
1410
+                                    }
1411
+                                }
1412
+                                if($opts['method']) {
1413
+                                    if($oldRequestMethod == $rq->getMethod() && $oldContainerMethod == $container->getRequestMethod()) {
1414
+                                        if($method = Toolkit::expandVariables($opts['method'], $expandVars)) {
1415
+                                            // see above for the reason of the if
1416
+                                            $rq->setMethod($method);
1417
+                                            $container->setRequestMethod($method);
1418
+                                        }
1419
+                                    } elseif($oldContainerMethod != $container->getRequestMethod()) {
1420
+                                        // copy the request method to the request (a method set on the container 
1421
+                                        // in a callback always has precedence over request methods set on the request)
1422
+                                        $rq->setMethod($container->getRequestMethod());
1423
+                                    } elseif($oldRequestMethod != $rq->getMethod()) {
1424
+                                        // copy the request method to the container
1425
+                                        $container->setRequestMethod($rq->getMethod());
1426
+                                    }
1427
+                                }
1428 1428
 								
1429
-								// one last thing we need to do: see if one of the callbacks modified the 'controller' or 'module' vars inside $vars if $umap is on
1430
-								// we then need to write those back to the container, unless they changed THERE, too, in which case the container values take precedence
1431
-								if($umap && $oldModule == $container->getModuleName() && array_key_exists($ma, $vars) && $vars[$ma] != $oldModule) {
1432
-									$container->setModuleName($vars[$ma]);
1433
-								}
1434
-								if($umap && $oldController == $container->getControllerName() && array_key_exists($aa, $vars) && $vars[$aa] != $oldController) {
1435
-									$container->setControllerName($vars[$aa]);
1436
-								}
1437
-							}
1438
-							if(!$callbackSuccess) {
1439
-								// jump straight to the next route
1440
-								continue;
1441
-							} else {
1442
-								// We added the ignores to the route variables so the callback receives them, so restore them from vars backup.
1443
-								// Restoring them from the backup is necessary since otherwise a value which has been set before this route
1444
-								// and which was ignored in this route would take the ignored value instead of keeping the old one.
1445
-								// And variables which have not been set in an earlier routes need to be removed again
1446
-								foreach($opts['ignores'] as $ignore) {
1447
-									if(array_key_exists($ignore, $varsBackup)) {
1448
-										$vars[$ignore] = $varsBackup[$ignore];
1449
-									} else {
1450
-										unset($vars[$ignore]);
1451
-									}
1452
-								}
1453
-							}
1454
-						}
1455
-
1456
-						$matchedRoutes[] = $opts['name'];
1457
-
1458
-						if($opts['cut'] || (count($opts['childs']) && $opts['cut'] === null)) {
1459
-							if($route['opt']['source'] !== null) {
1460
-								$s =& $this->sources[$route['opt']['source']];
1461
-							} else {
1462
-								$s =& $input;
1463
-							}
1464
-
1465
-							$ni = '';
1466
-							// if the route didn't match from the start of the input preserve the 'prefix'
1467
-							if($match[0][1] > 0) {
1468
-								$ni = substr($s, 0, $match[0][1]);
1469
-							}
1470
-							$ni .= substr($s, $match[0][1] + strlen($match[0][0]));
1471
-							$s = $ni;
1472
-						}
1473
-
1474
-						if(count($opts['childs'])) {
1475
-							// our childs need to be processed next and stop processing 'afterwards'
1476
-							$routeStack[] = $opts['childs'];
1477
-							break;
1478
-						}
1479
-
1480
-						if($opts['stop']) {
1481
-							break;
1482
-						}
1483
-
1484
-					} else {
1485
-						if(count($opts['callbacks']) > 0) {
1486
-							/** @var RoutingCallback $callbackInstance */
1487
-							foreach($route['callback_instances'] as $callbackInstance) {
1488
-								$onNotMatched = $callbackInstance->onNotMatched($container);
1489
-								if($onNotMatched instanceof Response) {
1490
-									return $onNotMatched;
1491
-								}
1492
-							}
1493
-						}
1494
-					}
1495
-				}
1496
-			}
1497
-		} while(count($routeStack) > 0);
1498
-
1499
-		// put the vars into the request
1500
-		$rd->setParameters($vars);
1501
-
1502
-		if($container->getModuleName() === null || $container->getControllerName() === null) {
1503
-			// no route which supplied the required parameters matched, use 404 controller
1504
-			$container->setModuleName(Config::get('controllers.error_404_module'));
1505
-			$container->setControllerName(Config::get('controllers.error_404_controller'));
1429
+                                // one last thing we need to do: see if one of the callbacks modified the 'controller' or 'module' vars inside $vars if $umap is on
1430
+                                // we then need to write those back to the container, unless they changed THERE, too, in which case the container values take precedence
1431
+                                if($umap && $oldModule == $container->getModuleName() && array_key_exists($ma, $vars) && $vars[$ma] != $oldModule) {
1432
+                                    $container->setModuleName($vars[$ma]);
1433
+                                }
1434
+                                if($umap && $oldController == $container->getControllerName() && array_key_exists($aa, $vars) && $vars[$aa] != $oldController) {
1435
+                                    $container->setControllerName($vars[$aa]);
1436
+                                }
1437
+                            }
1438
+                            if(!$callbackSuccess) {
1439
+                                // jump straight to the next route
1440
+                                continue;
1441
+                            } else {
1442
+                                // We added the ignores to the route variables so the callback receives them, so restore them from vars backup.
1443
+                                // Restoring them from the backup is necessary since otherwise a value which has been set before this route
1444
+                                // and which was ignored in this route would take the ignored value instead of keeping the old one.
1445
+                                // And variables which have not been set in an earlier routes need to be removed again
1446
+                                foreach($opts['ignores'] as $ignore) {
1447
+                                    if(array_key_exists($ignore, $varsBackup)) {
1448
+                                        $vars[$ignore] = $varsBackup[$ignore];
1449
+                                    } else {
1450
+                                        unset($vars[$ignore]);
1451
+                                    }
1452
+                                }
1453
+                            }
1454
+                        }
1455
+
1456
+                        $matchedRoutes[] = $opts['name'];
1457
+
1458
+                        if($opts['cut'] || (count($opts['childs']) && $opts['cut'] === null)) {
1459
+                            if($route['opt']['source'] !== null) {
1460
+                                $s =& $this->sources[$route['opt']['source']];
1461
+                            } else {
1462
+                                $s =& $input;
1463
+                            }
1464
+
1465
+                            $ni = '';
1466
+                            // if the route didn't match from the start of the input preserve the 'prefix'
1467
+                            if($match[0][1] > 0) {
1468
+                                $ni = substr($s, 0, $match[0][1]);
1469
+                            }
1470
+                            $ni .= substr($s, $match[0][1] + strlen($match[0][0]));
1471
+                            $s = $ni;
1472
+                        }
1473
+
1474
+                        if(count($opts['childs'])) {
1475
+                            // our childs need to be processed next and stop processing 'afterwards'
1476
+                            $routeStack[] = $opts['childs'];
1477
+                            break;
1478
+                        }
1479
+
1480
+                        if($opts['stop']) {
1481
+                            break;
1482
+                        }
1483
+
1484
+                    } else {
1485
+                        if(count($opts['callbacks']) > 0) {
1486
+                            /** @var RoutingCallback $callbackInstance */
1487
+                            foreach($route['callback_instances'] as $callbackInstance) {
1488
+                                $onNotMatched = $callbackInstance->onNotMatched($container);
1489
+                                if($onNotMatched instanceof Response) {
1490
+                                    return $onNotMatched;
1491
+                                }
1492
+                            }
1493
+                        }
1494
+                    }
1495
+                }
1496
+            }
1497
+        } while(count($routeStack) > 0);
1498
+
1499
+        // put the vars into the request
1500
+        $rd->setParameters($vars);
1501
+
1502
+        if($container->getModuleName() === null || $container->getControllerName() === null) {
1503
+            // no route which supplied the required parameters matched, use 404 controller
1504
+            $container->setModuleName(Config::get('controllers.error_404_module'));
1505
+            $container->setControllerName(Config::get('controllers.error_404_controller'));
1506 1506
 			
1507
-			if($umap) {
1508
-				$rd->setParameters(array(
1509
-					$ma => $container->getModuleName(),
1510
-					$aa => $container->getControllerName(),
1511
-				));
1512
-			}
1513
-		}
1514
-
1515
-		// set the list of matched route names as a request attribute
1516
-		$rq->setAttribute('matched_routes', $matchedRoutes, 'org.agavi.routing');
1517
-
1518
-		// return a list of matched route names
1519
-		return $container;
1520
-	}
1521
-
1522
-	/**
1523
-	 * Performs as match of the route against the input
1524
-	 *
1525
-	 * @param      array  $route   The route info array.
1526
-	 * @param      string $input   The input.
1527
-	 * @param      array  $matches The array where the matches will be stored to.
1528
-	 *
1529
-	 * @return     bool Whether the regexp matched.
1530
-	 *
1531
-	 * @author     Dominik del Bondio <[email protected]>
1532
-	 * @since      0.11.0
1533
-	 */
1534
-	protected function parseInput(array $route, $input, &$matches)
1535
-	{
1536
-		if($route['opt']['source'] !== null) {
1537
-			$parts = ArrayPathDefinition::getPartsFromPath($route['opt']['source']);
1538
-			$partArray = $parts['parts'];
1539
-			$count = count($partArray);
1540
-			if($count > 0 && isset($this->sources[$partArray[0]])) {
1541
-				$input = $this->sources[$partArray[0]];
1542
-				if($count > 1) {
1543
-					array_shift($partArray);
1544
-					if(is_array($input)) {
1545
-						$input = ArrayPathDefinition::getValue($partArray, $input);
1546
-					} elseif($input instanceof RoutingSourceInterface) {
1547
-						$input = $input->getSource($partArray);
1548
-					}
1549
-				}
1550
-			}
1551
-		}
1552
-		return preg_match($route['rxp'], $input, $matches, PREG_OFFSET_CAPTURE);
1553
-	}
1554
-
1555
-	/**
1556
-	 * Parses a route pattern string.
1557
-	 *
1558
-	 * @param      string $str The route pattern.
1559
-	 *
1560
-	 * @return     array The info for this route pattern.
1561
-	 *
1562
-	 * @author     Dominik del Bondio <[email protected]>
1563
-	 * @since      0.11.0
1564
-	 */
1565
-	protected function parseRouteString($str)
1566
-	{
1567
-		$vars = array();
1568
-		$rxStr = '';
1569
-		$reverseStr = '';
1570
-
1571
-		$anchor = 0;
1572
-		$anchor |= (substr($str, 0, 1) == '^') ? self::ANCHOR_START : 0;
1573
-		$anchor |= (substr($str, -1) == '$') ? self::ANCHOR_END : 0;
1574
-
1575
-		$str = substr($str, (int)$anchor & self::ANCHOR_START, $anchor & self::ANCHOR_END ? -1 : strlen($str));
1576
-
1577
-		$rxChars = implode('', array('.', '\\', '+', '*', '?', '[', '^', ']', '$', '(', ')', '{', '}', '=', '!', '<', '>', '|', ':'));
1578
-
1579
-		$len = strlen($str);
1580
-		$state = 'start';
1581
-		$tmpStr = '';
1582
-		$inEscape = false;
1583
-
1584
-		$rxName = null;
1585
-		$rxInner = null;
1586
-		$rxPrefix = null;
1587
-		$rxPostfix = null;
1588
-		$parenthesisCount = 0;
1589
-		$bracketCount = 0;
1590
-		$hasBrackets = false;
1591
-
1592
-		for($i = 0; $i < $len; ++$i) {
1593
-			$atEnd = $i + 1 == $len;
1594
-
1595
-			$c = $str[$i];
1596
-
1597
-			if(!$atEnd && !$inEscape && $c == '\\') {
1598
-				$cNext = $str[$i + 1];
1599
-
1600
-				if(
1601
-					($cNext == '\\') ||
1602
-					($state == 'start' && $cNext == '(') ||
1603
-					($state == 'rxStart' && in_array($cNext, array('(',')','{','}')))
1604
-				) {
1605
-					$inEscape = true;
1606
-					continue;
1607
-				}
1608
-				if($state == 'afterRx' && $cNext == '?') {
1609
-					$inEscape = false;
1610
-					$state = 'start';
1611
-					continue;
1612
-				}
1613
-			} elseif($inEscape) {
1614
-				$tmpStr .= $c;
1615
-				$inEscape = false;
1616
-				continue;
1617
-			}
1618
-
1619
-			if($state == 'start') {
1620
-				// start of regular expression block
1621
-				if($c == '(') {
1622
-					$rxStr .= preg_quote($tmpStr, '#');
1623
-					$reverseStr .= $tmpStr;
1624
-
1625
-					$tmpStr = '';
1626
-					$state = 'rxStart';
1627
-					$rxName = $rxInner = $rxPrefix = $rxPostfix = null;
1628
-					$parenthesisCount = 1;
1629
-					$bracketCount = 0;
1630
-					$hasBrackets = false;
1631
-				} else {
1632
-					$tmpStr .= $c;
1633
-				}
1634
-
1635
-				if($atEnd) {
1636
-					$rxStr .= preg_quote($tmpStr, '#');
1637
-					$reverseStr .= $tmpStr;
1638
-				}
1639
-			} elseif($state == 'rxStart') {
1640
-				if($c == '{') {
1641
-					++$bracketCount;
1642
-					if($bracketCount == 1) {
1643
-						$hasBrackets = true;
1644
-						$rxPrefix = $tmpStr;
1645
-						$tmpStr = '';
1646
-					} else {
1647
-						$tmpStr .= $c;
1648
-					}
1649
-				} elseif($c == '}') {
1650
-					--$bracketCount;
1651
-					if($bracketCount == 0) {
1652
-						list($rxName, $rxInner) = $this->parseParameterDefinition($tmpStr);
1653
-						$tmpStr = '';
1654
-					} else {
1655
-						$tmpStr .= $c;
1656
-					}
1657
-				} elseif($c == '(') {
1658
-					++$parenthesisCount;
1659
-					$tmpStr .= $c;
1660
-				} elseif($c == ')') {
1661
-					--$parenthesisCount;
1662
-					if($parenthesisCount > 0) {
1663
-						$tmpStr .= $c;
1664
-					} else {
1665
-						if($parenthesisCount < 0) {
1666
-							throw new AgaviException('The pattern ' . $str . ' contains an unbalanced set of parentheses!');
1667
-						}
1668
-
1669
-						if(!$hasBrackets) {
1670
-							list($rxName, $rxInner) = $this->parseParameterDefinition($tmpStr);
1671
-						} else {
1672
-							if($bracketCount != 0) {
1673
-								throw new AgaviException('The pattern ' . $str . ' contains an unbalanced set of brackets!');
1674
-							}
1675
-							$rxPostfix = $tmpStr;
1676
-						}
1677
-
1678
-						if(!$rxName) {
1679
-							$myRx = $rxPrefix . $rxInner . $rxPostfix;
1680
-							// if the entire regular expression doesn't contain any regular expression character we can safely append it to the reverseStr
1681
-							//if(strlen($myRx) == strcspn($myRx, $rxChars)) {
1682
-							if(strpbrk($myRx, $rxChars) === false) {
1683
-								$reverseStr .= $myRx;
1684
-							}
1685
-							$rxStr .= str_replace('#', '\#', sprintf('(%s)', $myRx));
1686
-						} else {
1687
-							$rxStr .= str_replace('#', '\#', sprintf('(%s(?P<%s>%s)%s)', $rxPrefix, $rxName, $rxInner, $rxPostfix));
1688
-							$reverseStr .= sprintf('(:%s:)', $rxName);
1689
-
1690
-							if(!isset($vars[$rxName])) {
1691
-								if(strpbrk($rxPrefix, $rxChars) !== false) {
1692
-									$rxPrefix = null;
1693
-								}
1694
-								if(strpbrk($rxInner, $rxChars) !== false) {
1695
-									$rxInner = null;
1696
-								}
1697
-								if(strpbrk($rxPostfix, $rxChars) !== false) {
1698
-									$rxPostfix = null;
1699
-								}
1700
-
1701
-								$vars[$rxName] = array('pre' => $rxPrefix, 'val' => $rxInner, 'post' => $rxPostfix, 'is_optional' => false);
1702
-							}
1703
-						}
1704
-
1705
-						$tmpStr = '';
1706
-						$state = 'afterRx';
1707
-					}
1708
-				} else {
1709
-					$tmpStr .= $c;
1710
-				}
1711
-
1712
-				if($atEnd && $parenthesisCount != 0) {
1713
-					throw new AgaviException('The pattern ' . $str . ' contains an unbalanced set of parentheses!');
1714
-				}
1715
-			} elseif($state == 'afterRx') {
1716
-				if($c == '?') {
1717
-					// only record the optional state when the pattern had a name
1718
-					if(isset($vars[$rxName])) {
1719
-						$vars[$rxName]['is_optional'] = true;
1720
-					}
1721
-					$rxStr .= $c;
1722
-				} else {
1723
-					// let the start state parse the char
1724
-					--$i;
1725
-				}
1726
-
1727
-				$state = 'start';
1728
-			}
1729
-		}
1730
-
1731
-		$rxStr = sprintf('#%s%s%s#', $anchor & self::ANCHOR_START ? '^' : '', $rxStr, $anchor & self::ANCHOR_END ? '$' : '');
1732
-		return array($rxStr, $reverseStr, $vars, $anchor);
1733
-	}
1734
-
1735
-	/**
1736
-	 * Parses an embedded regular expression in the route pattern string.
1737
-	 *
1738
-	 * @param      string $def The definition.
1739
-	 *
1740
-	 * @return     array The name and the regexp.
1741
-	 *
1742
-	 * @author     Dominik del Bondio <[email protected]>
1743
-	 * @since      0.11.0
1744
-	 */
1745
-	protected function parseParameterDefinition($def)
1746
-	{
1747
-		preg_match('#(?:([a-z0-9_-]+):)?(.*)#i', $def, $match);
1748
-		return array($match[1] !== '' ? $match[1] : null, $match[2]);
1749
-	}
1507
+            if($umap) {
1508
+                $rd->setParameters(array(
1509
+                    $ma => $container->getModuleName(),
1510
+                    $aa => $container->getControllerName(),
1511
+                ));
1512
+            }
1513
+        }
1514
+
1515
+        // set the list of matched route names as a request attribute
1516
+        $rq->setAttribute('matched_routes', $matchedRoutes, 'org.agavi.routing');
1517
+
1518
+        // return a list of matched route names
1519
+        return $container;
1520
+    }
1521
+
1522
+    /**
1523
+     * Performs as match of the route against the input
1524
+     *
1525
+     * @param      array  $route   The route info array.
1526
+     * @param      string $input   The input.
1527
+     * @param      array  $matches The array where the matches will be stored to.
1528
+     *
1529
+     * @return     bool Whether the regexp matched.
1530
+     *
1531
+     * @author     Dominik del Bondio <[email protected]>
1532
+     * @since      0.11.0
1533
+     */
1534
+    protected function parseInput(array $route, $input, &$matches)
1535
+    {
1536
+        if($route['opt']['source'] !== null) {
1537
+            $parts = ArrayPathDefinition::getPartsFromPath($route['opt']['source']);
1538
+            $partArray = $parts['parts'];
1539
+            $count = count($partArray);
1540
+            if($count > 0 && isset($this->sources[$partArray[0]])) {
1541
+                $input = $this->sources[$partArray[0]];
1542
+                if($count > 1) {
1543
+                    array_shift($partArray);
1544
+                    if(is_array($input)) {
1545
+                        $input = ArrayPathDefinition::getValue($partArray, $input);
1546
+                    } elseif($input instanceof RoutingSourceInterface) {
1547
+                        $input = $input->getSource($partArray);
1548
+                    }
1549
+                }
1550
+            }
1551
+        }
1552
+        return preg_match($route['rxp'], $input, $matches, PREG_OFFSET_CAPTURE);
1553
+    }
1554
+
1555
+    /**
1556
+     * Parses a route pattern string.
1557
+     *
1558
+     * @param      string $str The route pattern.
1559
+     *
1560
+     * @return     array The info for this route pattern.
1561
+     *
1562
+     * @author     Dominik del Bondio <[email protected]>
1563
+     * @since      0.11.0
1564
+     */
1565
+    protected function parseRouteString($str)
1566
+    {
1567
+        $vars = array();
1568
+        $rxStr = '';
1569
+        $reverseStr = '';
1570
+
1571
+        $anchor = 0;
1572
+        $anchor |= (substr($str, 0, 1) == '^') ? self::ANCHOR_START : 0;
1573
+        $anchor |= (substr($str, -1) == '$') ? self::ANCHOR_END : 0;
1574
+
1575
+        $str = substr($str, (int)$anchor & self::ANCHOR_START, $anchor & self::ANCHOR_END ? -1 : strlen($str));
1576
+
1577
+        $rxChars = implode('', array('.', '\\', '+', '*', '?', '[', '^', ']', '$', '(', ')', '{', '}', '=', '!', '<', '>', '|', ':'));
1578
+
1579
+        $len = strlen($str);
1580
+        $state = 'start';
1581
+        $tmpStr = '';
1582
+        $inEscape = false;
1583
+
1584
+        $rxName = null;
1585
+        $rxInner = null;
1586
+        $rxPrefix = null;
1587
+        $rxPostfix = null;
1588
+        $parenthesisCount = 0;
1589
+        $bracketCount = 0;
1590
+        $hasBrackets = false;
1591
+
1592
+        for($i = 0; $i < $len; ++$i) {
1593
+            $atEnd = $i + 1 == $len;
1594
+
1595
+            $c = $str[$i];
1596
+
1597
+            if(!$atEnd && !$inEscape && $c == '\\') {
1598
+                $cNext = $str[$i + 1];
1599
+
1600
+                if(
1601
+                    ($cNext == '\\') ||
1602
+                    ($state == 'start' && $cNext == '(') ||
1603
+                    ($state == 'rxStart' && in_array($cNext, array('(',')','{','}')))
1604
+                ) {
1605
+                    $inEscape = true;
1606
+                    continue;
1607
+                }
1608
+                if($state == 'afterRx' && $cNext == '?') {
1609
+                    $inEscape = false;
1610
+                    $state = 'start';
1611
+                    continue;
1612
+                }
1613
+            } elseif($inEscape) {
1614
+                $tmpStr .= $c;
1615
+                $inEscape = false;
1616
+                continue;
1617
+            }
1618
+
1619
+            if($state == 'start') {
1620
+                // start of regular expression block
1621
+                if($c == '(') {
1622
+                    $rxStr .= preg_quote($tmpStr, '#');
1623
+                    $reverseStr .= $tmpStr;
1624
+
1625
+                    $tmpStr = '';
1626
+                    $state = 'rxStart';
1627
+                    $rxName = $rxInner = $rxPrefix = $rxPostfix = null;
1628
+                    $parenthesisCount = 1;
1629
+                    $bracketCount = 0;
1630
+                    $hasBrackets = false;
1631
+                } else {
1632
+                    $tmpStr .= $c;
1633
+                }
1634
+
1635
+                if($atEnd) {
1636
+                    $rxStr .= preg_quote($tmpStr, '#');
1637
+                    $reverseStr .= $tmpStr;
1638
+                }
1639
+            } elseif($state == 'rxStart') {
1640
+                if($c == '{') {
1641
+                    ++$bracketCount;
1642
+                    if($bracketCount == 1) {
1643
+                        $hasBrackets = true;
1644
+                        $rxPrefix = $tmpStr;
1645
+                        $tmpStr = '';
1646
+                    } else {
1647
+                        $tmpStr .= $c;
1648
+                    }
1649
+                } elseif($c == '}') {
1650
+                    --$bracketCount;
1651
+                    if($bracketCount == 0) {
1652
+                        list($rxName, $rxInner) = $this->parseParameterDefinition($tmpStr);
1653
+                        $tmpStr = '';
1654
+                    } else {
1655
+                        $tmpStr .= $c;
1656
+                    }
1657
+                } elseif($c == '(') {
1658
+                    ++$parenthesisCount;
1659
+                    $tmpStr .= $c;
1660
+                } elseif($c == ')') {
1661
+                    --$parenthesisCount;
1662
+                    if($parenthesisCount > 0) {
1663
+                        $tmpStr .= $c;
1664
+                    } else {
1665
+                        if($parenthesisCount < 0) {
1666
+                            throw new AgaviException('The pattern ' . $str . ' contains an unbalanced set of parentheses!');
1667
+                        }
1668
+
1669
+                        if(!$hasBrackets) {
1670
+                            list($rxName, $rxInner) = $this->parseParameterDefinition($tmpStr);
1671
+                        } else {
1672
+                            if($bracketCount != 0) {
1673
+                                throw new AgaviException('The pattern ' . $str . ' contains an unbalanced set of brackets!');
1674
+                            }
1675
+                            $rxPostfix = $tmpStr;
1676
+                        }
1677
+
1678
+                        if(!$rxName) {
1679
+                            $myRx = $rxPrefix . $rxInner . $rxPostfix;
1680
+                            // if the entire regular expression doesn't contain any regular expression character we can safely append it to the reverseStr
1681
+                            //if(strlen($myRx) == strcspn($myRx, $rxChars)) {
1682
+                            if(strpbrk($myRx, $rxChars) === false) {
1683
+                                $reverseStr .= $myRx;
1684
+                            }
1685
+                            $rxStr .= str_replace('#', '\#', sprintf('(%s)', $myRx));
1686
+                        } else {
1687
+                            $rxStr .= str_replace('#', '\#', sprintf('(%s(?P<%s>%s)%s)', $rxPrefix, $rxName, $rxInner, $rxPostfix));
1688
+                            $reverseStr .= sprintf('(:%s:)', $rxName);
1689
+
1690
+                            if(!isset($vars[$rxName])) {
1691
+                                if(strpbrk($rxPrefix, $rxChars) !== false) {
1692
+                                    $rxPrefix = null;
1693
+                                }
1694
+                                if(strpbrk($rxInner, $rxChars) !== false) {
1695
+                                    $rxInner = null;
1696
+                                }
1697
+                                if(strpbrk($rxPostfix, $rxChars) !== false) {
1698
+                                    $rxPostfix = null;
1699
+                                }
1700
+
1701
+                                $vars[$rxName] = array('pre' => $rxPrefix, 'val' => $rxInner, 'post' => $rxPostfix, 'is_optional' => false);
1702
+                            }
1703
+                        }
1704
+
1705
+                        $tmpStr = '';
1706
+                        $state = 'afterRx';
1707
+                    }
1708
+                } else {
1709
+                    $tmpStr .= $c;
1710
+                }
1711
+
1712
+                if($atEnd && $parenthesisCount != 0) {
1713
+                    throw new AgaviException('The pattern ' . $str . ' contains an unbalanced set of parentheses!');
1714
+                }
1715
+            } elseif($state == 'afterRx') {
1716
+                if($c == '?') {
1717
+                    // only record the optional state when the pattern had a name
1718
+                    if(isset($vars[$rxName])) {
1719
+                        $vars[$rxName]['is_optional'] = true;
1720
+                    }
1721
+                    $rxStr .= $c;
1722
+                } else {
1723
+                    // let the start state parse the char
1724
+                    --$i;
1725
+                }
1726
+
1727
+                $state = 'start';
1728
+            }
1729
+        }
1730
+
1731
+        $rxStr = sprintf('#%s%s%s#', $anchor & self::ANCHOR_START ? '^' : '', $rxStr, $anchor & self::ANCHOR_END ? '$' : '');
1732
+        return array($rxStr, $reverseStr, $vars, $anchor);
1733
+    }
1734
+
1735
+    /**
1736
+     * Parses an embedded regular expression in the route pattern string.
1737
+     *
1738
+     * @param      string $def The definition.
1739
+     *
1740
+     * @return     array The name and the regexp.
1741
+     *
1742
+     * @author     Dominik del Bondio <[email protected]>
1743
+     * @since      0.11.0
1744
+     */
1745
+    protected function parseParameterDefinition($def)
1746
+    {
1747
+        preg_match('#(?:([a-z0-9_-]+):)?(.*)#i', $def, $match);
1748
+        return array($match[1] !== '' ? $match[1] : null, $match[2]);
1749
+    }
1750 1750
 	
1751
-	/**
1752
-	 * Creates and initializes a new RoutingValue.
1753
-	 * 
1754
-	 * @param      mixed $value              The value of the returned routing value.
1755
-	 * @param      bool  $valueNeedsEncoding Whether the $value needs to be encoded.
1756
-	 * 
1757
-	 * @return     RoutingValue
1758
-	 *
1759
-	 * @author     Dominik del Bondio <[email protected]>
1760
-	 * @since      1.0.0
1761
-	 */
1762
-	public function createValue($value, $valueNeedsEncoding = true)
1763
-	{
1764
-		$value = new RoutingValue($value, $valueNeedsEncoding);
1765
-		$value->initialize($this->context);
1766
-		return $value;
1767
-	}
1751
+    /**
1752
+     * Creates and initializes a new RoutingValue.
1753
+     * 
1754
+     * @param      mixed $value              The value of the returned routing value.
1755
+     * @param      bool  $valueNeedsEncoding Whether the $value needs to be encoded.
1756
+     * 
1757
+     * @return     RoutingValue
1758
+     *
1759
+     * @author     Dominik del Bondio <[email protected]>
1760
+     * @since      1.0.0
1761
+     */
1762
+    public function createValue($value, $valueNeedsEncoding = true)
1763
+    {
1764
+        $value = new RoutingValue($value, $valueNeedsEncoding);
1765
+        $value->initialize($this->context);
1766
+        return $value;
1767
+    }
1768 1768
 	
1769 1769
 }
1770 1770
 
Please login to merge, or discard this patch.
Spacing   +224 added lines, -224 removed lines patch added patch discarded remove patch
@@ -140,7 +140,7 @@  discard block
 block discarded – undo
140 140
 	{
141 141
 		$cfg = Config::get('core.config_dir') . '/routing.xml';
142 142
 		// allow missing routing.xml when routing is not enabled
143
-		if($this->isEnabled() || is_readable($cfg)) {
143
+		if ($this->isEnabled() || is_readable($cfg)) {
144 144
 			$this->importRoutes(unserialize(file_get_contents(ConfigCache::checkConfig($cfg, $this->context->getName()))));
145 145
 		}
146 146
 	}
@@ -159,7 +159,7 @@  discard block
 block discarded – undo
159 159
 
160 160
 		$this->sources['_SERVER'] = new RoutingArraySource($_SERVER);
161 161
 
162
-		if(Config::get('core.use_security')) {
162
+		if (Config::get('core.use_security')) {
163 163
 			$this->sources['user'] = new RoutingUserSource($this->context->getUser());
164 164
 		}
165 165
 	}
@@ -210,7 +210,7 @@  discard block
 block discarded – undo
210 210
 	 */
211 211
 	public final function getRoute($name)
212 212
 	{
213
-		if(!isset($this->routes[$name])) {
213
+		if (!isset($this->routes[$name])) {
214 214
 			return null;
215 215
 		}
216 216
 		return $this->routes[$name];
@@ -273,15 +273,15 @@  discard block
 block discarded – undo
273 273
 	public function addRoute($route, array $options = array(), $parent = null)
274 274
 	{
275 275
 		// catch the old options from the route which has to be overwritten
276
-		if(isset($options['name']) && isset($this->routes[$options['name']])) {
276
+		if (isset($options['name']) && isset($this->routes[$options['name']])) {
277 277
 			$defaultOpts = $this->routes[$options['name']]['opt'];
278 278
 
279 279
 			// when the parent is set and differs from the parent of the route to be overwritten bail out
280
-			if($parent !== null && $defaultOpts['parent'] != $parent) {
280
+			if ($parent !== null && $defaultOpts['parent'] != $parent) {
281 281
 				throw new AgaviException('You are trying to overwrite a route but are not staying in the same hierarchy');
282 282
 			}
283 283
 
284
-			if($parent === null) {
284
+			if ($parent === null) {
285 285
 				$parent = $defaultOpts['parent'];
286 286
 			} else {
287 287
 				$defaultOpts['parent'] = $parent;
@@ -290,15 +290,15 @@  discard block
 block discarded – undo
290 290
 			$defaultOpts = array('name' => Toolkit::uniqid(), 'stop' => true, 'output_type' => null, 'module' => null, 'controller' => null, 'parameters' => array(), 'ignores' => array(), 'defaults' => array(), 'childs' => array(), 'callbacks' => array(), 'imply' => false, 'cut' => null, 'source' => null, 'method' => null, 'constraint' => array(), 'locale' => null, 'pattern_parameters' => array(), 'optional_parameters' => array(), 'parent' => $parent, 'reverseStr' => '', 'nostops' => array(), 'anchor' => self::ANCHOR_NONE);
291 291
 		}
292 292
 		// retain backwards compatibility to 0.11
293
-		if(isset($options['callback'])) {
293
+		if (isset($options['callback'])) {
294 294
 			$options['callbacks'] = array(array('class' => $options['callback'], 'parameters' => array()));
295 295
 			unset($options['callback']);
296 296
 		}
297 297
 
298
-		if(isset($options['defaults'])) {
299
-			foreach($options['defaults'] as $name => &$value) {
298
+		if (isset($options['defaults'])) {
299
+			foreach ($options['defaults'] as $name => &$value) {
300 300
 				$val = $pre = $post = null;
301
-				if(preg_match('#(.*)\{(.*)\}(.*)#', $value, $match)) {
301
+				if (preg_match('#(.*)\{(.*)\}(.*)#', $value, $match)) {
302 302
 					$pre = $match[1];
303 303
 					$val = $match[2];
304 304
 					$post = $match[3];
@@ -317,14 +317,14 @@  discard block
 block discarded – undo
317 317
 		$params = array();
318 318
 
319 319
 		// transfer the parameters and fill available automatic defaults
320
-		foreach($routeParams as $name => $param) {
320
+		foreach ($routeParams as $name => $param) {
321 321
 			$params[] = $name;
322 322
 
323
-			if($param['is_optional']) {
323
+			if ($param['is_optional']) {
324 324
 				$options['optional_parameters'][$name] = true;
325 325
 			}
326 326
 
327
-			if(!isset($options['defaults'][$name]) && ($param['pre'] || $param['val'] || $param['post'])) {
327
+			if (!isset($options['defaults'][$name]) && ($param['pre'] || $param['val'] || $param['post'])) {
328 328
 				unset($param['is_optional']);
329 329
 				$options['defaults'][$name] = $this->createValue($param['val'])->setPrefix($param['pre'])->setPostfix($param['post']);
330 330
 			}
@@ -333,8 +333,8 @@  discard block
 block discarded – undo
333 333
 		$options['pattern_parameters'] = $params;
334 334
 
335 335
 		// remove all ignore from the parameters in the route
336
-		foreach($options['ignores'] as $ignore) {
337
-			if(($key = array_search($ignore, $params)) !== false) {
336
+		foreach ($options['ignores'] as $ignore) {
337
+			if (($key = array_search($ignore, $params)) !== false) {
338 338
 				unset($params[$key]);
339 339
 			}
340 340
 		}
@@ -343,38 +343,38 @@  discard block
 block discarded – undo
343 343
 
344 344
 		// parse all the setting values for dynamic variables
345 345
 		// check if 2 nodes with the same name in the same execution tree exist
346
-		foreach($this->routes as $name => $route) {
346
+		foreach ($this->routes as $name => $route) {
347 347
 			// if a route with this route as parent exist check if its really a child of our route
348
-			if($route['opt']['parent'] == $routeName && !in_array($name, $options['childs'])) {
348
+			if ($route['opt']['parent'] == $routeName && !in_array($name, $options['childs'])) {
349 349
 				throw new AgaviException('The route ' . $routeName . ' specifies a child route with the same name');
350 350
 			}
351 351
 		}
352 352
 
353 353
 		// direct childs/parents with the same name aren't caught by the above check
354
-		if($routeName == $parent) {
354
+		if ($routeName == $parent) {
355 355
 			throw new AgaviException('The route ' . $routeName . ' specifies a child route with the same name');
356 356
 		}
357 357
 
358 358
 		// if we are a child route, we need add this route as a child to the parent
359
-		if($parent !== null) {
360
-			foreach($this->routes[$parent]['opt']['childs'] as $name) {
361
-				if($name == $routeName) {
359
+		if ($parent !== null) {
360
+			foreach ($this->routes[$parent]['opt']['childs'] as $name) {
361
+				if ($name == $routeName) {
362 362
 					// we're overwriting a route, so unlike when first adding the route, there are more routes after this that might also be non-stopping, but we obviously don't want those, so we need to bail out at this point
363 363
 					break;
364 364
 				}
365 365
 				$route = $this->routes[$name];
366
-				if(!$route['opt']['stop']) {
366
+				if (!$route['opt']['stop']) {
367 367
 					$options['nostops'][] = $name;
368 368
 				}
369 369
 			}
370 370
 			$this->routes[$parent]['opt']['childs'][] = $routeName;
371 371
 		} else {
372
-			foreach($this->routes as $name => $route) {
373
-				if($name == $routeName) {
372
+			foreach ($this->routes as $name => $route) {
373
+				if ($name == $routeName) {
374 374
 					// we're overwriting a route, so unlike when first adding the route, there are more routes after this that might also be non-stopping, but we obviously don't want those, so we need to bail out at this point
375 375
 					break;
376 376
 				}
377
-				if(!$route['opt']['stop'] && !$route['opt']['parent']) {
377
+				if (!$route['opt']['stop'] && !$route['opt']['parent']) {
378 378
 					$options['nostops'][] = $name;
379 379
 				}
380 380
 			}
@@ -433,23 +433,23 @@  discard block
 block discarded – undo
433 433
 		$includedRoutes = array();
434 434
 		$excludedRoutes = array();
435 435
 		
436
-		if($route === null) {
436
+		if ($route === null) {
437 437
 			$includedRoutes = array_reverse($this->getContext()->getRequest()->getAttribute('matched_routes', 'org.agavi.routing', array()));
438 438
 			$isNullRoute = true;
439
-		} elseif(strlen($route) > 0) {
440
-			if($route[0] == '-' || $route[0] == '+') {
439
+		} elseif (strlen($route) > 0) {
440
+			if ($route[0] == '-' || $route[0] == '+') {
441 441
 				$includedRoutes = array_reverse($this->getContext()->getRequest()->getAttribute('matched_routes', 'org.agavi.routing', array()));
442 442
 				$isNullRoute = true;
443 443
 			}
444 444
 			
445 445
 			$routeParts = preg_split('#(-|\+)#', $route, -1, PREG_SPLIT_DELIM_CAPTURE);
446 446
 			$prevDelimiter = '+';
447
-			foreach($routeParts as $part) {
448
-				if($part == '+' || $part == '-') {
447
+			foreach ($routeParts as $part) {
448
+				if ($part == '+' || $part == '-') {
449 449
 					$prevDelimiter = $part;
450 450
 				}
451 451
 				
452
-				if($prevDelimiter == '+') {
452
+				if ($prevDelimiter == '+') {
453 453
 					$includedRoutes[] = $part;
454 454
 				} else { // $prevDelimiter == '-'
455 455
 					$excludedRoutes[] = $part;
@@ -459,48 +459,48 @@  discard block
 block discarded – undo
459 459
 		
460 460
 		$excludedRoutes = array_flip($excludedRoutes);
461 461
 
462
-		if($includedRoutes) {
462
+		if ($includedRoutes) {
463 463
 			$route = $includedRoutes[0];
464 464
 			// TODO: useful comment here
465 465
 			unset($includedRoutes[0]);
466 466
 		}
467 467
 		
468 468
 		$myRoutes = array();
469
-		foreach($includedRoutes as $r) {
469
+		foreach ($includedRoutes as $r) {
470 470
 			$myRoutes[$r] = true;
471 471
 		}
472 472
 
473 473
 		$affectedRoutes = array();
474 474
 
475
-		if(isset($this->routes[$route])) {
475
+		if (isset($this->routes[$route])) {
476 476
 			$parent = $route;
477 477
 			do {
478
-				if(!isset($excludedRoutes[$parent])) {
478
+				if (!isset($excludedRoutes[$parent])) {
479 479
 					$affectedRoutes[] = $parent;
480 480
 				}
481 481
 				$r = $this->routes[$parent];
482 482
 
483
-				foreach(array_reverse($r['opt']['nostops']) as $noStop) {
483
+				foreach (array_reverse($r['opt']['nostops']) as $noStop) {
484 484
 					$myR = $this->routes[$noStop];
485
-					if(isset($myRoutes[$noStop])) {
485
+					if (isset($myRoutes[$noStop])) {
486 486
 						unset($myRoutes[$noStop]);
487
-					} elseif(!$myR['opt']['imply']) {
487
+					} elseif (!$myR['opt']['imply']) {
488 488
 						continue;
489 489
 					}
490 490
 
491
-					if(!isset($excludedRoutes[$noStop])) {
491
+					if (!isset($excludedRoutes[$noStop])) {
492 492
 						$affectedRoutes[] = $noStop;
493 493
 					}
494 494
 				}
495 495
 
496 496
 				$parent = $r['opt']['parent'];
497 497
 
498
-			} while($parent);
498
+			} while ($parent);
499 499
 		} else {
500 500
 			// TODO: error handling - route with the given name does not exist
501 501
 		}
502 502
 
503
-		if(count($myRoutes)) {
503
+		if (count($myRoutes)) {
504 504
 			// TODO: error handling - we couldn't find some of the nonstopping rules
505 505
 		}
506 506
 
@@ -521,8 +521,8 @@  discard block
 block discarded – undo
521 521
 	public function getMatchedParameters(array $routeNames)
522 522
 	{
523 523
 		$params = array();
524
-		foreach($routeNames as $name) {
525
-			if(isset($this->routes[$name])) {
524
+		foreach ($routeNames as $name) {
525
+			if (isset($this->routes[$name])) {
526 526
 				$route = $this->routes[$name];
527 527
 				$params = array_merge($params, $route['matches']);
528 528
 			}
@@ -546,17 +546,17 @@  discard block
 block discarded – undo
546 546
 	 */
547 547
 	protected function resolveGenOptions($input = array())
548 548
 	{
549
-		if(is_string($input)) {
549
+		if (is_string($input)) {
550 550
 			// A single option preset was given
551
-			if(isset($this->genOptionsPresets[$input])) {
551
+			if (isset($this->genOptionsPresets[$input])) {
552 552
 				return array_merge($this->defaultGenOptions, $this->genOptionsPresets[$input]);
553 553
 			}
554
-		} elseif(is_array($input)) {
554
+		} elseif (is_array($input)) {
555 555
 			$genOptions = $this->defaultGenOptions;
556
-			foreach($input as $key => $value) {
557
-				if(is_numeric($key)) {
556
+			foreach ($input as $key => $value) {
557
+				if (is_numeric($key)) {
558 558
 					// Numeric key – it's an option preset
559
-					if(isset($this->genOptionsPresets[$value])) {
559
+					if (isset($this->genOptionsPresets[$value])) {
560 560
 						$genOptions = array_merge($genOptions, $this->genOptionsPresets[$value]);
561 561
 					} else {
562 562
 						throw new AgaviException('Undefined Routing gen() options preset "' . $value . '"');
@@ -610,14 +610,14 @@  discard block
 block discarded – undo
610 610
 		$optionalParams = array();
611 611
 		$firstRoute = true;
612 612
 		
613
-		foreach($routeNames as $routeName) {
613
+		foreach ($routeNames as $routeName) {
614 614
 			$r = $this->routes[$routeName];
615 615
 
616 616
 			$myDefaults = $r['opt']['defaults'];
617 617
 
618
-			if(count($r['opt']['callbacks']) > 0) {
619
-				if(!isset($r['callback_instances'])) {
620
-					foreach($r['opt']['callbacks'] as $key => $callback) {
618
+			if (count($r['opt']['callbacks']) > 0) {
619
+				if (!isset($r['callback_instances'])) {
620
+					foreach ($r['opt']['callbacks'] as $key => $callback) {
621 621
 						/** @var RoutingCallback $instance */
622 622
 						$instance = new $callback['class']();
623 623
 						$instance->setParameters($callback['parameters']);
@@ -625,20 +625,20 @@  discard block
 block discarded – undo
625 625
 						$r['callback_instances'][$key] = $instance;
626 626
 					}
627 627
 				}
628
-				foreach($r['callback_instances'] as $callbackInstance) {
628
+				foreach ($r['callback_instances'] as $callbackInstance) {
629 629
 					$paramsCopy = $params;
630 630
 					$isLegacyCallback = false;
631
-					if($callbackInstance instanceof LegacyRoutingCallbackInterface) {
631
+					if ($callbackInstance instanceof LegacyRoutingCallbackInterface) {
632 632
 						$isLegacyCallback = true;
633 633
 						// convert all routing values to strings so legacy callbacks don't break
634 634
 						$defaultsCopy = $myDefaults;
635
-						foreach($paramsCopy as &$param) {
636
-							if($param instanceof RoutingValueInterface) {
635
+						foreach ($paramsCopy as &$param) {
636
+							if ($param instanceof RoutingValueInterface) {
637 637
 								$param = $param->getValue();
638 638
 							}
639 639
 						}
640
-						foreach($defaultsCopy as &$default) {
641
-							if($default instanceof RoutingValueInterface) {
640
+						foreach ($defaultsCopy as &$default) {
641
+							if ($default instanceof RoutingValueInterface) {
642 642
 								$default = array(
643 643
 									'pre' => $default->getPrefix(),
644 644
 									'val' => $default->getValue(),
@@ -647,13 +647,13 @@  discard block
 block discarded – undo
647 647
 							}
648 648
 						}
649 649
 						$changedParamsCopy = $paramsCopy;
650
-						if(!$callbackInstance->onGenerate($defaultsCopy, $paramsCopy, $options)) {
650
+						if (!$callbackInstance->onGenerate($defaultsCopy, $paramsCopy, $options)) {
651 651
 							continue 2;
652 652
 						}
653 653
 						// find all params changed in the callback, but ignore unset() parameters since they will be filled in at a later stage (and doing something the them would prevent default values being inserted after unset()tting of a parameter)
654 654
 						$diff = array();
655
-						foreach($paramsCopy as $key => $value) {
656
-							if(!array_key_exists($key, $changedParamsCopy) || $changedParamsCopy[$key] !== $value) {
655
+						foreach ($paramsCopy as $key => $value) {
656
+							if (!array_key_exists($key, $changedParamsCopy) || $changedParamsCopy[$key] !== $value) {
657 657
 								$diff[$key] = $value;
658 658
 							}
659 659
 						}
@@ -661,13 +661,13 @@  discard block
 block discarded – undo
661 661
 						// $diff = array_udiff_assoc($paramsCopy, $changedParamsCopy, array($this, 'onGenerateParamDiffCallback'));
662 662
 						// likely caused by http://bugs.php.net/bug.php?id=42838 / http://cvs.php.net/viewvc.cgi/php-src/ext/standard/array.c?r1=1.308.2.21.2.51&r2=1.308.2.21.2.52
663 663
 					} else {
664
-						if(!$callbackInstance->onGenerate($myDefaults, $params, $options)) {
664
+						if (!$callbackInstance->onGenerate($myDefaults, $params, $options)) {
665 665
 							continue 2;
666 666
 						}
667 667
 						// find all params changed in the callback, but ignore unset() parameters since they will be filled in at a later stage (and doing something the them would prevent default values being inserted after unset()tting of a parameter)
668 668
 						$diff = array();
669
-						foreach($params as $key => $value) {
670
-							if(!array_key_exists($key, $paramsCopy) || $paramsCopy[$key] !== $value) {
669
+						foreach ($params as $key => $value) {
670
+							if (!array_key_exists($key, $paramsCopy) || $paramsCopy[$key] !== $value) {
671 671
 								$diff[$key] = $value;
672 672
 							}
673 673
 						}
@@ -676,16 +676,16 @@  discard block
 block discarded – undo
676 676
 						// likely caused by http://bugs.php.net/bug.php?id=42838 / http://cvs.php.net/viewvc.cgi/php-src/ext/standard/array.c?r1=1.308.2.21.2.51&r2=1.308.2.21.2.52
677 677
 					}
678 678
 					
679
-					if(count($diff)) {
679
+					if (count($diff)) {
680 680
 						$diffKeys = array_keys($diff);
681
-						foreach($diffKeys as $key) {
681
+						foreach ($diffKeys as $key) {
682 682
 							// NEVER assign this value as a reference, as PHP will go completely bonkers if we use a reference here (it marks the entry in the array as a reference, so modifying the value in $params in a callback means it gets modified in $paramsCopy as well)
683 683
 							// if the callback was a legacy callback, the array to read the values from is different (since everything was cast to strings before running the callback)
684 684
 							$value = $isLegacyCallback ? $paramsCopy[$key] : $params[$key];
685
-							if($value !== null && !($value instanceof RoutingValueInterface)) {
685
+							if ($value !== null && !($value instanceof RoutingValueInterface)) {
686 686
 								$routingValue = $this->createValue($value, false);
687
-								if(isset($myDefaults[$key])) {
688
-									if($myDefaults[$key] instanceof RoutingValueInterface) {
687
+								if (isset($myDefaults[$key])) {
688
+									if ($myDefaults[$key] instanceof RoutingValueInterface) {
689 689
 										// clone the default value so pre and postfix are preserved
690 690
 										/** @var RoutingValue $routingValue */
691 691
 										$routingValue = clone $myDefaults[$key];
@@ -707,7 +707,7 @@  discard block
 block discarded – undo
707 707
 			}
708 708
 
709 709
 			// if the route has a source we shouldn't put its stuff in the generated string
710
-			if($r['opt']['source']) {
710
+			if ($r['opt']['source']) {
711 711
 				continue;
712 712
 			}
713 713
 
@@ -716,8 +716,8 @@  discard block
 block discarded – undo
716 716
 
717 717
 			$availableParams = array_merge($availableParams, array_reverse($r['opt']['pattern_parameters']));
718 718
 
719
-			if($firstRoute || $r['opt']['cut'] || (count($r['opt']['childs']) && $r['opt']['cut'] === null)) {
720
-				if($r['opt']['anchor'] & self::ANCHOR_START || $r['opt']['anchor'] == self::ANCHOR_NONE) {
719
+			if ($firstRoute || $r['opt']['cut'] || (count($r['opt']['childs']) && $r['opt']['cut'] === null)) {
720
+				if ($r['opt']['anchor'] & self::ANCHOR_START || $r['opt']['anchor'] == self::ANCHOR_NONE) {
721 721
 					$uri = $r['opt']['reverseStr'] . $uri;
722 722
 				} else {
723 723
 					$uri = $uri . $r['opt']['reverseStr'];
@@ -756,9 +756,9 @@  discard block
 block discarded – undo
756 756
 	 */
757 757
 	protected function refillAllMatchedParameters(array $options, array $params, array $matchedParams)
758 758
 	{
759
-		if(!empty($options['refill_all_parameters'])) {
760
-			foreach($matchedParams as $name => $value) {
761
-				if(!(isset($params[$name]) || array_key_exists($name, $params))) {
759
+		if (!empty($options['refill_all_parameters'])) {
760
+			foreach ($matchedParams as $name => $value) {
761
+				if (!(isset($params[$name]) || array_key_exists($name, $params))) {
762 762
 					$params[$name] = $this->createValue($value, true);
763 763
 				}
764 764
 			}
@@ -790,14 +790,14 @@  discard block
 block discarded – undo
790 790
 	{
791 791
 		$refillValue = true;
792 792
 		$finalParams = array();
793
-		foreach($availableParams as $name) {
793
+		foreach ($availableParams as $name) {
794 794
 			// loop all params and fill all with the matched parameters
795 795
 			// until a user (not callback) supplied parameter is encountered.
796 796
 			// After that only check defaults. Parameters supplied from the user
797 797
 			// or via callback always have precedence
798 798
 
799 799
 			// keep track if a user supplied parameter has already been encountered
800
-			if($refillValue && (isset($originalUserParams[$name]) || array_key_exists($name, $originalUserParams))) {
800
+			if ($refillValue && (isset($originalUserParams[$name]) || array_key_exists($name, $originalUserParams))) {
801 801
 				$refillValue = false;
802 802
 			}
803 803
 
@@ -807,18 +807,18 @@  discard block
 block discarded – undo
807 807
 			$hasDefault = isset($defaultParams[$name]);
808 808
 			$hasUserCallbackParam = (isset($params[$name]) || array_key_exists($name, $params));
809 809
 
810
-			if($hasUserCallbackParam) {
810
+			if ($hasUserCallbackParam) {
811 811
 				// anything a user or callback supplied has precedence
812 812
 				// and since the user params are handled afterwards, skip them here
813
-			} elseif($refillValue && $hasMatched) {
813
+			} elseif ($refillValue && $hasMatched) {
814 814
 				// Use the matched input
815 815
 				$finalParams[$name] = $this->createValue($matchedParams[$name], true);
816
-			} elseif($hasDefault) {
816
+			} elseif ($hasDefault) {
817 817
 				// now we just need to check if there are defaults for this available param and fill them in if applicable
818 818
 				$default = $defaultParams[$name];
819
-				if(!$isOptional || strlen($default->getValue()) > 0) {
819
+				if (!$isOptional || strlen($default->getValue()) > 0) {
820 820
 					$finalParams[$name] = clone $default;
821
-				} elseif($isOptional) {
821
+				} elseif ($isOptional) {
822 822
 					// there is no default or incoming match for this optional param, so remove it
823 823
 					$finalParams[$name] = null;
824 824
 				}
@@ -847,19 +847,19 @@  discard block
 block discarded – undo
847 847
 	{
848 848
 		$availableParamsAsKeys = array_flip($availableParams);
849 849
 
850
-		foreach($params as $name => $param) {
851
-			if(!(isset($finalParams[$name]) || array_key_exists($name, $finalParams))) {
852
-				if($param === null && isset($optionalParams[$name])) {
850
+		foreach ($params as $name => $param) {
851
+			if (!(isset($finalParams[$name]) || array_key_exists($name, $finalParams))) {
852
+				if ($param === null && isset($optionalParams[$name])) {
853 853
 					// null was set for an optional parameter
854 854
 					$finalParams[$name] = $param;
855 855
 				} else {
856
-					if(isset($defaultParams[$name])) {
857
-						if($param === null || ($param instanceof RoutingValue && $param->getValue() === null)) {
856
+					if (isset($defaultParams[$name])) {
857
+						if ($param === null || ($param instanceof RoutingValue && $param->getValue() === null)) {
858 858
 							// the user set the parameter to null, to signal that the default value should be used
859 859
 							$param = clone $defaultParams[$name];
860 860
 						}
861 861
 						$finalParams[$name] = $param;
862
-					} elseif(isset($availableParamsAsKeys[$name])) {
862
+					} elseif (isset($availableParamsAsKeys[$name])) {
863 863
 						// when the parameter was available in one of the routes
864 864
 						$finalParams[$name] = $param;
865 865
 					}
@@ -887,14 +887,14 @@  discard block
 block discarded – undo
887 887
 	protected function removeMatchingDefaults(array $options, array $finalParams, array $availableParams, array $optionalParams, array $defaultParams)
888 888
 	{
889 889
 		// if omit_defaults is set, we should not put optional values into the result string in case they are equal to their default value - even if they were given as a param
890
-		if(!empty($options['omit_defaults'])) {
890
+		if (!empty($options['omit_defaults'])) {
891 891
 			// remove the optional parameters from the pattern beginning from right to the left, in case they are equal to their default
892
-			foreach(array_reverse($availableParams) as $name) {
893
-				if(isset($optionalParams[$name])) {
892
+			foreach (array_reverse($availableParams) as $name) {
893
+				if (isset($optionalParams[$name])) {
894 894
 					// the isset() could be replaced by
895 895
 					// "!array_key_exists($name, $finalParams) || $finalParams[$name] === null"
896 896
 					// to clarify that null is explicitly allowed here
897
-					if(!isset($finalParams[$name]) ||
897
+					if (!isset($finalParams[$name]) ||
898 898
 							(
899 899
 								isset($defaultParams[$name]) && 
900 900
 								$finalParams[$name]->getValue() == $defaultParams[$name]->getValue() &&
@@ -929,18 +929,18 @@  discard block
 block discarded – undo
929 929
 	 */
930 930
 	protected function updatePrefixAndPostfix(array $finalParams, array $defaultParams)
931 931
 	{
932
-		foreach($finalParams as $name => $param) {
933
-			if($param === null) {
932
+		foreach ($finalParams as $name => $param) {
933
+			if ($param === null) {
934 934
 				continue;
935 935
 			}
936 936
 			
937
-			if(isset($defaultParams[$name])) {
937
+			if (isset($defaultParams[$name])) {
938 938
 				// update the pre- and postfix from the default if they are not set in the routing value
939 939
 				$default = $defaultParams[$name];
940
-				if(!$param->hasPrefix() && $default->hasPrefix()) {
940
+				if (!$param->hasPrefix() && $default->hasPrefix()) {
941 941
 					$param->setPrefix($default->getPrefix());
942 942
 				}
943
-				if(!$param->hasPostfix() && $default->hasPostfix()) {
943
+				if (!$param->hasPostfix() && $default->hasPostfix()) {
944 944
 					$param->setPostfix($default->getPostfix());
945 945
 				}
946 946
 			}
@@ -961,7 +961,7 @@  discard block
 block discarded – undo
961 961
 	 */
962 962
 	protected function encodeParameters(array $options, array $params)
963 963
 	{
964
-		foreach($params as &$param) {
964
+		foreach ($params as &$param) {
965 965
 			$param = $this->encodeParameter($param);
966 966
 		}
967 967
 		return $params;
@@ -979,10 +979,10 @@  discard block
 block discarded – undo
979 979
 	 */
980 980
 	protected function encodeParameter($parameter)
981 981
 	{
982
-		if($parameter instanceof RoutingValue) {
982
+		if ($parameter instanceof RoutingValue) {
983 983
 			return sprintf('%s%s%s', 
984
-				$parameter->getPrefixNeedsEncoding()  ? $this->escapeOutputParameter($parameter->getPrefix())  : $parameter->getPrefix(),
985
-				$parameter->getValueNeedsEncoding()   ? $this->escapeOutputParameter($parameter->getValue())   : $parameter->getValue(),
984
+				$parameter->getPrefixNeedsEncoding() ? $this->escapeOutputParameter($parameter->getPrefix()) : $parameter->getPrefix(),
985
+				$parameter->getValueNeedsEncoding() ? $this->escapeOutputParameter($parameter->getValue()) : $parameter->getValue(),
986 986
 				$parameter->getPostfixNeedsEncoding() ? $this->escapeOutputParameter($parameter->getPostfix()) : $parameter->getPostfix()
987 987
 			);
988 988
 		} else {
@@ -1002,11 +1002,11 @@  discard block
 block discarded – undo
1002 1002
 	 */
1003 1003
 	protected function convertParametersToRoutingValues(array $parameters)
1004 1004
 	{
1005
-		if(count($parameters)) {
1005
+		if (count($parameters)) {
1006 1006
 			// make sure everything in $parameters is a routing value
1007
-			foreach($parameters as &$param) {
1008
-				if(!$param instanceof RoutingValue) {
1009
-					if($param !== null) {
1007
+			foreach ($parameters as &$param) {
1008
+				if (!$param instanceof RoutingValue) {
1009
+					if ($param !== null) {
1010 1010
 						$param = $this->createValue($param);
1011 1011
 					}
1012 1012
 				} else {
@@ -1037,8 +1037,8 @@  discard block
 block discarded – undo
1037 1037
 	 */
1038 1038
 	public function gen($route, array $params = array(), $options = array())
1039 1039
 	{
1040
-		if(array_key_exists('prefix', $options)) {
1041
-			$prefix = (string) $options['prefix'];
1040
+		if (array_key_exists('prefix', $options)) {
1041
+			$prefix = (string)$options['prefix'];
1042 1042
 		} else {
1043 1043
 			$prefix = $this->getPrefix();
1044 1044
 		}
@@ -1046,11 +1046,11 @@  discard block
 block discarded – undo
1046 1046
 		$isNullRoute = false;
1047 1047
 		$routes = $this->getAffectedRoutes($route, $isNullRoute);
1048 1048
 		
1049
-		if(count($routes) == 0) {
1049
+		if (count($routes) == 0) {
1050 1050
 			return array($route, array(), $options, $params, $isNullRoute);
1051 1051
 		}
1052 1052
 		
1053
-		if($isNullRoute) {
1053
+		if ($isNullRoute) {
1054 1054
 			// for gen(null) and friends all matched parameters are inserted before the 
1055 1055
 			// supplied params are backuped
1056 1056
 			$params = $this->fillGenNullParameters($routes, $params);
@@ -1077,7 +1077,7 @@  discard block
 block discarded – undo
1077 1077
 		$extras = array_diff_key(array_merge($originalParams, $params), $finalParams);
1078 1078
 		// but since the values are expected as plain values and not routing values, convert the routing values back to 
1079 1079
 		// 'plain' values
1080
-		foreach($extras as &$extra) {
1080
+		foreach ($extras as &$extra) {
1081 1081
 			$extra = ($extra instanceof RoutingValue) ? $extra->getValue() : $extra;
1082 1082
 		}
1083 1083
 
@@ -1090,14 +1090,14 @@  discard block
 block discarded – undo
1090 1090
 		
1091 1091
 
1092 1092
 		// remove not specified available parameters
1093
-		foreach(array_unique($assembledInformation['available_parameters']) as $name) {
1094
-			if(!isset($params[$name])) {
1093
+		foreach (array_unique($assembledInformation['available_parameters']) as $name) {
1094
+			if (!isset($params[$name])) {
1095 1095
 				$from[] = '(:' . $name . ':)';
1096 1096
 				$to[] = '';
1097 1097
 			}
1098 1098
 		}
1099 1099
 
1100
-		foreach($params as $n => $p) {
1100
+		foreach ($params as $n => $p) {
1101 1101
 			$from[] = '(:' . $n . ':)';
1102 1102
 			$to[] = $p;
1103 1103
 		}
@@ -1142,7 +1142,7 @@  discard block
 block discarded – undo
1142 1142
 		
1143 1143
 		$container = $this->context->getDispatcher()->createExecutionContainer();
1144 1144
 
1145
-		if(!$this->isEnabled()) {
1145
+		if (!$this->isEnabled()) {
1146 1146
 			// routing disabled, just bail out here
1147 1147
 			return $container;
1148 1148
 		}
@@ -1164,8 +1164,8 @@  discard block
 block discarded – undo
1164 1164
 
1165 1165
 		$routes = array();
1166 1166
 		// get all top level routes
1167
-		foreach($this->routes as $name => $route) {
1168
-			if(!$route['opt']['parent']) {
1167
+		foreach ($this->routes as $name => $route) {
1168
+			if (!$route['opt']['parent']) {
1169 1169
 				$routes[] = $name;
1170 1170
 			}
1171 1171
 		}
@@ -1175,12 +1175,12 @@  discard block
 block discarded – undo
1175 1175
 
1176 1176
 		do {
1177 1177
 			$routes = array_pop($routeStack);
1178
-			foreach($routes as $key) {
1179
-				$route =& $this->routes[$key];
1180
-				$opts =& $route['opt'];
1181
-				if(count($opts['constraint']) == 0 || in_array($requestMethod, $opts['constraint'])) {
1182
-					if(count($opts['callbacks']) > 0 && !isset($route['callback_instances'])) {
1183
-						foreach($opts['callbacks'] as $key => $callback) {
1178
+			foreach ($routes as $key) {
1179
+				$route = & $this->routes[$key];
1180
+				$opts = & $route['opt'];
1181
+				if (count($opts['constraint']) == 0 || in_array($requestMethod, $opts['constraint'])) {
1182
+					if (count($opts['callbacks']) > 0 && !isset($route['callback_instances'])) {
1183
+						foreach ($opts['callbacks'] as $key => $callback) {
1184 1184
 							/** @var RoutingCallback $instance */
1185 1185
 							$instance = new $callback['class']();
1186 1186
 							$instance->initialize($this->context, $route);
@@ -1190,37 +1190,37 @@  discard block
 block discarded – undo
1190 1190
 					}
1191 1191
 
1192 1192
 					$match = array();
1193
-					if($this->parseInput($route, $input, $match)) {
1193
+					if ($this->parseInput($route, $input, $match)) {
1194 1194
 						$varsBackup = $vars;
1195 1195
 						
1196 1196
 						// backup the container, must be done here already
1197
-						if(count($opts['callbacks']) > 0) {
1197
+						if (count($opts['callbacks']) > 0) {
1198 1198
 							$containerBackup = $container;
1199 1199
 							$container = clone $container;
1200 1200
 						}
1201 1201
 						
1202 1202
 						$ign = array();
1203
-						if(count($opts['ignores']) > 0) {
1203
+						if (count($opts['ignores']) > 0) {
1204 1204
 							$ign = array_flip($opts['ignores']);
1205 1205
 						}
1206 1206
 
1207 1207
 						/**
1208 1208
 						 * @var $value RoutingValue;
1209 1209
 						 */
1210
-						foreach($opts['defaults'] as $key => $value) {
1211
-							if(!isset($ign[$key]) && $value->getValue() !== null) {
1210
+						foreach ($opts['defaults'] as $key => $value) {
1211
+							if (!isset($ign[$key]) && $value->getValue() !== null) {
1212 1212
 								$vars[$key] = $value->getValue();
1213 1213
 							}
1214 1214
 						}
1215 1215
 
1216
-						foreach($route['par'] as $param) {
1217
-							if(isset($match[$param]) && $match[$param][1] != -1) {
1216
+						foreach ($route['par'] as $param) {
1217
+							if (isset($match[$param]) && $match[$param][1] != -1) {
1218 1218
 								$vars[$param] = $match[$param][0];
1219 1219
 							}
1220 1220
 						}
1221 1221
 
1222
-						foreach($match as $name => $m) {
1223
-							if(is_string($name) && $m[1] != -1) {
1222
+						foreach ($match as $name => $m) {
1223
+							if (is_string($name) && $m[1] != -1) {
1224 1224
 								$route['matches'][$name] = $m[0];
1225 1225
 							}
1226 1226
 						}
@@ -1239,23 +1239,23 @@  discard block
 block discarded – undo
1239 1239
 						}
1240 1240
 						// */
1241 1241
 
1242
-						if($opts['module']) {
1242
+						if ($opts['module']) {
1243 1243
 							$module = Toolkit::expandVariables($opts['module'], $matchvals);
1244 1244
 							$container->setModuleName($module);
1245
-							if($umap) {
1245
+							if ($umap) {
1246 1246
 								$vars[$ma] = $module;
1247 1247
 							}
1248 1248
 						}
1249 1249
 
1250
-						if($opts['controller']) {
1250
+						if ($opts['controller']) {
1251 1251
 							$controller = Toolkit::expandVariables($opts['controller'], $matchvals);
1252 1252
 							$container->setControllerName($controller);
1253
-							if($umap) {
1253
+							if ($umap) {
1254 1254
 								$vars[$aa] = $controller;
1255 1255
 							}
1256 1256
 						}
1257 1257
 
1258
-						if($opts['output_type']) {
1258
+						if ($opts['output_type']) {
1259 1259
 							// set the output type if necessary
1260 1260
 							// here no explicit check is done, since in 0.11 this is compared against null
1261 1261
 							// which can never be the result of expandVariables
@@ -1265,15 +1265,15 @@  discard block
 block discarded – undo
1265 1265
 							// and because it makes sense - maybe a callback checks or changes the output type name
1266 1266
 							try {
1267 1267
 								$container->setOutputType($this->context->getDispatcher()->getOutputType($ot));
1268
-							} catch(AgaviException $e) {
1268
+							} catch (AgaviException $e) {
1269 1269
 							}
1270 1270
 						}
1271 1271
 
1272
-						if($opts['locale']) {
1272
+						if ($opts['locale']) {
1273 1273
 							$localeBackup = $tm->getCurrentLocaleIdentifier();
1274 1274
 							
1275 1275
 							// set the locale if necessary
1276
-							if($locale = Toolkit::expandVariables($opts['locale'], $matchvals)) {
1276
+							if ($locale = Toolkit::expandVariables($opts['locale'], $matchvals)) {
1277 1277
 								// the if is here for bc reasons, since if $opts['locale'] only contains variable parts
1278 1278
 								// expandVariables could possibly return an empty string in which case the pre 1.0 routing
1279 1279
 								// didn't set the variable
@@ -1282,7 +1282,7 @@  discard block
 block discarded – undo
1282 1282
 								// and because it makes sense - maybe a callback checks or changes the locale name
1283 1283
 								try {
1284 1284
 									$tm->setLocale($locale);
1285
-								} catch(AgaviException $e) {
1285
+								} catch (AgaviException $e) {
1286 1286
 								}
1287 1287
 							}
1288 1288
 						} else {
@@ -1290,9 +1290,9 @@  discard block
 block discarded – undo
1290 1290
 							$localeBackup = null;
1291 1291
 						}
1292 1292
 
1293
-						if($opts['method']) {
1293
+						if ($opts['method']) {
1294 1294
 							// set the request method if necessary
1295
-							if($method = Toolkit::expandVariables($opts['method'], $matchvals)) {
1295
+							if ($method = Toolkit::expandVariables($opts['method'], $matchvals)) {
1296 1296
 								// the if is here for bc reasons, since if $opts['method'] only contains variable parts
1297 1297
 								// expandVariables could possibly return an empty string in which case the pre 1.0 routing
1298 1298
 								// didn't set the variable
@@ -1302,31 +1302,31 @@  discard block
 block discarded – undo
1302 1302
 							}
1303 1303
 						}
1304 1304
 
1305
-						if(count($opts['callbacks']) > 0) {
1306
-							if(count($opts['ignores']) > 0) {
1305
+						if (count($opts['callbacks']) > 0) {
1306
+							if (count($opts['ignores']) > 0) {
1307 1307
 								// add ignored variables to the callback vars
1308
-								foreach($vars as $name => &$var) {
1309
-									$vars[$name] =& $var;
1308
+								foreach ($vars as $name => &$var) {
1309
+									$vars[$name] = & $var;
1310 1310
 								}
1311
-								foreach($opts['ignores'] as $ignore) {
1312
-									if(isset($match[$ignore]) && $match[$ignore][1] != -1) {
1311
+								foreach ($opts['ignores'] as $ignore) {
1312
+									if (isset($match[$ignore]) && $match[$ignore][1] != -1) {
1313 1313
 										$vars[$ignore] = $match[$ignore][0];
1314 1314
 									}
1315 1315
 								}
1316 1316
 							}
1317 1317
 							$callbackSuccess = true;
1318 1318
 							/** @var RoutingCallback $callbackInstance */
1319
-							foreach($route['callback_instances'] as $callbackInstance) {
1319
+							foreach ($route['callback_instances'] as $callbackInstance) {
1320 1320
 								// call onMatched on all callbacks until one of them returns false
1321 1321
 								// then restore state and call onNotMatched on that same callback
1322 1322
 								// after that, call onNotMatched for all remaining callbacks of that route
1323
-								if($callbackSuccess) {
1323
+								if ($callbackSuccess) {
1324 1324
 									// backup stuff which could be changed in the callback so we are 
1325 1325
 									// able to determine which values were changed in the callback
1326 1326
 									$oldModule = $container->getModuleName();
1327 1327
 									$oldController = $container->getControllerName();
1328 1328
 									$oldOutputTypeName = $container->getOutputType() ? $container->getOutputType()->getName() : null;
1329
-									if(null === $tm) {
1329
+									if (null === $tm) {
1330 1330
 										$oldLocale = null;
1331 1331
 									} else {
1332 1332
 										$oldLocale = $tm->getCurrentLocaleIdentifier();
@@ -1335,10 +1335,10 @@  discard block
 block discarded – undo
1335 1335
 									$oldContainerMethod = $container->getRequestMethod();
1336 1336
 
1337 1337
 									$onMatched = $callbackInstance->onMatched($vars, $container);
1338
-									if($onMatched instanceof Response) {
1338
+									if ($onMatched instanceof Response) {
1339 1339
 										return $onMatched;
1340 1340
 									}
1341
-									if(!$onMatched) {
1341
+									if (!$onMatched) {
1342 1342
 										$callbackSuccess = false;
1343 1343
 										
1344 1344
 										// reset the matches array. it must be populated by the time onMatched() is called so matches can be modified in a callback
@@ -1348,7 +1348,7 @@  discard block
 block discarded – undo
1348 1348
 										// reset all relevant container data we already set in the container for this (now non matching) route
1349 1349
 										$container = $containerBackup;
1350 1350
 										// restore locale
1351
-										if(isset($localeBackup)) {
1351
+										if (isset($localeBackup)) {
1352 1352
 											$tm->setLocale($localeBackup);
1353 1353
 										}
1354 1354
 										// restore request method
@@ -1357,9 +1357,9 @@  discard block
 block discarded – undo
1357 1357
 								}
1358 1358
 								
1359 1359
 								// always call onNotMatched if $callbackSuccess == false, even if we just called onMatched() on the same instance. this is expected behavior
1360
-								if(!$callbackSuccess) {
1360
+								if (!$callbackSuccess) {
1361 1361
 									$onNotMatched = $callbackInstance->onNotMatched($container);
1362
-									if($onNotMatched instanceof Response) {
1362
+									if ($onNotMatched instanceof Response) {
1363 1363
 										return $onNotMatched;
1364 1364
 									}
1365 1365
 									
@@ -1371,8 +1371,8 @@  discard block
 block discarded – undo
1371 1371
 								$expandVars = $vars;
1372 1372
 								$routeParamsAsKey = array_flip($route['par']);
1373 1373
 								// only use parameters which are defined in this route or are new
1374
-								foreach($expandVars as $name => $value) {
1375
-									if(!isset($routeParamsAsKey[$name]) && array_key_exists($name, $varsBackup)) {
1374
+								foreach ($expandVars as $name => $value) {
1375
+									if (!isset($routeParamsAsKey[$name]) && array_key_exists($name, $varsBackup)) {
1376 1376
 										unset($expandVars[$name]);
1377 1377
 									}
1378 1378
 								} 
@@ -1385,42 +1385,42 @@  discard block
 block discarded – undo
1385 1385
 								// if the callback didn't change the value, execute expandVariables again since 
1386 1386
 								// the callback could have changed one of the values which expandVariables uses
1387 1387
 								// to evaluate the contents of the attribute in question (e.g. module="${zomg}")
1388
-								if($opts['module'] && $oldModule == $container->getModuleName() && (!$umap || !array_key_exists($ma, $vars) || $oldModule == $vars[$ma])) {
1388
+								if ($opts['module'] && $oldModule == $container->getModuleName() && (!$umap || !array_key_exists($ma, $vars) || $oldModule == $vars[$ma])) {
1389 1389
 									$module = Toolkit::expandVariables($opts['module'], $expandVars);
1390 1390
 									$container->setModuleName($module);
1391
-									if($umap) {
1391
+									if ($umap) {
1392 1392
 										$vars[$ma] = $module;
1393 1393
 									}
1394 1394
 								}
1395
-								if($opts['controller'] && $oldController == $container->getControllerName() && (!$umap || !array_key_exists($aa, $vars) || $oldController == $vars[$aa])) {
1395
+								if ($opts['controller'] && $oldController == $container->getControllerName() && (!$umap || !array_key_exists($aa, $vars) || $oldController == $vars[$aa])) {
1396 1396
 									$controller = Toolkit::expandVariables($opts['controller'], $expandVars);
1397 1397
 									$container->setControllerName($controller);
1398
-									if($umap) {
1398
+									if ($umap) {
1399 1399
 										$vars[$aa] = $controller;
1400 1400
 									}
1401 1401
 								}
1402
-								if($opts['output_type'] && $oldOutputTypeName == ($container->getOutputType() ? $container->getOutputType()->getName() : null)) {
1402
+								if ($opts['output_type'] && $oldOutputTypeName == ($container->getOutputType() ? $container->getOutputType()->getName() : null)) {
1403 1403
 									$ot = Toolkit::expandVariables($opts['output_type'], $expandVars);
1404 1404
 									$container->setOutputType($this->context->getDispatcher()->getOutputType($ot));
1405 1405
 								}
1406
-								if($opts['locale'] && $oldLocale == $tm->getCurrentLocaleIdentifier()) {
1407
-									if($locale = Toolkit::expandVariables($opts['locale'], $expandVars)) {
1406
+								if ($opts['locale'] && $oldLocale == $tm->getCurrentLocaleIdentifier()) {
1407
+									if ($locale = Toolkit::expandVariables($opts['locale'], $expandVars)) {
1408 1408
 										// see above for the reason of the if
1409 1409
 										$tm->setLocale($locale);
1410 1410
 									}
1411 1411
 								}
1412
-								if($opts['method']) {
1413
-									if($oldRequestMethod == $rq->getMethod() && $oldContainerMethod == $container->getRequestMethod()) {
1414
-										if($method = Toolkit::expandVariables($opts['method'], $expandVars)) {
1412
+								if ($opts['method']) {
1413
+									if ($oldRequestMethod == $rq->getMethod() && $oldContainerMethod == $container->getRequestMethod()) {
1414
+										if ($method = Toolkit::expandVariables($opts['method'], $expandVars)) {
1415 1415
 											// see above for the reason of the if
1416 1416
 											$rq->setMethod($method);
1417 1417
 											$container->setRequestMethod($method);
1418 1418
 										}
1419
-									} elseif($oldContainerMethod != $container->getRequestMethod()) {
1419
+									} elseif ($oldContainerMethod != $container->getRequestMethod()) {
1420 1420
 										// copy the request method to the request (a method set on the container 
1421 1421
 										// in a callback always has precedence over request methods set on the request)
1422 1422
 										$rq->setMethod($container->getRequestMethod());
1423
-									} elseif($oldRequestMethod != $rq->getMethod()) {
1423
+									} elseif ($oldRequestMethod != $rq->getMethod()) {
1424 1424
 										// copy the request method to the container
1425 1425
 										$container->setRequestMethod($rq->getMethod());
1426 1426
 									}
@@ -1428,14 +1428,14 @@  discard block
 block discarded – undo
1428 1428
 								
1429 1429
 								// one last thing we need to do: see if one of the callbacks modified the 'controller' or 'module' vars inside $vars if $umap is on
1430 1430
 								// we then need to write those back to the container, unless they changed THERE, too, in which case the container values take precedence
1431
-								if($umap && $oldModule == $container->getModuleName() && array_key_exists($ma, $vars) && $vars[$ma] != $oldModule) {
1431
+								if ($umap && $oldModule == $container->getModuleName() && array_key_exists($ma, $vars) && $vars[$ma] != $oldModule) {
1432 1432
 									$container->setModuleName($vars[$ma]);
1433 1433
 								}
1434
-								if($umap && $oldController == $container->getControllerName() && array_key_exists($aa, $vars) && $vars[$aa] != $oldController) {
1434
+								if ($umap && $oldController == $container->getControllerName() && array_key_exists($aa, $vars) && $vars[$aa] != $oldController) {
1435 1435
 									$container->setControllerName($vars[$aa]);
1436 1436
 								}
1437 1437
 							}
1438
-							if(!$callbackSuccess) {
1438
+							if (!$callbackSuccess) {
1439 1439
 								// jump straight to the next route
1440 1440
 								continue;
1441 1441
 							} else {
@@ -1443,8 +1443,8 @@  discard block
 block discarded – undo
1443 1443
 								// Restoring them from the backup is necessary since otherwise a value which has been set before this route
1444 1444
 								// and which was ignored in this route would take the ignored value instead of keeping the old one.
1445 1445
 								// And variables which have not been set in an earlier routes need to be removed again
1446
-								foreach($opts['ignores'] as $ignore) {
1447
-									if(array_key_exists($ignore, $varsBackup)) {
1446
+								foreach ($opts['ignores'] as $ignore) {
1447
+									if (array_key_exists($ignore, $varsBackup)) {
1448 1448
 										$vars[$ignore] = $varsBackup[$ignore];
1449 1449
 									} else {
1450 1450
 										unset($vars[$ignore]);
@@ -1455,38 +1455,38 @@  discard block
 block discarded – undo
1455 1455
 
1456 1456
 						$matchedRoutes[] = $opts['name'];
1457 1457
 
1458
-						if($opts['cut'] || (count($opts['childs']) && $opts['cut'] === null)) {
1459
-							if($route['opt']['source'] !== null) {
1460
-								$s =& $this->sources[$route['opt']['source']];
1458
+						if ($opts['cut'] || (count($opts['childs']) && $opts['cut'] === null)) {
1459
+							if ($route['opt']['source'] !== null) {
1460
+								$s = & $this->sources[$route['opt']['source']];
1461 1461
 							} else {
1462
-								$s =& $input;
1462
+								$s = & $input;
1463 1463
 							}
1464 1464
 
1465 1465
 							$ni = '';
1466 1466
 							// if the route didn't match from the start of the input preserve the 'prefix'
1467
-							if($match[0][1] > 0) {
1467
+							if ($match[0][1] > 0) {
1468 1468
 								$ni = substr($s, 0, $match[0][1]);
1469 1469
 							}
1470 1470
 							$ni .= substr($s, $match[0][1] + strlen($match[0][0]));
1471 1471
 							$s = $ni;
1472 1472
 						}
1473 1473
 
1474
-						if(count($opts['childs'])) {
1474
+						if (count($opts['childs'])) {
1475 1475
 							// our childs need to be processed next and stop processing 'afterwards'
1476 1476
 							$routeStack[] = $opts['childs'];
1477 1477
 							break;
1478 1478
 						}
1479 1479
 
1480
-						if($opts['stop']) {
1480
+						if ($opts['stop']) {
1481 1481
 							break;
1482 1482
 						}
1483 1483
 
1484 1484
 					} else {
1485
-						if(count($opts['callbacks']) > 0) {
1485
+						if (count($opts['callbacks']) > 0) {
1486 1486
 							/** @var RoutingCallback $callbackInstance */
1487
-							foreach($route['callback_instances'] as $callbackInstance) {
1487
+							foreach ($route['callback_instances'] as $callbackInstance) {
1488 1488
 								$onNotMatched = $callbackInstance->onNotMatched($container);
1489
-								if($onNotMatched instanceof Response) {
1489
+								if ($onNotMatched instanceof Response) {
1490 1490
 									return $onNotMatched;
1491 1491
 								}
1492 1492
 							}
@@ -1494,17 +1494,17 @@  discard block
 block discarded – undo
1494 1494
 					}
1495 1495
 				}
1496 1496
 			}
1497
-		} while(count($routeStack) > 0);
1497
+		} while (count($routeStack) > 0);
1498 1498
 
1499 1499
 		// put the vars into the request
1500 1500
 		$rd->setParameters($vars);
1501 1501
 
1502
-		if($container->getModuleName() === null || $container->getControllerName() === null) {
1502
+		if ($container->getModuleName() === null || $container->getControllerName() === null) {
1503 1503
 			// no route which supplied the required parameters matched, use 404 controller
1504 1504
 			$container->setModuleName(Config::get('controllers.error_404_module'));
1505 1505
 			$container->setControllerName(Config::get('controllers.error_404_controller'));
1506 1506
 			
1507
-			if($umap) {
1507
+			if ($umap) {
1508 1508
 				$rd->setParameters(array(
1509 1509
 					$ma => $container->getModuleName(),
1510 1510
 					$aa => $container->getControllerName(),
@@ -1533,17 +1533,17 @@  discard block
 block discarded – undo
1533 1533
 	 */
1534 1534
 	protected function parseInput(array $route, $input, &$matches)
1535 1535
 	{
1536
-		if($route['opt']['source'] !== null) {
1536
+		if ($route['opt']['source'] !== null) {
1537 1537
 			$parts = ArrayPathDefinition::getPartsFromPath($route['opt']['source']);
1538 1538
 			$partArray = $parts['parts'];
1539 1539
 			$count = count($partArray);
1540
-			if($count > 0 && isset($this->sources[$partArray[0]])) {
1540
+			if ($count > 0 && isset($this->sources[$partArray[0]])) {
1541 1541
 				$input = $this->sources[$partArray[0]];
1542
-				if($count > 1) {
1542
+				if ($count > 1) {
1543 1543
 					array_shift($partArray);
1544
-					if(is_array($input)) {
1544
+					if (is_array($input)) {
1545 1545
 						$input = ArrayPathDefinition::getValue($partArray, $input);
1546
-					} elseif($input instanceof RoutingSourceInterface) {
1546
+					} elseif ($input instanceof RoutingSourceInterface) {
1547 1547
 						$input = $input->getSource($partArray);
1548 1548
 					}
1549 1549
 				}
@@ -1589,36 +1589,36 @@  discard block
 block discarded – undo
1589 1589
 		$bracketCount = 0;
1590 1590
 		$hasBrackets = false;
1591 1591
 
1592
-		for($i = 0; $i < $len; ++$i) {
1592
+		for ($i = 0; $i < $len; ++$i) {
1593 1593
 			$atEnd = $i + 1 == $len;
1594 1594
 
1595 1595
 			$c = $str[$i];
1596 1596
 
1597
-			if(!$atEnd && !$inEscape && $c == '\\') {
1597
+			if (!$atEnd && !$inEscape && $c == '\\') {
1598 1598
 				$cNext = $str[$i + 1];
1599 1599
 
1600
-				if(
1600
+				if (
1601 1601
 					($cNext == '\\') ||
1602 1602
 					($state == 'start' && $cNext == '(') ||
1603
-					($state == 'rxStart' && in_array($cNext, array('(',')','{','}')))
1603
+					($state == 'rxStart' && in_array($cNext, array('(', ')', '{', '}')))
1604 1604
 				) {
1605 1605
 					$inEscape = true;
1606 1606
 					continue;
1607 1607
 				}
1608
-				if($state == 'afterRx' && $cNext == '?') {
1608
+				if ($state == 'afterRx' && $cNext == '?') {
1609 1609
 					$inEscape = false;
1610 1610
 					$state = 'start';
1611 1611
 					continue;
1612 1612
 				}
1613
-			} elseif($inEscape) {
1613
+			} elseif ($inEscape) {
1614 1614
 				$tmpStr .= $c;
1615 1615
 				$inEscape = false;
1616 1616
 				continue;
1617 1617
 			}
1618 1618
 
1619
-			if($state == 'start') {
1619
+			if ($state == 'start') {
1620 1620
 				// start of regular expression block
1621
-				if($c == '(') {
1621
+				if ($c == '(') {
1622 1622
 					$rxStr .= preg_quote($tmpStr, '#');
1623 1623
 					$reverseStr .= $tmpStr;
1624 1624
 
@@ -1632,54 +1632,54 @@  discard block
 block discarded – undo
1632 1632
 					$tmpStr .= $c;
1633 1633
 				}
1634 1634
 
1635
-				if($atEnd) {
1635
+				if ($atEnd) {
1636 1636
 					$rxStr .= preg_quote($tmpStr, '#');
1637 1637
 					$reverseStr .= $tmpStr;
1638 1638
 				}
1639
-			} elseif($state == 'rxStart') {
1640
-				if($c == '{') {
1639
+			} elseif ($state == 'rxStart') {
1640
+				if ($c == '{') {
1641 1641
 					++$bracketCount;
1642
-					if($bracketCount == 1) {
1642
+					if ($bracketCount == 1) {
1643 1643
 						$hasBrackets = true;
1644 1644
 						$rxPrefix = $tmpStr;
1645 1645
 						$tmpStr = '';
1646 1646
 					} else {
1647 1647
 						$tmpStr .= $c;
1648 1648
 					}
1649
-				} elseif($c == '}') {
1649
+				} elseif ($c == '}') {
1650 1650
 					--$bracketCount;
1651
-					if($bracketCount == 0) {
1651
+					if ($bracketCount == 0) {
1652 1652
 						list($rxName, $rxInner) = $this->parseParameterDefinition($tmpStr);
1653 1653
 						$tmpStr = '';
1654 1654
 					} else {
1655 1655
 						$tmpStr .= $c;
1656 1656
 					}
1657
-				} elseif($c == '(') {
1657
+				} elseif ($c == '(') {
1658 1658
 					++$parenthesisCount;
1659 1659
 					$tmpStr .= $c;
1660
-				} elseif($c == ')') {
1660
+				} elseif ($c == ')') {
1661 1661
 					--$parenthesisCount;
1662
-					if($parenthesisCount > 0) {
1662
+					if ($parenthesisCount > 0) {
1663 1663
 						$tmpStr .= $c;
1664 1664
 					} else {
1665
-						if($parenthesisCount < 0) {
1665
+						if ($parenthesisCount < 0) {
1666 1666
 							throw new AgaviException('The pattern ' . $str . ' contains an unbalanced set of parentheses!');
1667 1667
 						}
1668 1668
 
1669
-						if(!$hasBrackets) {
1669
+						if (!$hasBrackets) {
1670 1670
 							list($rxName, $rxInner) = $this->parseParameterDefinition($tmpStr);
1671 1671
 						} else {
1672
-							if($bracketCount != 0) {
1672
+							if ($bracketCount != 0) {
1673 1673
 								throw new AgaviException('The pattern ' . $str . ' contains an unbalanced set of brackets!');
1674 1674
 							}
1675 1675
 							$rxPostfix = $tmpStr;
1676 1676
 						}
1677 1677
 
1678
-						if(!$rxName) {
1678
+						if (!$rxName) {
1679 1679
 							$myRx = $rxPrefix . $rxInner . $rxPostfix;
1680 1680
 							// if the entire regular expression doesn't contain any regular expression character we can safely append it to the reverseStr
1681 1681
 							//if(strlen($myRx) == strcspn($myRx, $rxChars)) {
1682
-							if(strpbrk($myRx, $rxChars) === false) {
1682
+							if (strpbrk($myRx, $rxChars) === false) {
1683 1683
 								$reverseStr .= $myRx;
1684 1684
 							}
1685 1685
 							$rxStr .= str_replace('#', '\#', sprintf('(%s)', $myRx));
@@ -1687,14 +1687,14 @@  discard block
 block discarded – undo
1687 1687
 							$rxStr .= str_replace('#', '\#', sprintf('(%s(?P<%s>%s)%s)', $rxPrefix, $rxName, $rxInner, $rxPostfix));
1688 1688
 							$reverseStr .= sprintf('(:%s:)', $rxName);
1689 1689
 
1690
-							if(!isset($vars[$rxName])) {
1691
-								if(strpbrk($rxPrefix, $rxChars) !== false) {
1690
+							if (!isset($vars[$rxName])) {
1691
+								if (strpbrk($rxPrefix, $rxChars) !== false) {
1692 1692
 									$rxPrefix = null;
1693 1693
 								}
1694
-								if(strpbrk($rxInner, $rxChars) !== false) {
1694
+								if (strpbrk($rxInner, $rxChars) !== false) {
1695 1695
 									$rxInner = null;
1696 1696
 								}
1697
-								if(strpbrk($rxPostfix, $rxChars) !== false) {
1697
+								if (strpbrk($rxPostfix, $rxChars) !== false) {
1698 1698
 									$rxPostfix = null;
1699 1699
 								}
1700 1700
 
@@ -1709,13 +1709,13 @@  discard block
 block discarded – undo
1709 1709
 					$tmpStr .= $c;
1710 1710
 				}
1711 1711
 
1712
-				if($atEnd && $parenthesisCount != 0) {
1712
+				if ($atEnd && $parenthesisCount != 0) {
1713 1713
 					throw new AgaviException('The pattern ' . $str . ' contains an unbalanced set of parentheses!');
1714 1714
 				}
1715
-			} elseif($state == 'afterRx') {
1716
-				if($c == '?') {
1715
+			} elseif ($state == 'afterRx') {
1716
+				if ($c == '?') {
1717 1717
 					// only record the optional state when the pattern had a name
1718
-					if(isset($vars[$rxName])) {
1718
+					if (isset($vars[$rxName])) {
1719 1719
 						$vars[$rxName]['is_optional'] = true;
1720 1720
 					}
1721 1721
 					$rxStr .= $c;
Please login to merge, or discard this patch.
src/build/phing/org/agavi/build/tasks/DisplayControllersTask.php 1 patch
Indentation   +59 added lines, -59 removed lines patch added patch discarded remove patch
@@ -31,75 +31,75 @@
 block discarded – undo
31 31
  */
32 32
 class AgaviDisplayControllersTask extends AgaviTask
33 33
 {
34
-	protected $path = null;
34
+    protected $path = null;
35 35
 	
36
-	/**
37
-	 * Sets the path to the project directory from which this task will read.
38
-	 *
39
-	 * @param      PhingFile Path to the project directory.
40
-	 */
41
-	public function setPath(PhingFile $path)
42
-	{
43
-		$this->path = $path;
44
-	}
36
+    /**
37
+     * Sets the path to the project directory from which this task will read.
38
+     *
39
+     * @param      PhingFile Path to the project directory.
40
+     */
41
+    public function setPath(PhingFile $path)
42
+    {
43
+        $this->path = $path;
44
+    }
45 45
 	
46
-	/**
47
-	 * Executes this task.
48
-	 */
49
-	public function main()
50
-	{
51
-		if($this->path === null) {
52
-			throw new \Agavi\Build\Exception\BuildException('The path attribute must be specified');
53
-		}
46
+    /**
47
+     * Executes this task.
48
+     */
49
+    public function main()
50
+    {
51
+        if($this->path === null) {
52
+            throw new \Agavi\Build\Exception\BuildException('The path attribute must be specified');
53
+        }
54 54
 		
55
-		$check = new \Agavi\Build\Check\ModuleFilesystemCheck();
56
-		$check->setConfigDirectory($this->project->getProperty('module.config.directory'));
55
+        $check = new \Agavi\Build\Check\ModuleFilesystemCheck();
56
+        $check->setConfigDirectory($this->project->getProperty('module.config.directory'));
57 57
 		
58
-		$check->setPath($this->path->getAbsolutePath());
59
-		if(!$check->check()) {
60
-			throw new \Agavi\Build\Exception\BuildException('The path attribute must be a valid module base directory');
61
-		}
58
+        $check->setPath($this->path->getAbsolutePath());
59
+        if(!$check->check()) {
60
+            throw new \Agavi\Build\Exception\BuildException('The path attribute must be a valid module base directory');
61
+        }
62 62
 		
63
-		/* We don't know whether the module is configured or not here, so load the
63
+        /* We don't know whether the module is configured or not here, so load the
64 64
 		 * values we want properly. */
65
-		$this->tryLoadAgavi();
66
-		$this->tryBootstrapAgavi();
65
+        $this->tryLoadAgavi();
66
+        $this->tryBootstrapAgavi();
67 67
 		
68
-		require_once(\Agavi\Config\ConfigCache::checkConfig(
69
-			sprintf('%s/%s/module.xml',
70
-				$this->path->getAbsolutePath(),
71
-				(string)$this->project->getProperty('module.config.directory')
72
-			)
73
-		));
68
+        require_once(\Agavi\Config\ConfigCache::checkConfig(
69
+            sprintf('%s/%s/module.xml',
70
+                $this->path->getAbsolutePath(),
71
+                (string)$this->project->getProperty('module.config.directory')
72
+            )
73
+        ));
74 74
 		
75
-		$controllerPath = \Agavi\Util\Toolkit::expandVariables(
76
-			\Agavi\Util\Toolkit::expandDirectives(\Agavi\Config\Config::get(
77
-				sprintf('modules.%s.agavi.controller.path', strtolower($this->path->getName())),
78
-				'%core.module_dir%/${moduleName}/controllers/${controllerName}Controller.class.php'
79
-			)),
80
-			array(
81
-				'moduleName' => $this->path->getName()
82
-			)
83
-		);
84
-		$pattern = '#^' . \Agavi\Util\Toolkit::expandVariables(
85
-			/* Blaaaaaaaaauuuuuughhhhhhh... */
86
-			str_replace('\\$\\{controllerName\\}', '${controllerName}', preg_quote($controllerPath, '#')),
87
-			array('controllerName' => '(?P<controller_name>.*?)')
88
-		) . '$#';
75
+        $controllerPath = \Agavi\Util\Toolkit::expandVariables(
76
+            \Agavi\Util\Toolkit::expandDirectives(\Agavi\Config\Config::get(
77
+                sprintf('modules.%s.agavi.controller.path', strtolower($this->path->getName())),
78
+                '%core.module_dir%/${moduleName}/controllers/${controllerName}Controller.class.php'
79
+            )),
80
+            array(
81
+                'moduleName' => $this->path->getName()
82
+            )
83
+        );
84
+        $pattern = '#^' . \Agavi\Util\Toolkit::expandVariables(
85
+            /* Blaaaaaaaaauuuuuughhhhhhh... */
86
+            str_replace('\\$\\{controllerName\\}', '${controllerName}', preg_quote($controllerPath, '#')),
87
+            array('controllerName' => '(?P<controller_name>.*?)')
88
+        ) . '$#';
89 89
 		
90
-		$iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($this->path->getAbsolutePath()));
91
-		for(; $iterator->valid(); $iterator->next()) {
92
-			$rdi = $iterator->getInnerIterator();
93
-			if($rdi->isDot() || !$rdi->isFile()) {
94
-				continue;
95
-			}
90
+        $iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($this->path->getAbsolutePath()));
91
+        for(; $iterator->valid(); $iterator->next()) {
92
+            $rdi = $iterator->getInnerIterator();
93
+            if($rdi->isDot() || !$rdi->isFile()) {
94
+                continue;
95
+            }
96 96
 			
97
-			$file = $rdi->getPathname();
98
-			if(preg_match($pattern, $file, $matches)) {
99
-				$this->log(str_replace(DIRECTORY_SEPARATOR, '.', $matches['controller_name']));
100
-			}
101
-		}
102
-	}
97
+            $file = $rdi->getPathname();
98
+            if(preg_match($pattern, $file, $matches)) {
99
+                $this->log(str_replace(DIRECTORY_SEPARATOR, '.', $matches['controller_name']));
100
+            }
101
+        }
102
+    }
103 103
 }
104 104
 
105 105
 ?>
106 106
\ No newline at end of file
Please login to merge, or discard this patch.
src/build/phing/org/agavi/build/tasks/ListControllersTask.php 1 patch
Indentation   +77 added lines, -77 removed lines patch added patch discarded remove patch
@@ -31,96 +31,96 @@
 block discarded – undo
31 31
  */
32 32
 class ListControllersTask extends AgaviTask
33 33
 {
34
-	protected $property = null;
35
-	protected $path = null;
34
+    protected $property = null;
35
+    protected $path = null;
36 36
 	
37
-	/**
38
-	 * Sets the property that this task will modify.
39
-	 *
40
-	 * @param      string The property to modify.
41
-	 */
42
-	public function setProperty($property)
43
-	{
44
-		$this->property = $property;
45
-	}
37
+    /**
38
+     * Sets the property that this task will modify.
39
+     *
40
+     * @param      string The property to modify.
41
+     */
42
+    public function setProperty($property)
43
+    {
44
+        $this->property = $property;
45
+    }
46 46
 	
47
-	/**
48
-	 * Sets the path to the project directory from which this task will read.
49
-	 *
50
-	 * @param      PhingFile Path to the project directory.
51
-	 */
52
-	public function setPath(PhingFile $path)
53
-	{
54
-		$this->path = $path;
55
-	}
47
+    /**
48
+     * Sets the path to the project directory from which this task will read.
49
+     *
50
+     * @param      PhingFile Path to the project directory.
51
+     */
52
+    public function setPath(PhingFile $path)
53
+    {
54
+        $this->path = $path;
55
+    }
56 56
 	
57
-	/**
58
-	 * Executes this task.
59
-	 */
60
-	public function main()
61
-	{
62
-		if($this->property === null) {
63
-			throw new BuildException('The property attribute must be specified');
64
-		}
65
-		if($this->path === null) {
66
-			throw new BuildException('The path attribute must be specified');
67
-		}
57
+    /**
58
+     * Executes this task.
59
+     */
60
+    public function main()
61
+    {
62
+        if($this->property === null) {
63
+            throw new BuildException('The property attribute must be specified');
64
+        }
65
+        if($this->path === null) {
66
+            throw new BuildException('The path attribute must be specified');
67
+        }
68 68
 		
69
-		$check = new \Agavi\Build\Check\ModuleFilesystemCheck();
70
-		$check->setConfigDirectory($this->project->getProperty('module.config.directory'));
69
+        $check = new \Agavi\Build\Check\ModuleFilesystemCheck();
70
+        $check->setConfigDirectory($this->project->getProperty('module.config.directory'));
71 71
 		
72
-		$check->setPath($this->path->getAbsolutePath());
73
-		if(!$check->check()) {
74
-			throw new BuildException('The path attribute must be a valid module base directory');
75
-		}
72
+        $check->setPath($this->path->getAbsolutePath());
73
+        if(!$check->check()) {
74
+            throw new BuildException('The path attribute must be a valid module base directory');
75
+        }
76 76
 		
77
-		/* We don't know whether the module is configured or not here, so load the
77
+        /* We don't know whether the module is configured or not here, so load the
78 78
 		 * values we want properly. */
79
-		$this->tryLoadAgavi();
80
-		$this->tryBootstrapAgavi();
79
+        $this->tryLoadAgavi();
80
+        $this->tryBootstrapAgavi();
81 81
 
82
-		require_once(\Agavi\Config\ConfigCache::checkConfig(
83
-			sprintf('%s/%s/module.xml',
84
-				$this->path->getAbsolutePath(),
85
-				(string)$this->project->getProperty('module.config.directory')
86
-			)
87
-		));
82
+        require_once(\Agavi\Config\ConfigCache::checkConfig(
83
+            sprintf('%s/%s/module.xml',
84
+                $this->path->getAbsolutePath(),
85
+                (string)$this->project->getProperty('module.config.directory')
86
+            )
87
+        ));
88 88
 		
89
-		$controllerPath = \Agavi\Util\Toolkit::expandVariables(
90
-			\Agavi\Util\Toolkit::expandDirectives(\Agavi\Config\Config::get(
91
-				sprintf('modules.%s.agavi.controller.path', strtolower($this->path->getName())),
92
-				'%core.module_dir%/${moduleName}/controllers/${controllerName}Controller.class.php'
93
-			)),
94
-			array(
95
-				'moduleName' => $this->path->getName()
96
-			)
97
-		);
98
-		$pattern = '#^' . \Agavi\Util\Toolkit::expandVariables(
99
-			/* Blaaaaaaaaauuuuuughhhhhhh... */
100
-			str_replace('\\$\\{controllerName\\}', '${controllerName}', preg_quote($controllerPath, '#')),
101
-			array('controllerName' => '(?P<controller_name>.*?)')
102
-		) . '$#';
89
+        $controllerPath = \Agavi\Util\Toolkit::expandVariables(
90
+            \Agavi\Util\Toolkit::expandDirectives(\Agavi\Config\Config::get(
91
+                sprintf('modules.%s.agavi.controller.path', strtolower($this->path->getName())),
92
+                '%core.module_dir%/${moduleName}/controllers/${controllerName}Controller.class.php'
93
+            )),
94
+            array(
95
+                'moduleName' => $this->path->getName()
96
+            )
97
+        );
98
+        $pattern = '#^' . \Agavi\Util\Toolkit::expandVariables(
99
+            /* Blaaaaaaaaauuuuuughhhhhhh... */
100
+            str_replace('\\$\\{controllerName\\}', '${controllerName}', preg_quote($controllerPath, '#')),
101
+            array('controllerName' => '(?P<controller_name>.*?)')
102
+        ) . '$#';
103 103
 		
104
-		$controllers = array();
105
-		$iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($this->path->getAbsolutePath()));
106
-		for(; $iterator->valid(); $iterator->next()) {
107
-			$rdi = $iterator->getInnerIterator();
108
-			if($rdi->isDot() || !$rdi->isFile()) {
109
-				continue;
110
-			}
104
+        $controllers = array();
105
+        $iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($this->path->getAbsolutePath()));
106
+        for(; $iterator->valid(); $iterator->next()) {
107
+            $rdi = $iterator->getInnerIterator();
108
+            if($rdi->isDot() || !$rdi->isFile()) {
109
+                continue;
110
+            }
111 111
 			
112
-			$file = $rdi->getPathname();
113
-			if(preg_match($pattern, $file, $matches)) {
114
-				$controllers[] = str_replace(DIRECTORY_SEPARATOR, '.', $matches['controller_name']);
115
-			}
116
-		}
112
+            $file = $rdi->getPathname();
113
+            if(preg_match($pattern, $file, $matches)) {
114
+                $controllers[] = str_replace(DIRECTORY_SEPARATOR, '.', $matches['controller_name']);
115
+            }
116
+        }
117 117
 		
118
-		$list = new \Agavi\Build\Transform\ArraytostringTransform();
119
-		$list->setInput($controllers);
120
-		$list->setDelimiter(' ');
118
+        $list = new \Agavi\Build\Transform\ArraytostringTransform();
119
+        $list->setInput($controllers);
120
+        $list->setDelimiter(' ');
121 121
 		
122
-		$this->project->setUserProperty($this->property, $list->transform());
123
-	}
122
+        $this->project->setUserProperty($this->property, $list->transform());
123
+    }
124 124
 }
125 125
 
126 126
 ?>
127 127
\ No newline at end of file
Please login to merge, or discard this patch.