Source of file Dispatcher.php

Size: 4,787 Bytes - Last Modified: 2015-12-22T09:12:14-05:00

../src/Dispatcher.php

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051
Covered by 3 test(s):
  • MvcLite\DispatcherTest::testInit
  • MvcLite\DispatcherTest::testDispatch with data set "good controller request"
  • MvcLite\DispatcherTest::testDispatch with data set "bad controller request"
52
Covered by 3 test(s):
  • MvcLite\DispatcherTest::testInit
  • MvcLite\DispatcherTest::testDispatch with data set "good controller request"
  • MvcLite\DispatcherTest::testDispatch with data set "bad controller request"
53
Covered by 3 test(s):
  • MvcLite\DispatcherTest::testInit
  • MvcLite\DispatcherTest::testDispatch with data set "good controller request"
  • MvcLite\DispatcherTest::testDispatch with data set "bad controller request"
54
Covered by 3 test(s):
  • MvcLite\DispatcherTest::testInit
  • MvcLite\DispatcherTest::testDispatch with data set "good controller request"
  • MvcLite\DispatcherTest::testDispatch with data set "bad controller request"
5556
Covered by 3 test(s):
  • MvcLite\DispatcherTest::testInit
  • MvcLite\DispatcherTest::testDispatch with data set "good controller request"
  • MvcLite\DispatcherTest::testDispatch with data set "bad controller request"
57585960616263646566
Covered by 2 test(s):
  • MvcLite\DispatcherTest::testDispatch with data set "good controller request"
  • MvcLite\DispatcherTest::testDispatch with data set "bad controller request"
67
Covered by 2 test(s):
  • MvcLite\DispatcherTest::testDispatch with data set "good controller request"
  • MvcLite\DispatcherTest::testDispatch with data set "bad controller request"
68
Covered by 2 test(s):
  • MvcLite\DispatcherTest::testDispatch with data set "good controller request"
  • MvcLite\DispatcherTest::testDispatch with data set "bad controller request"
69
Covered by 2 test(s):
  • MvcLite\DispatcherTest::testDispatch with data set "good controller request"
  • MvcLite\DispatcherTest::testDispatch with data set "bad controller request"
70
Covered by 2 test(s):
  • MvcLite\DispatcherTest::testDispatch with data set "good controller request"
  • MvcLite\DispatcherTest::testDispatch with data set "bad controller request"
71
Covered by 2 test(s):
  • MvcLite\DispatcherTest::testDispatch with data set "good controller request"
  • MvcLite\DispatcherTest::testDispatch with data set "bad controller request"
72
Covered by 2 test(s):
  • MvcLite\DispatcherTest::testDispatch with data set "good controller request"
  • MvcLite\DispatcherTest::testDispatch with data set "bad controller request"
73
Covered by 2 test(s):
  • MvcLite\DispatcherTest::testDispatch with data set "good controller request"
  • MvcLite\DispatcherTest::testDispatch with data set "bad controller request"
747576777879
Covered by 2 test(s):
  • MvcLite\DispatcherTest::testDispatch with data set "good controller request"
  • MvcLite\DispatcherTest::testDispatch with data set "bad controller request"
8081
Covered by 2 test(s):
  • MvcLite\DispatcherTest::testDispatch with data set "good controller request"
  • MvcLite\DispatcherTest::testDispatch with data set "bad controller request"
82
Covered by 1 test(s):
  • MvcLite\DispatcherTest::testDispatch with data set "bad controller request"
83848586
Covered by 1 test(s):
  • MvcLite\DispatcherTest::testDispatch with data set "good controller request"
87
Covered by 1 test(s):
  • MvcLite\DispatcherTest::testDispatch with data set "good controller request"
88
Covered by 1 test(s):
  • MvcLite\DispatcherTest::testDispatch with data set "good controller request"
8990
Covered by 2 test(s):
  • MvcLite\DispatcherTest::testDispatch with data set "good controller request"
  • MvcLite\DispatcherTest::testDispatch with data set "bad controller request"
91
Covered by 2 test(s):
  • MvcLite\DispatcherTest::testDispatch with data set "good controller request"
  • MvcLite\DispatcherTest::testDispatch with data set "bad controller request"
92
Covered by 2 test(s):
  • MvcLite\DispatcherTest::testDispatch with data set "good controller request"
  • MvcLite\DispatcherTest::testDispatch with data set "bad controller request"
93
Covered by 2 test(s):
  • MvcLite\DispatcherTest::testDispatch with data set "good controller request"
  • MvcLite\DispatcherTest::testDispatch with data set "bad controller request"
