Dispatcher::dispatch()   F
last analyzed

Complexity

Conditions 11
Paths 333

Size

Total Lines 77
Code Lines 40

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 11
eloc 40
nc 333
nop 2
dl 0
loc 77
rs 3.9252
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
// +---------------------------------------------------------------------------+
4
// | This file is part of the Agavi package.                                   |
5
// | Copyright (c) 2005-2011 the Agavi Project.                                |
6
// | Based on the Mojavi3 MVC Framework, Copyright (c) 2003-2005 Sean Kerr.    |
7
// |                                                                           |
8
// | For the full copyright and license information, please view the LICENSE   |
9
// | file that was distributed with this source code. You can also view the    |
10
// | LICENSE file online at http://www.agavi.org/LICENSE.txt                   |
11
// |   vi: set noexpandtab:                                                    |
12
// |   Local Variables:                                                        |
13
// |   indent-tabs-mode: t                                                     |
14
// |   End:                                                                    |
15
// +---------------------------------------------------------------------------+
16
17
namespace Agavi\Dispatcher;
18
19
use Agavi\Controller\Controller;
20
use Agavi\Config\Config;
21
use Agavi\Config\ConfigCache;
22
use Agavi\Exception\AgaviException;
23
use Agavi\Exception\ClassNotFoundException;
24
use Agavi\Exception\FileNotFoundException;
25
use Agavi\Filter\FilterChain;
26
use Agavi\Filter\Filter;
27
use Agavi\Request\RequestDataHolder;
28
use Agavi\Response\Response;
29
use Agavi\Util\ParameterHolder;
30
use Agavi\Exception\DispatcherException;
31
use Agavi\Core\Context;
32
use Agavi\Exception\DisabledModuleException;
33
use Agavi\Util\Toolkit;
34
use Agavi\View\View;
35
36
/**
37
 * Dispatcher directs application flow.
38
 *
39
 * @package    agavi
40
 * @subpackage Dispatcher
41
 *
42
 * @author     Sean Kerr <[email protected]>
43
 * @author     David Zülke <[email protected]>
44
 * @copyright  Authors
45
 * @copyright  The Agavi Project
46
 *
47
 * @since      0.9.0
48
 *
49
 * @version    $Id$
50
 */
51
class Dispatcher extends ParameterHolder
52
{
53
    /**
54
     * @var        int The number of execution containers run so far.
55
     */
56
    protected $numExecutions = 0;
57
    
58
    /**
59
     * @var        Context An Context instance.
60
     */
61
    protected $context = null;
62
    
63
    /**
64
     * @var        Response The global response.
65
     */
66
    protected $response = null;
67
    
68
    /**
69
     * @var        FilterChain The global filter chain.
70
     */
71
    protected $filterChain = null;
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
    );
85
    
86
    /**
87
     * @var        string The default Output Type.
88
     */
89
    protected $defaultOutputType = null;
90
    
91
    /**
92
     * @var        array An array of registered Output Types.
93
     */
94
    protected $outputTypes = array();
95
    
96
    /**
97
     * @var        array Ref to the request data object from the request.
98
     */
99
    private $requestData = null;
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');
113
        
114
        if (++$this->numExecutions > $maxExecutions && $maxExecutions > 0) {
115
            throw new DispatcherException('Too many execution runs have been detected for this Context.');
116
        }
117
    }
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
140
        /** @var ExecutionContainer $container */
141
        $container = $this->context->createInstanceFor('execution_container');
142
        $container->setModuleName($moduleName);
143
        $container->setControllerName($controllerName);
144
        $container->setRequestData($this->requestData);
0 ignored issues
show
Documentation introduced by
$this->requestData is of type array, but the function expects a object<Agavi\Request\RequestDataHolder>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
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
    
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
        
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
            
186
            $moduleAutoload = Config::get('core.module_dir') . '/' . $moduleName . '/config/autoload.xml';
187
            if (is_readable($moduleAutoload)) {
188
                ConfigCache::load($moduleAutoload);
189
            }
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
        }
198
        
