Completed
Push — b0.27.0 ( c529b3...34cc26 )
by Sebastian
05:07
created

FrontController::runController()   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 20
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 4.0218

Importance

Changes 4
Bugs 2 Features 0
Metric Value
eloc 8
c 4
b 2
f 0
dl 0
loc 20
ccs 8
cts 9
cp 0.8889
rs 10
cc 4
nc 3
nop 0
crap 4.0218
1
<?php
2
3
/**
4
 * Linna Framework.
5
 *
6
 * @author Sebastian Rapetti <[email protected]>
7
 * @copyright (c) 2018, Sebastian Rapetti
8
 * @license http://opensource.org/licenses/MIT MIT License
9
 */
10
declare(strict_types=1);
11
12
namespace Linna\Mvc;
13
14
use Linna\Router\Route;
15
use Linna\Router\RouteInterface;
16
17
/**
18
 * FrontController.
19
 */
20
class FrontController
21
{
22
    /**
23
     * @var View Contain view object for render
24
     */
25
    private View $view;
26
27
    /**
28
     * @var Model Contain model object
29
     */
30
    private Model $model;
31
32
    /**
33
     * @var Controller Contain controller object
34
     */
35
    private Controller $controller;
36
37
    /**
38
     * @var string Contain Controller and View action name
39
     */
40
    private string $routeAction = '';
41
42
    /**
43
     * @var array<mixed> Paremeters passed to Controller
44
     */
45
    private array $routeParam = [];
46
47
    /**
48
     * Constructor.
49
     *
50
     * @param Model          $model
51
     * @param View           $view
52
     * @param Controller     $controller
53
     * @param RouteInterface $route
54
     */
55 19
    public function __construct(Model $model, View $view, Controller $controller, RouteInterface $route)
56
    {
57 19
        if ($route instanceof Route) {
58 19
            $this->routeAction = ($route->action) ?: 'entryPoint';
59 19
            $this->routeParam = $route->param;
60
        }
61
62 19
        $this->model = $model;
63 19
        $this->view = $view;
64 19
        $this->controller = $controller;
65 19
    }
66
67
    /**
68
     * Run mvc pattern.
69
     *
70
     * @return void
71
     */
72 18
    public function run(): void
73
    {
74
        //attach Oserver to Subjetc
75 18
        $this->model->attach($this->view);
76
77
        //run action before controller
78 18
        $this->beforeAfterController('before');
79 18
        $this->beforeAfterControllerAction('before');
80
81
        //run controller
82 18
        $this->runController();
83
84
        //run action after controller
85 18
        $this->beforeAfterControllerAction('after');
86 18
        $this->beforeAfterController('after');
87
88
        //notify model changes to view
89 18
        $this->model->notify();
90
91
        //run view
92 18
        $this->runView();
93 18
    }
94
95
    /**
96
     * Run action before or after controller action execution.
97
     *
98
     * @param string $when
99
     *
100
     * @return void
101
     */
102 18
    private function beforeAfterControllerAction(string $when): void
103
    {
104 18
        $method = $when.\ucfirst($this->routeAction);
105
106 18
        if (\method_exists($this->controller, $method) && $method !== $when) {
107 5
            \call_user_func([$this->controller, $method]);
108
        }
109 18
    }
110
111
    /**
112
     * Run action before or after controller execution.
113
     *
114
     * @param string $when
115
     *
116
     * @return void
117
     */
118 18
    private function beforeAfterController(string $when): void
119
    {
120 18
        if (\method_exists($this->controller, $when)) {
121 5
            \call_user_func([$this->controller, $when]);
122
        }
123 18
    }
124
125
    /**
126
     * Run controller.
127
     *
128
     * @return void
129
     */
130 18
    private function runController(): void
131
    {
132
        //get route information
133 18
        $action = $this->routeAction;
134 18
        $param = $this->routeParam;
135
136
        //if controller does not have the method named entryPoint
137
        //this avoid problems
138 18
        if (!\method_exists($this->controller, $action)) {
139
            return;
140
        }
141
142
        //action - call controller passing params
143 18
        if (!empty($param) && $action) {
144 10
            \call_user_func_array([$this->controller, $action], $param);
145 10
            return;
146
        }
147
148
        //action - call controller
149 8
        \call_user_func([$this->controller, $action]);
150 8
    }
151
152
    /**
153
     * Run view.
154
     *
155
     * @return void
156
     */
157 18
    private function runView(): void
158
    {
159
        //get route information
160 18
        $action = $this->routeAction;
161
162 18
        if (\method_exists($this->view, $action)) {
163 18
            \call_user_func([$this->view, $action]);
164
        }
165 18
    }
166
167
    /**
168
     * Return view data.
169
     *
170
     * @return string
171
     */
172 18
    public function response(): string
173
    {
174 18
        return $this->view->render();
175
    }
176
}
177