94
Covered by 2 test(s):
  • MvcLite\DispatcherTest::testDispatch with data set "good controller request"
  • MvcLite\DispatcherTest::testDispatch with data set "bad controller request"
95969798
Covered by 2 test(s):
  • MvcLite\DispatcherTest::testDispatch with data set "good controller request"
  • MvcLite\DispatcherTest::testDispatch with data set "bad controller request"
99100101
Covered by 2 test(s):
  • MvcLite\DispatcherTest::testDispatch with data set "good controller request"
  • MvcLite\DispatcherTest::testDispatch with data set "bad controller request"
102103104
Covered by 2 test(s):
  • MvcLite\DispatcherTest::testDispatch with data set "good controller request"
  • MvcLite\DispatcherTest::testDispatch with data set "bad controller request"
105106107
Covered by 2 test(s):
  • MvcLite\DispatcherTest::testDispatch with data set "good controller request"
  • MvcLite\DispatcherTest::testDispatch with data set "bad controller request"
108
Covered by 2 test(s):
  • MvcLite\DispatcherTest::testDispatch with data set "good controller request"
  • MvcLite\DispatcherTest::testDispatch with data set "bad controller request"
109
Covered by 2 test(s):
  • MvcLite\DispatcherTest::testDispatch with data set "good controller request"
  • MvcLite\DispatcherTest::testDispatch with data set "bad controller request"
110
Covered by 2 test(s):
  • MvcLite\DispatcherTest::testDispatch with data set "good controller request"
  • MvcLite\DispatcherTest::testDispatch with data set "bad controller request"
111
Covered by 2 test(s):
  • MvcLite\DispatcherTest::testDispatch with data set "good controller request"
  • MvcLite\DispatcherTest::testDispatch with data set "bad controller request"
112113
Covered by 2 test(s):
  • MvcLite\DispatcherTest::testDispatch with data set "good controller request"
  • MvcLite\DispatcherTest::testDispatch with data set "bad controller request"
114
Covered by 2 test(s):
  • MvcLite\DispatcherTest::testDispatch with data set "good controller request"
  • MvcLite\DispatcherTest::testDispatch with data set "bad controller request"
115116117
Covered by 2 test(s):
  • MvcLite\DispatcherTest::testDispatch with data set "good controller request"
  • MvcLite\DispatcherTest::testDispatch with data set "bad controller request"
118119120
Covered by 2 test(s):
  • MvcLite\DispatcherTest::testDispatch with data set "good controller request"
  • MvcLite\DispatcherTest::testDispatch with data set "bad controller request"
121
Covered by 2 test(s):
  • MvcLite\DispatcherTest::testDispatch with data set "good controller request"
  • MvcLite\DispatcherTest::testDispatch with data set "bad controller request"
122123124125126127128129130
Covered by 2 test(s):
  • MvcLite\DispatcherTest::testDispatch with data set "good controller request"
  • MvcLite\DispatcherTest::testDispatch with data set "bad controller request"
131
Covered by 2 test(s):
  • MvcLite\DispatcherTest::testDispatch with data set "good controller request"
  • MvcLite\DispatcherTest::testDispatch with data set "bad controller request"
132
Covered by 2 test(s):
  • MvcLite\DispatcherTest::testDispatch with data set "good controller request"
  • MvcLite\DispatcherTest::testDispatch with data set "bad controller request"
133
Covered by 2 test(s):
  • MvcLite\DispatcherTest::testDispatch with data set "good controller request"
  • MvcLite\DispatcherTest::testDispatch with data set "bad controller request"
134
Covered by 2 test(s):
  • MvcLite\DispatcherTest::testDispatch with data set "good controller request"
  • MvcLite\DispatcherTest::testDispatch with data set "bad controller request"
135136137138139140141142143144
Covered by 2 test(s):
  • MvcLite\DispatcherTest::testTranslateControllerName with data set "simple"
  • MvcLite\DispatcherTest::testTranslateControllerName with data set "with dashes"
145
Covered by 2 test(s):
  • MvcLite\DispatcherTest::testTranslateControllerName with data set "simple"
  • MvcLite\DispatcherTest::testTranslateControllerName with data set "with dashes"
146
Covered by 2 test(s):
  • MvcLite\DispatcherTest::testTranslateControllerName with data set "simple"
  • MvcLite\DispatcherTest::testTranslateControllerName with data set "with dashes"
147148149150151152153154155156157158
Covered by 2 test(s):
  • MvcLite\DispatcherTest::testTranslateActionName with data set "simple"
  • MvcLite\DispatcherTest::testTranslateActionName with data set "with dashes"