199
        if (!Config::get('modules.' . $lowerModuleName . '.enabled')) {
200
            throw new DisabledModuleException(sprintf('The module "%1$s" is disabled.', $moduleName));
201
        }
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
    }
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 {
227
            $rq = $this->context->getRequest();
228
            $rd = $rq->getRequestData();
229
            
230
            if ($container === null) {
231
                // match routes and assign returned initial execution container
232
                $container = $this->context->getRouting()->execute();
233
            }
234
            
235
            if ($container instanceof ExecutionContainer) {
236
                // merge in any arguments given. they need to have precedence over what the routing found
237
                if ($arguments !== null) {
238
                    $rd->merge($arguments);
239
                }
240
                
241
                // next, we have to see if the routing did anything useful, i.e. whether or not it was enabled.
242
                $moduleName = $container->getModuleName();
243
                $controllerName = $container->getControllerName();
244
                if (!$moduleName) {
245
                    // no module has been specified; that means the routing did not run, as it would otherwise have the 404 controller's module name
246
                    
247
                    // lets see if our request data has values for module and controller
248
                    $ma = $rq->getParameter('module_accessor');
249
                    $aa = $rq->getParameter('controller_accessor');
250
                    if ($rd->hasParameter($ma) && $rd->hasParameter($aa)) {
251
                        // yup. grab those
252
                        $moduleName = $rd->getParameter($ma);
253
                        $controllerName = $rd->getParameter($aa);
254
                    } else {
255
                        // nope. then its time for the default controller
256
                        $moduleName = Config::get('controllers.default_module');
257
                        $controllerName = Config::get('controllers.default_controller');
258
                    }
259
                    
260
                    // so by now we hopefully have something reasonable for module and controller names - let's set them on the container
261
                    $container->setModuleName($moduleName);
262
                    $container->setControllerName($controllerName);
263
                }
264
                
265
                if (!Config::get('core.available', false)) {
0 ignored issues
show
Documentation introduced by
false is of type boolean, but the function expects a string|null.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
266
                    $container = $container->createSystemControllerForwardContainer('unavailable');
267
                }
268
                
269
                // create a new filter chain
270
                /** @var FilterChain $filterChain */
271
                $filterChain = $this->getFilterChain();
272
                
273
                $this->loadFilters($filterChain, 'global');
274
                
275
                // register the dispatch filter
276
                $filterChain->register($this->filters['dispatch'], 'agavi_dispatch_filter');
277
                
278
                // go, go, go!
279
                $filterChain->execute($container);
280
                
281
                $response = $container->getResponse();
282
            } elseif ($container instanceof Response) {
283
                // the routing returned a response!
284
                $response = $container;
285
                // set $container to null so Exception::render() won't think it is a container if an exception happens later!
286
                $container = null;
287
            } else {
288
                throw new AgaviException('AgaviRouting::execute() returned neither ExecutionContainer nor Response object.');
289
            }
290
            $response->merge($this->response);
291
            
292
            if ($this->getParameter('send_response')) {
293
                $response->send();
294
            }
295
            
296
            return $response;
297
        } catch (\Exception $e) {
298
            AgaviException::render($e, $this->context, $container);
0 ignored issues
show
Bug introduced by
It seems like $container defined by $this->context->getRouting()->execute() on line 232 can also be of type object<Agavi\Response\Response>; however, Agavi\Exception\AgaviException::render() does only seem to accept null|object<Agavi\Dispatcher\ExecutionContainer>, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
299
        }
300
    }
301
    
302
    /**
303
     * Get the global response instance.
304
     *
305
     * @return     Response The global response.
306
     *
307
     * @author     David Zülke <[email protected]>
308
     * @since      0.11.0
309
     */
310
    public function getGlobalResponse()
311
    {
312
        return $this->response;
313
    }
314
    
315
    
316
    /**
317
     * Indicates whether or not a module has a specific controller file.
318
     *
319
     * Please note that this is only a cursory check and does not
320
     * check whether the file actually contains the proper class
321
     *
322
     * @param      string $moduleName A module name.
323
     * @param      string $controllerName An controller name.
324
     *
325
     * @return     string|false  the path to the controller file if the controller file
326
     *                    exists and is readable, false in any other case
327
     *
328
     * @author     Felix Gilcher <[email protected]>
329
     * @since      1.0.0
330
     */
331 View Code Duplication
    public function checkControllerFile($moduleName, $controllerName)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
332
    {
333
        $this->initializeModule($moduleName);
334
335
336
        $controllerName = Toolkit::canonicalName(Toolkit::stripNamespace($controllerName));
337
        $file = Toolkit::evaluateModuleDirective(
338
            $moduleName,
339
            'agavi.controller.path',
340
            array(
341
                'moduleName' => $moduleName,
342
                'controllerName' => $controllerName,
343
            )
344
        );
345
        
346
        if (is_readable($file) && substr($controllerName, 0, 1) !== '/') {
347
            return $file;
348
        }
349
        return false;
350
    }
