Passed
Push — master ( 0c1da5...f04640 )
by Jay
02:13
created

Framework::dispatch()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 18
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 13
CRAP Score 4

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 18
ccs 13
cts 13
cp 1
rs 9.2
cc 4
eloc 13
nc 4
nop 0
crap 4
1
<?php
2
declare(strict_types = 1);
3
4
namespace Nano;
5
6
/**
7
 * Class Framework
8
 * @package Nano
9
 */
10
final class Framework
11
{
12
    private $projectNamespace = '\Project';
13
    private $controllerPackage = '\Controller';
14
    private $controllerActionSuffix = 'Action';
15
16
    /**
17
     * Dispatch the request
18
     * @throws \Exception
19
     * @return mixed
20
     */
21 10
    public function dispatch()
22
    {
23 10
        list($controllerName, $action) = $this->getControllerAndAction();
24 10
        $controller = $this->projectNamespace . $this->controllerPackage . '\\' . ucfirst($controllerName);
25 10
        if (!class_exists($controller)) {
26 3
            throw new \Exception('controller ' . $controllerName . ' not found');
27
        };
28 7
        $controller = new $controller;
29 7
        $finalAction = $this->getVerbFromRequest() . ucfirst($action) . $this->controllerActionSuffix;
30 7
        if (is_callable(array($controller, $finalAction))) {
31 1
            return $controller->$finalAction();
32
        }
33 6
        $finalAction = $action . $this->controllerActionSuffix;
34 6
        if (!is_callable(array($controller, $finalAction))) {
35 1
            throw new \Exception('action ' . $finalAction . ' not found in controller ' . $controllerName);
36
        }
37 5
        return $controller->$finalAction();
38
    }
39
40
    /**
41
     * Return HTTP Method for request
42
     * @return string
43
     */
44 7
    private function getVerbFromRequest()
45
    {
46 7
        return isset($_SERVER['REQUEST_METHOD']) ? strtolower($_SERVER['REQUEST_METHOD']) : 'get';
47
    }
48
49
    /**
50
     * Returns Request uri without query string
51
     * @return string
52
     */
53 10
    private function getQuery() : string
54
    {
55 10
        $requestUri = $_SERVER['REQUEST_URI'];
56 10
        $appendUri = strpos($requestUri, '?');
57 10
        return substr($requestUri, 0, $appendUri === false ? strlen($requestUri) : $appendUri);
58
    }
59
60
    /**
61
     * Determine controller and action from Request Uri
62
     * @return array
63
     */
64 10
    private function getControllerAndAction() : array
65
    {
66 10
        $parts = explode('/', preg_replace('~^' . Basepath::get() . '~', '', $this->getQuery()));
67 10
        $action = count($parts) >= 2 ? array_pop($parts) : 'index';
68 10
        $controllerName = isset($parts[0]) && $parts[0] ? implode($parts, '\\') : 'index';
69 10
        return [$controllerName, $action ?: 'index'];
70
    }
71
72
    /**
73
     * Redefine personal namespace
74
     * @param string $namespace
75
     * @return Framework
76
     */
77 4
    public function setNamespace(string $namespace = '\Project') : Framework
78
    {
79 4
        $this->projectNamespace = strlen($namespace) && $namespace{0} != '\\' ? '\\' . $namespace : $namespace;
80 4
        return $this;
81
    }
82
83
    /**
84
     * Redefine controller subpackage
85
     * @param string $controllerPackage
86
     * @return Framework
87
     */
88 5
    public function setControllerPackage(string $controllerPackage = '\Controller') : Framework
89
    {
90 5
        $this->controllerPackage = strlen($controllerPackage) && $controllerPackage{0} != '\\'
91 2
            ? '\\' . $controllerPackage
92 3
            : $controllerPackage;
93 5
        return $this;
94
    }
95
96
    /**
97
     * Redefine controller action suffix
98
     * @param string $suffix
99
     * @return Framework
100
     */
101 3
    public function setControllerActionSuffix(string $suffix = 'Action') : Framework
102
    {
103 3
        $this->controllerActionSuffix = (string)$suffix;
104 3
        return $this;
105
    }
106
}
107