Passed
Push — master ( c9493e...51929d )
by Victor
01:45
created

InspectorMiddleware::value()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 8
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 6.9849

Importance

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