351
    
352
    /**
353
     * Retrieve an Controller implementation instance.
354
     *
355
     * @param      string $moduleName A module name.
356
     * @param      string $controllerName An controller name.
357
     *
358
     * @return     Controller An Controller implementation instance
359
     *
360
     * @throws     FileNotFoundException|ClassNotFoundException if the controller could not be found.
361
     *
362
     * @author     Sean Kerr <[email protected]>
363
     * @author     Mike Vincent <[email protected]>
364
     * @author     David Zülke <[email protected]>
365
     * @since      0.9.0
366
     */
367
    public function createControllerInstance($moduleName, $controllerName)
368
    {
369
        $this->initializeModule($moduleName);
370
        
371
372
        $longControllerName = str_replace('/', '\\', Toolkit::canonicalName(Toolkit::stripNamespace($controllerName)));
373
        $ns = Config::get('app.namespace');
374
375
        if (strlen($ns) > 0) {
376
            $ns .= '\\Modules\\' . $moduleName . '\\Controllers\\';
377
        }
378
        $class = $ns . $longControllerName . 'Controller';
379
        if (!class_exists($class)) {
380
            if (false !== ($file = $this->checkControllerFile($moduleName, $controllerName))) {
381
                require($file);
382
            } else {
383
                throw new FileNotFoundException(sprintf('Could not find file for Controller "%s" in Module "%s".', $controllerName, $moduleName));
384
            }
385
            
386
            if (!class_exists($class, false)) {
387
                throw new ClassNotFoundException(sprintf('Failed to instantiate Controller "%s" in Module "%s" because file "%s" does not contain class "%s".', $controllerName, $moduleName, $file, $class));
388
            }
389
        }
390
        
391
        return new $class();
392
    }
393
394
    /**
395
     * Retrieve the current application context.
396
     *
397
     * @return     Context An Context instance.
398
     *
399
     * @author     Sean Kerr <[email protected]>
400
     * @since      0.9.0
401
     */
402
    final public function getContext()
403
    {
404
        return $this->context;
405
    }
406
407
408
    
409
    /**
410
     * Indicates whether or not a module has a specific view file.
411
     *
412
     * Please note that this is only a cursory check and does not
413
     * check whether the file actually contains the proper class
414
     *
415
     * @param      string $moduleName A module name.
416
     * @param      string $viewName A view name.
417
     *
418
     * @return     string|false  the path to the view file if the view file
419
     *                    exists and is readable, false in any other case
420
     *
421
     * @author     Felix Gilcher <[email protected]>
422
     * @since      1.0.0
423
     */
424 View Code Duplication
    public function checkViewFile($moduleName, $viewName)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
425
    {
426
        $this->initializeModule($moduleName);
427
        
428
        $viewName = Toolkit::canonicalName(Toolkit::stripNamespace($viewName));
429
        $file = Toolkit::evaluateModuleDirective(
430
            $moduleName,
431
            'agavi.view.path',
432
            array(
433
                'moduleName' => $moduleName,
434
                'viewName' => $viewName,
435
            )
436
        );
437
        
438
        if (is_readable($file) && substr($viewName, 0, 1) !== '/') {
439
            return $file;
440
        }
441
        
442
        return false;
443
    }
444
    
445
    /**
446
     * Retrieve a View implementation instance.
447
     *
448
     * @param      string $moduleName A module name.
449
     * @param      string $viewName A view name.
450
     *
451
     * @return     View A View implementation instance,
452
     *
453
     * @throws     AgaviException if the view could not be found.
454
     *
455
     * @author     Sean Kerr <[email protected]>
456
     * @author     Mike Vincent <[email protected]>
457
     * @author     David Zülke <[email protected]>
458
     * @since      0.9.0
459
     */
460
    public function createViewInstance($moduleName, $viewName)
