Completed
Push — master ( c0f250...321e24 )
by Filipe
15:10
created

ControllerDispatch::checkClassExists()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 8
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 4
nc 2
nop 1
1
<?php
2
3
/**
4
 * This file is part of slick/web_stack package
5
 *
6
 * For the full copyright and license information, please view the LICENSE
7
 * file that was distributed with this source code.
8
 */
9
10
namespace Slick\WebStack\Dispatcher;
11
12
use Slick\WebStack\ControllerInterface;
13
use Slick\WebStack\Exception\BadControllerClassException;
14
use Slick\WebStack\Exception\ControllerNotFoundException;
15
use Slick\WebStack\Exception\MissingControllerMethodException;
16
17
/**
18
 * ControllerDispatch
19
 *
20
 * @package Slick\WebStack\Dispatcher
21
 */
22
class ControllerDispatch
23
{
24
    /**
25
     * @var \ReflectionClass
26
     */
27
    private $controllerClass;
28
29
    /**
30
     * @var \ReflectionMethod
31
     */
32
    private $method;
33
34
    /**
35
     * @var array
36
     */
37
    private $arguments;
38
39
    /**
40
     * Creates a Controller Dispatch
41
     *
42
     * @param string $controllerClassName
43
     * @param string $method
44
     * @param array  $arguments
45
     *
46
     * @throws ControllerNotFoundException      If controller class name does ot exits
47
     * @throws BadControllerClassException      If the provided class does not implement ControllerInterface
48
     * @throws MissingControllerMethodException If provided method is not defined within the class
49
     */
50
    public function __construct($controllerClassName, $method, array $arguments = [])
51
    {
52
        $this->checkClassExists($controllerClassName);
53
        $this->checkClassIsAController($controllerClassName);
54
        $this->controllerClass = new \ReflectionClass($controllerClassName);
55
56
        $this->checkMethodExists($method);
57
        $this->method = $this->controllerClass->getMethod($method);
58
59
        $this->arguments = $arguments;
60
    }
61
62
    /**
63
     * Controller class name
64
     *
65
     * @return \ReflectionClass
66
     */
67
    public function controllerClass()
68
    {
69
        return $this->controllerClass;
70
    }
71
72
    /**
73
     * The method name that will be called to handle the request
74
     *
75
     * @return \ReflectionMethod
76
     */
77
    public function handlerMethod()
78
    {
79
        return $this->method;
80
    }
81
82
    /**
83
     * A list of optional arguments to use when calling the request handler
84
     *
85
     * @return array
86
     */
87
    public function arguments()
88
    {
89
        return $this->arguments;
90
    }
91
92
    /**
93
     * Check if controller class exists
94
     *
95
     * @param $controllerClassName
96
     *
97
     * @throws ControllerNotFoundException if controller class name does ot exits
98
     */
99
    private function checkClassExists($controllerClassName)
100
    {
101
        if (! class_exists($controllerClassName)) {
102
            throw new ControllerNotFoundException(
103
                "The controller class {$controllerClassName} does not exists or cannot be loaded."
104
            );
105
        }
106
    }
107
108
    /**
109
     * Check if controller class implements the ControllerInterface
110
     *
111
     * @param $controllerClassName
112
     *
113
     * @throws BadControllerClassException If the provided class does not implement ControllerInterface
114
     */
115
    private function checkClassIsAController($controllerClassName)
116
    {
117
        if (! is_subclass_of($controllerClassName, ControllerInterface::class)) {
118
            throw new BadControllerClassException(
119
                sprintf(
120
                    "The provided class cannot be used as a controller. ".
121
                    "It must implement the %s interface.",
122
                    ControllerInterface::class
123
                )
124
            );
125
        }
126
    }
127
128
    /**
129
     * Check if controller class has the provided method name
130
     *
131
     * @param string $method
132
     *
133
     * @throws MissingControllerMethodException If provided method is not defined within the class
134
     */
135
    private function checkMethodExists($method)
136
    {
137
        if (! $this->controllerClass->hasMethod($method)) {
138
            throw new MissingControllerMethodException(
139
                sprintf(
140
                    "Method %s::%s() is not defined in controller.",
141
                    $this->controllerClass->getShortName(),
142
                    $method
143
                )
144
            );
145
        }
146
    }
147
}
148