InspectorMiddleware::scalar()   A
last analyzed

Complexity

Conditions 5
Paths 8

Size

Total Lines 14
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 5.2742

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 9
c 1
b 0
f 0
dl 0
loc 14
ccs 7
cts 9
cp 0.7778
rs 9.6111
cc 5
nc 8
nop 2
crap 5.2742
1
<?php
2
declare(strict_types=1);
3
4
namespace Shoot\Shoot\Middleware;
5
6
use Psr\Http\Message\ServerRequestInterface;
7
use Shoot\Shoot\HasPresenterInterface;
8
use Shoot\Shoot\MiddlewareInterface;
9
use Shoot\Shoot\PresentationModel;
10
use Shoot\Shoot\View;
11
12
/**
13
 * The inspector shows you what templates, presentation models, presenters and variables were used to render a page by
14
 * logging this information to your browser console.
15
 */
16
final class InspectorMiddleware implements MiddlewareInterface
17
{
18
    /**
19
     * Process the view within the context of the current HTTP request, either before or after calling the next
20
     * middleware. Returns the processed view.
21
     *
22
     * @param View                   $view
23
     * @param ServerRequestInterface $request
24
     * @param callable               $next
25
     *
26
     * @return View
27
     */
28 1
    public function process(View $view, ServerRequestInterface $request, callable $next): View
29
    {
30 1
        $this->script();
31 1
        $this->view($view);
32 1
        $this->scriptEnd();
33
34 1
        return $next($view);
35
    }
36
37
    /**
38
     * @param mixed  $value
39
     * @param string $label
40
     *
41
     * @return void
42
     */
43 1
    private function value($value, string $label = ''): void
44
    {
45 1
        if (is_scalar($value)) {
46 1
            $this->scalar($value, $label);
47
        } elseif (is_array($value)) {
48
            $this->iterable($value, $label);
49
        } elseif (is_object($value)) {
50
            $this->object($value, $label);
51
        }
52 1
    }
53
54
    /**
55
     * @param bool|float|int|string $scalar
56
     * @param string                $label
57
     *
58
     * @return void
59
     */
60 1
    private function scalar($scalar, string $label = ''): void
61
    {
62 1
        if (is_bool($scalar)) {
63
            $scalar = $scalar ? 'true' : 'false';
64 1
        } elseif (is_string($scalar)) {
65 1
            $scalar = "'{$this->escape($scalar)}'";
66
        }
67
68 1
        if ($label !== '') {
69 1
            $label = $this->escape($label);
70
71 1
            echo "console.log('%c{$label}','font-weight:bold',{$scalar});";
72
        } else {
73
            echo "console.log({$scalar});";
74
        }
75 1
    }
76
77
    /**
78
     * @param mixed[] $iterable
79
     * @param string  $label
80
     *
81
     * @return void
82
     */
83 1
    private function iterable(array $iterable, string $label = ''): void
84
    {
85 1
        if ($label === '') {
86
            $label = '...';
87
        }
88
89 1
        $this->group($label);
90
91 1
        foreach ($iterable as $key => $item) {
92 1
            if (!is_string($key)) {
93
                $key = '';
94
            }
95
96 1
            $this->value($item, $key);
97
        }
98
99 1
        $this->groupEnd();
100 1
    }
101
102
    /**
103
     * @param object $object
104
     * @param string $label
105
     *
106
     * @return void
107
     */
108
    private function object($object, string $label = ''): void
109
    {
110
        if ($object instanceof PresentationModel) {
111
            $this->presentationModel($object, $label);
112
        } elseif ($object instanceof View) {
113
            $this->view($object);
114
        } else {
115
            $this->iterable(get_object_vars($object), $label);
116
        }
117
    }
118
119
    /**
120
     * @param View $view
121
     *
122
     * @return void
123
     */
124 1
    private function view(View $view): void
125
    {
126 1
        $this->group($view->getName(), false);
127 1
        $this->presentationModel($view->getPresentationModel(), 'presentationModel');
128 1
        $this->groupEnd();
129 1
    }
130
131
    /**
132
     * @param PresentationModel $presentationModel
133
     * @param string            $label
134
     *
135
     * @return void
136
     */
137 1
    private function presentationModel(PresentationModel $presentationModel, string $label = ''): void
138
    {
139 1
        if ($label === '') {
140
            $label = $presentationModel->getName();
141
        }
142
143 1
        $this->group($label, false);
144 1
        $this->value($presentationModel->getName(), 'name');
145
146 1
        if ($presentationModel instanceof HasPresenterInterface) {
147 1
            $this->value($presentationModel->getPresenterName(), 'presenter');
148
        }
149
150 1
        $this->iterable($presentationModel->getVariables(), 'variables');
151 1
        $this->groupEnd();
152 1
    }
153
154
    /**
155
     * @param string $string
156
     *
157
     * @return string
158
     */
159 1
    private function escape(string $string): string
160
    {
161 1
        return addslashes($string);
162
    }
163
164
    /**
165
     * @param string $label
166
     * @param bool   $collapsed
167
     *
168
     * @return void
169
     */
170 1
    private function group(string $label, bool $collapsed = true): void
171
    {
172 1
        $label = $this->escape($label);
173
174 1
        if ($collapsed) {
175 1
            echo "console.groupCollapsed('{$label}');";
176
        } else {
177 1
            echo "console.group('{$label}');";
178
        }
179 1
    }
180
181
    /**
182
     * @return void
183
     */
184 1
    private function groupEnd(): void
185
    {
186 1
        echo 'console.groupEnd();';
187 1
    }
188
189
    /**
190
     * @return void
191
     */
192 1
    private function script(): void
193
    {
194 1
        echo '<script>';
195 1
    }
196
197
    /**
198
     * @return void
199
     */
200 1
    private function scriptEnd(): void
201
    {
202 1
        echo '</script>';
203 1
    }
204
}
205