461
    {
462
        try {
463
            $this->initializeModule($moduleName);
464
        } catch (DisabledModuleException $e) {
465
            // views from disabled modules should be usable by definition
466
            // swallow
467
        }
468
469
        $longViewName = str_replace('/', '\\', Toolkit::canonicalName(Toolkit::stripNamespace($viewName)));
470
        $ns = Config::get('app.namespace');
471
472
        if (strlen($ns) > 0 && strrpos($ns, '\\') !== strlen($ns)) {
473
            $ns .= '\\Modules\\' . $moduleName . '\\Views\\';
474
        }
475
        $class = $ns . $longViewName . 'View';
476
        
477
        if (!class_exists($class)) {
478
            if (false !== ($file = $this->checkViewFile($moduleName, $viewName))) {
479
                require($file);
480
            } else {
481
                throw new FileNotFoundException(sprintf('Could not find file for View "%s" in Module "%s".', $viewName, $moduleName));
482
            }
483
            
484
            if (!class_exists($class, false)) {
485
                throw new ClassNotFoundException(sprintf('Failed to instantiate View "%s" in Module "%s" because file "%s" does not contain class "%s".', $viewName, $moduleName, $file, $class));
486
            }
487
        }
488
        
489
        return new $class();
490
    }
491
492
    /**
493
     * Constructor.
494
     *
495
     * @author     David Zülke <[email protected]>
496
     * @since      0.11.0
497
     */
498
    public function __construct()
499
    {
500
        parent::__construct();
501
        $this->setParameters(array(
502
            'max_executions' => 20,
503
            'send_response' => true,
504
        ));
505
    }
506
    
507
    /**
508
     * Initialize this Dispatcher.
509
     *
510
     * @param      Context $context A Context instance.
511
     * @param      array   $parameters An array of initialization parameters.
512
     *
513
     * @author     David Zülke <[email protected]>
514
     * @since      0.9.0
515
     */
516
    public function initialize(Context $context, array $parameters = array())
517
    {
518
        $this->context = $context;
519
        
520
        $this->setParameters($parameters);
521
        
522
        $this->response = $this->context->createInstanceFor('response');
523
        
524
        $cfg = Config::get('core.config_dir') . '/output_types.xml';
525
        require(ConfigCache::checkConfig($cfg, $this->context->getName()));
526
        
527
        if (Config::get('core.use_security', false)) {
0 ignored issues
show
Documentation introduced by
false is of type boolean, but the function expects a string|null.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
528
            $this->filters['security'] = $this->context->createInstanceFor('security_filter');
529
        }
530
        
531
        $this->filters['dispatch'] = $this->context->createInstanceFor('dispatch_filter');
532
        
533
        $this->filters['execution'] = $this->context->createInstanceFor('execution_filter');
534
    }
535
    
536
    /**
537
     * Get a filter.
538
     *
539
     * @param      string $which The name of the filter list section.
540
     *
541
     * @return     Filter A filter instance, or null.
542
     *
543
     * @author     David Zülke <[email protected]>
544
     * @since      0.11.0
545
     */
546
    public function getFilter($which)
547
    {
548
        return (isset($this->filters[$which]) ? $this->filters[$which] : null);
549
    }
550
    
551
    /**
552
     * Get the global filter chain.
553
     *
554
     * @return     FilterChain The global filter chain.
555
     *
556
     * @author     David Zülke <[email protected]>
557
     * @since      1.1.0
558
     */
559 View Code Duplication
    public function getFilterChain()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
560
    {
561
        if ($this->filterChain === null) {
562
            $this->filterChain = $this->context->createInstanceFor('filter_chain');
563
            $this->filterChain->setType(FilterChain::TYPE_GLOBAL);
564
        }
565
        
566
        return $this->filterChain;
567
    }
568
    
569
    /**
570
     * Load filters.
571
     *
572
     * @param      FilterChain $filterChain A FilterChain instance.
573
     * @param      string      $which "global" or "controller".
574
     * @param      string      $module A module name, or "*" for the generic config.
575
     *
576
     * @author     David Zülke <[email protected]>
577
     * @since      0.11.0
578
     */
579
    public function loadFilters(FilterChain $filterChain, $which = 'global', $module = null)