159
Covered by 2 test(s):
  • MvcLite\DispatcherTest::testTranslateActionName with data set "simple"
  • MvcLite\DispatcherTest::testTranslateActionName with data set "with dashes"
160
Covered by 2 test(s):
  • MvcLite\DispatcherTest::testTranslateActionName with data set "simple"
  • MvcLite\DispatcherTest::testTranslateActionName with data set "with dashes"
161162163
<?php
/**
 * Base Dispatcher
 *
 * @category    PHP
 * @package     MvcLite
 * @subpackage  Dispatcher
 * @since       File available since release 1.0.1
 * @author      Cory Collier <corycollier@corycollier.com>
 */

namespace MvcLite;

use MvcLite\Traits\Config as ConfigTrait;
use MvcLite\Traits\Request as RequestTrait;
use MvcLite\Traits\Response as ResponseTrait;
use MvcLite\Traits\Session as SessionTrait;
use MvcLite\Traits\Singleton as SingletonTrait;
use MvcLite\Traits\Filepath as FilepathTrait;
use MvcLite\Traits\Loader as LoaderTrait;
use MvcLite\Traits\FilterChain as FilterChainTrait;

/**
 * Base Dispatcher
 *
 * @category    PHP
 * @package     MvcLite
 * @subpackage  Dispatcher
 * @since       Class available since release 1.0.1
 * @author      Cory Collier <corycollier@corycollier.com>
 */

class Dispatcher extends ObjectAbstract
{
    use ConfigTrait;
    use RequestTrait;
    use ResponseTrait;
    use SessionTrait;
    use SingletonTrait;
    use FilepathTrait;
    use LoaderTrait;
    use FilterChainTrait;

    /**
     * Initialize the dispatcher.
     *
     * @return MvcLite\Dispatcher Returns $this for object-chaining.
     */
    public function init($loader)
    {
        $this->setLoader($loader);
        $this->getConfig()->init($this->filepath(CONFIG_PATH . '/app.ini'));
        $this->getRequest()->init();
        $this->getResponse()->init();

        return $this;
    }

    /**
     * dispatch
     *
     * This is the main entry point for dispatching a request
     */
    public function dispatch()
    {
        $request     = $this->getRequest();
        $params      = $request->getParams();
        $controller  = $this->translateControllerName($params['controller']);
        $action      = $this->translateActionName($params['action']);
        $response    = $this->getResponse();
        $loader      = $this->getLoader();
        $contentType = $request->getContentType();
        $format      = $request->getFormat($contentType);

        // If the controller doesn't exist, or the action isn't callable,
        // use the error controller
        try {
            // First, make sure the controller is callable.
            $result = $loader->loadClass($controller);

            if (is_null($result)) {
                throw new Exception('Invalid controller specified');
            }

            // Now, instantiate the controller and try to run it's action.
            $controller = new $controller;
            if (! method_exists($controller, $action)) {
                throw new Exception('Action not available');
            }
        } catch (Exception $exception) {
            $this->handleDispatchException($exception);
            $controller = new \App\ErrorController;
            $action = 'errorAction';
            $controller->getView()->set('error', $exception);
        }

        // run the init hook
        $controller->init()->preDispatch();

        // run the requested action on the requested controller
        call_user_func([$controller, $action]);

        // run the postDispatch hook
        $controller->postDispatch();

        // send the response
        $body = $controller->getView()
            ->init()
            ->setLoader($loader)
            ->setFormat($format)
            ->render();

        $response->setContentType($request->getContentType());
        $response->setBody($body);

        // if this is an actual request, not a unit test, send headers
        $response->sendHeaders();

        // echo the body
        echo $response->getBody();
    }

    /**
     * Handle exceptions that occur during dispatch.
     *
     * @param  MvcLite\Exception $exception The exception that was thrown.
     */
    protected function handleDispatchException($exception)
    {
        $request = $this->getRequest();
        $request->setParam('controller', 'error');
        $request->setParam('action', 'error');
        $request->setParam('error', $exception->getMessage());
    }

    /**
     * Translates a raw request param for a controller into a class name.
     *
     * @param string $controller
     * @return string
     */
    protected function translateControllerName($controller = '')
    {
        $filter = $this->getFilterChain(['DashToCamelcase', 'StringToProper']);
        $controller = $filter->filter($controller);
        return '\App\\' . $controller . 'Controller';
    }

    /**
     * Translates a raw request param for an action into an action name.
     *
     * @param string $action
     *
     * @return string
     */
    protected function translateActionName($action = '')
    {
        $filter = $this->getFilterChain(['DashToCamelcase']);
        $action = $filter->filter($action);
        return $action . 'Action';
    }
}