Completed
Push — 3.0 ( c31299...36a54d )
by Vermeulen
02:09
created

BfwController::getExecRouteSystemName()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
1
<?php
2
3
namespace BfwController;
4
5
use Exception;
6
7
/**
8
 * Controller system class
9
 */
10
class BfwController implements \SplObserver
11
{
12
    /**
13
     * @const ERR_RUN_OBJECT_CLASS_AND_METHOD_UNDEFINED Error code if the class
14
     * and the method is not declared for the current route, in object mode.
15
     */
16
    const ERR_RUN_OBJECT_CLASS_AND_METHOD_UNDEFINED = 2001001;
17
    
18
    /**
19
     * @const ERR_RUN_OBJECT_CLASS_NOT_FOUND Error code if the class declared
20
     * for the route is not found. In object mode only.
21
     */
22
    const ERR_RUN_OBJECT_CLASS_NOT_FOUND = 2001002;
23
    
24
    /**
25
     * @const ERR_RUN_OBJECT_METHOD_NOT_FOUND Error code if the method declared
26
     * for the route is not found. In object mode only.
27
     */
28
    const ERR_RUN_OBJECT_METHOD_NOT_FOUND = 2001003;
29
    
30
    /**
31
     * @const ERR_RUN_PROCEDURAL_FILE_NOT_FOUND Error code if the file to use
32
     * for the route is not found. In procedural mode only.
33
     */
34
    const ERR_RUN_PROCEDURAL_FILE_NOT_FOUND = 2001004;
35
    
36
    /**
37
     * @var \BFW\Module $module The bfw module instance for this module
38
     */
39
    protected $module;
40
    
41
    /**
42
     * @var \BFW\Config $config The bfw config instance for this module
43
     */
44
    protected $config;
45
    
46
    /**
47
     * @var \stdClass|null $ctrlRouterInfos The context object passed to
48
     * subject for the action "searchRoute".
49
     */
50
    protected $ctrlRouterInfos;
51
    
52
    /**
53
     * @var string $execRouteSystemName The name of the current system. Used on
54
     * event "execRoute". Allow to extends this class in another module :)
55
     */
56
    protected $execRouteSystemName = 'bfw-controller';
57
    
58
    /**
59
     * Constructor
60
     * Get config and linker instance
61
     * 
62
     * @param \BFW\Module $module
63
     */
64
    public function __construct(\BFW\Module $module)
65
    {
66
        $this->module = $module;
67
        $this->config = $module->getConfig();
68
    }
69
    
70
    /**
71
     * Getter accessor for module property
72
     * 
73
     * @return \BFW\Module
74
     */
75
    public function getModule()
76
    {
77
        return $this->module;
78
    }
79
80
    /**
81
     * Getter accessor for config property
82
     * 
83
     * @return \BFW\Config
84
     */
85
    public function getConfig()
86
    {
87
        return $this->config;
88
    }
89
90
    /**
91
     * Getter accessor for ctrlRouterInfos property
92
     * 
93
     * @return \stdClass
94
     */
95
    public function getCtrlRouterInfos()
96
    {
97
        return $this->ctrlRouterInfos;
98
    }
99
    
100
    /**
101
     * Getter accessor for execRouteSystemName property
102
     * 
103
     * @return string
104
     */
105
    public function getExecRouteSystemName()
106
    {
107
        return $this->execRouteSystemName;
108
    }
109
    
110
    /**
111
     * Observer update method
112
     * 
113
     * @param \SplSubject $subject
114
     * 
115
     * @return void
116
     */
117
    public function update(\SplSubject $subject)
118
    {
119
        if ($subject->getAction() === 'bfw_ctrlRouterLink_subject_added') {
120
            $app = \BFW\Application::getInstance();
121
            $app->getSubjectList()
122
                ->getSubjectForName('ctrlRouterLink')
123
                ->attach($this)
124
            ;
125
        } elseif ($subject->getAction() === 'execRoute') {
126
            $this->obtainCtrlRouterInfos($subject);
0 ignored issues
show
Documentation introduced by
$subject is of type object<SplSubject>, but the function expects a object<BFW\Subject>.

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...
127
            
128
            if (
129
                $this->ctrlRouterInfos->isFound === true &&
130
                $this->ctrlRouterInfos->forWho === $this->execRouteSystemName
131
            ) {
132
                $this->run();
133
            }
134
        }
135
    }
136
    
137
    /**
138
     * Set the property ctrlRouterInfos with the context object obtain linked
139
     * to the subject.
140
     * Allow override to get only some part. And used for unit test.
141
     * 
142
     * @param \BFW\Subject $subject
143
     * 
144
     * @return void
145
     */
146
    protected function obtainCtrlRouterInfos($subject)
147
    {
148
        $this->ctrlRouterInfos = $subject->getContext();
149
    }
150
    
151
    /**
152
     * Run controller system if application is not run in cli mode
153
     * 
154
     * @return void
155
     */
156
    protected function run()
157
    {
158
        if (PHP_SAPI === 'cli') {
159
            return;
160
        }
161
        
162
        if ($this->ctrlRouterInfos->target === null) {
163
            return;
164
        }
165
        
166
        $useClass = $this->config->getValue('useClass');
167
        
168
        if ($useClass === true) {
169
            $this->runObject();
170
        } else {
171
            $this->runProcedural();
172
        }
173
    }
174
    
175
    /**
176
     * Call controller when is an object.
177
     * 
178
     * @return void
179
     */
180
    protected function runObject()
181
    {
182
        $targetInfos = (object) $this->ctrlRouterInfos->target;
183
        
184
        if (
185
            !property_exists($targetInfos, 'class') ||
186
            !property_exists($targetInfos, 'method')
187
        ) {
188
            throw new Exception(
189
                'You must define properties "class" and "method" for'
190
                .' the current route in the router configuration.',
191
                self::ERR_RUN_OBJECT_CLASS_AND_METHOD_UNDEFINED
192
            );
193
        }
194
        
195
        $class  = $targetInfos->class;
196
        $method = $targetInfos->method;
197
        
198
        if (!class_exists($class)) {
199
            throw new Exception(
200
                'Class '.$class.' not found',
201
                self::ERR_RUN_OBJECT_CLASS_NOT_FOUND
202
            );
203
        }
204
        
205
        $classInstance = new $class;
206
        if (!method_exists($classInstance, $method)) {
207
            throw new Exception(
208
                'Method '.$method.' not found in class '.$class,
209
                self::ERR_RUN_OBJECT_METHOD_NOT_FOUND
210
            );
211
        }
212
        
213
        $classInstance->{$method}();
214
    }
215
    
216
    /**
217
     * Call controler when is a procedural file
218
     * 
219
     * @return void
220
     */
221
    protected function runProcedural()
222
    {
223
        $routerLinker = $this->ctrlRouterInfos;
224
        
225
        $runFct = function() use ($routerLinker) {
226
            $controllerFile = (string) $routerLinker->target;
227
            
228
            if (!file_exists(CTRL_DIR.$controllerFile)) {
229
                throw new Exception(
230
                    'Controller file '.$controllerFile.' not found.',
231
                    self::ERR_RUN_PROCEDURAL_FILE_NOT_FOUND
232
                );
233
            }
234
            
235
            include(CTRL_DIR.$controllerFile);
236
        };
237
        
238
        $runFct();
239
    }
240
}
241