580
    {
581
        if ($module === null) {
582
            $module = '*';
583
        }
584
        
585
        if (($which != 'global' && !isset($this->filters[$which][$module])) || $which == 'global' && $this->filters[$which] == null) {
586
            if ($which == 'global') {
587
                $this->filters[$which] = array();
588
                $filters =& $this->filters[$which];
589 View Code Duplication
            } else {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
590
                $this->filters[$which][$module] = array();
591
                $filters =& $this->filters[$which][$module];
592
            }
593
            $config = ($module == '*' ? Config::get('core.config_dir') : Config::get('core.module_dir') . '/' . $module . '/config') . '/' . $which . '_filters.xml';
594
            if (is_readable($config)) {
595
                require(ConfigCache::checkConfig($config, $this->context->getName()));
596
            }
597 View Code Duplication
        } else {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
598
            if ($which == 'global') {
599
                $filters =& $this->filters[$which];
600
            } else {
601
                $filters =& $this->filters[$which][$module];
602
            }
603
        }
604
        
605
        foreach ($filters as $name => $filter) {
606
            $filterChain->register($filter, $name);
607
        }
608
    }
609
610
    /**
611
     * Indicates whether or not a module has a specific model.
612
     *
613
     * @param      string $moduleName A module name.
614
     * @param      string $modelName A model name.
615
     *
616
     * @return     bool true, if the model exists, otherwise false.
617
     *
618
     * @author     Sean Kerr <[email protected]>
619
     * @since      0.9.0
620
     */
621
    public function modelExists($moduleName, $modelName)
622
    {
623
        $modelName = Toolkit::canonicalName($modelName);
624
        $file = Config::get('core.module_dir') . '/' . $moduleName . '/models/' . $modelName .  'Model.class.php';
625
        return is_readable($file);
626
    }
627
628
    /**
629
     * Indicates whether or not a module exists.
630
     *
631
     * @param      string $moduleName A module name.
632
     *
633
     * @return     bool true, if the module exists, otherwise false.
634
     *
635
     * @author     Sean Kerr <[email protected]>
636
     * @since      0.9.0
637
     */
638
    public function moduleExists($moduleName)
639
    {
640
        $file = Config::get('core.module_dir') . '/' . $moduleName . '/config/module.xml';
641
        return is_readable($file);
642
    }
643
644
    /**
645
     * Do any necessary startup work after initialization.
646
     *
647
     * This method is not called directly after initialize().
648
     *
649
     * @author     David Zülke <[email protected]>
650
     * @since      0.11.0
651
     */
652
    public function startup()
653
    {
654
        // grab a pointer to the request data
655
        $this->requestData = $this->context->getRequest()->getRequestData();
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->context->getRequest()->getRequestData() of type object<Agavi\Request\RequestDataHolder> is incompatible with the declared type array of property $requestData.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
656
    }
657
658
    /**
659
     * Execute the shutdown procedure for this Dispatcher.
660
     *
661
     * @author     Sean Kerr <[email protected]>
662
     * @since      0.9.0
663
     */
664
    public function shutdown()
665
    {
666
    }
667
668
    /**
669
     * Indicates whether or not a module has a specific controller.
670
     *
671
     * @param      string $moduleName A module name.
672
     * @param      string $controllerName A view name.
673
     *
674
     * @return     bool true, if the controller exists, otherwise false.
675
     *
676
     * @author     David Zülke <[email protected]>
677
     * @since      1.0.1
678
     */
679
    public function controllerExists($moduleName, $controllerName)
680
    {
681
        return $this->checkControllerFile($moduleName, $controllerName) !== false;
682
    }
683
684
    /**
685
     * Indicates whether or not a module has a specific view.
686
     *
687
     * @param      string $moduleName A module name.
688
     * @param      string $viewName A view name.
689
     *
690
     * @return     bool true, if the view exists, otherwise false.
691
     *
692
     * @author     Sean Kerr <[email protected]>
693
     * @since      0.9.0
694
     */
695
    public function viewExists($moduleName, $viewName)
696
    {
697
        return $this->checkViewFile($moduleName, $viewName) !== false;
698
    }
699
    
700
    /**
701
     * Retrieve an Output Type object
702
     *
703
     * @param      string $name The optional output type name.
704
     *
705
     * @return     OutputType An Output Type object.
706
     *
707
     * @author     David Zülke <[email protected]>
708
     * @since      0.11.0
709
     */
710 View Code Duplication
    public function getOutputType($name = null)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
711
    {
712
        if ($name === null) {
713
            $name = $this->defaultOutputType;
714
        }
715
        if (isset($this->outputTypes[$name])) {
716
            return $this->outputTypes[$name];
717
        } else {
718
            throw new AgaviException('Output Type "' . $name . '" has not been configured.');
719
        }
720
    }
721
}
722