Passed
Push — master ( c0e83c...089a6d )
by Bruno
07:03
created

Framework::editableCompose()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 52
Code Lines 45

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

Changes 3
Bugs 0 Features 0
Metric Value
cc 3
eloc 45
c 3
b 0
f 0
nc 3
nop 3
dl 0
loc 52
rs 9.2
ccs 0
cts 0
cp 0
crap 12

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php declare(strict_types=1);
2
3
namespace Formularium\Frontend\Vue;
4
5
use Formularium\Datatype;
6
use Formularium\Datatype\Datatype_bool;
7
use Formularium\Datatype\Datatype_number;
8
use Formularium\HTMLElement;
9
use Formularium\Model;
10
11
class Framework extends \Formularium\Framework
12
{
13
    const VUE_MODE_SINGLE_FILE = 'VUE_MODE_SINGLE_FILE';
14
    const VUE_MODE_EMBEDDED = 'VUE_MODE_EMBEDDED';
15
16
    /**
17
     * @var string
18
     */
19
    protected $mode = self::VUE_MODE_EMBEDDED;
20
21
    /**
22
    * The tag used as container for fields in viewable()
23
    *
24
    * @var string
25
    */
26
    protected $viewableContainerTag = 'div';
27
28
    /**
29
     * The tag used as container for fields in editable()
30
     *
31
     * @var string
32
     */
33
    protected $editableContainerTag = 'div';
34
35
    /**
36
     * The viewable template.
37
     *
38
     * The following variables are replaced:
39
     *
40
     * {{form}}
41
     * {{jsonData}}
42
     * {{containerTag}}
43
     *
44
     * @var string
45
     */
46
    protected $viewableTemplate = '';
47
48
    /**
49
     *
50
     *
51
     * @var string
52
     */
53
    protected $editableTemplate = '';
54
55
    public function __construct(string $name = 'Vue')
56
    {
57
        parent::__construct($name);
58
    }
59
60
    /**
61
     * Get the tag used as container for fields in viewable()
62
     *
63
     * @return  string
64
     */
65
    public function getViewableContainerTag(): string
66
    {
67
        return $this->viewableContainerTag;
68
    }
69
70
    /**
71
     * Set the tag used as container for fields in viewable()
72
     *
73
     * @param  string  $viewableContainerTag  The tag used as container for fields in viewable()
74
     *
75
     * @return  self
76
     */
77
    public function setViewableContainerTag(string $viewableContainerTag): Framework
78
    {
79
        $this->viewableContainerTag = $viewableContainerTag;
80
        return $this;
81
    }
82
83
    public function getEditableContainerTag(): string
84
    {
85
        return $this->editableContainerTag;
86
    }
87
    
88
    /**
89
     * @param string $tag
90
     * @return self
91
     */
92
    public function setEditableContainerTag(string $tag): Framework
93
    {
94
        $this->editableContainerTag = $tag;
95
        return $this;
96
    }
97
98
    /**
99
     * Get the value of editableTemplate
100
     */
101
    public function getEditableTemplate(): string
102
    {
103
        return $this->editableTemplate;
104
    }
105
106
    /**
107
     * Set the value of editableTemplate
108
     *
109
     * @return self
110
     */
111
    public function setEditableTemplate(string $editableTemplate): Framework
112
    {
113
        $this->editableTemplate = $editableTemplate;
114
115
        return $this;
116
    }
117
    
118
    /**
119
     * Sets the vue render mode, single file component or embedded
120
     *
121
     * @param string $mode self::VUE_MODE_EMBEDDED or self::VUE_MODE_SINGLE_FILE
122
     * @return Framework
123
     */
124
    public function setMode(string $mode): Framework
125
    {
126
        $this->mode = $mode;
127
        return $this;
128
    }
129
130
    /**
131
     * Get the value of mode
132
     *
133
     * @return string
134
     */
135
    public function getMode(): string
136
    {
137
        return $this->mode;
138
    }
139
140
    public function htmlHead(HTMLElement &$head)
141
    {
142
        $head->prependContent(
143
            HTMLElement::factory('script', ['src' => "https://cdn.jsdelivr.net/npm/vue/dist/vue.js"])
144
        );
145
    }
146
147
    protected function mapType(Datatype $type): string
148
    {
149
        if ($type instanceof Datatype_number) {
150
            return 'Number';
151
        } elseif ($type instanceof Datatype_bool) {
152
            return 'Boolean';
153
        }
154
        return 'String';
155
    }
156
157
    protected function props(Model $m): array
158
    {
159
        $props = [];
160
        foreach ($m->getFields() as $field) {
161
            if ($field->getExtension('VUEPROP')) { // TODO
0 ignored issues
show
Bug introduced by
The call to Formularium\Field::getExtension() has too few arguments starting with default. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

161
            if ($field->/** @scrutinizer ignore-call */ getExtension('VUEPROP')) { // TODO

This check compares calls to functions or methods with their respective definitions. If the call has less arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
162
                $p = [
163
                    'type' => $this->mapType($field->getDatatype()),
164
                ];
165
                if ($field->getExtension(Datatype::REQUIRED)) {
166
                    $p['required'] = true;
167
                }
168
                $props[$field->getName()] = $p;
169
            }
170
        }
171
        return $props;
172
    }
173
174
    public function viewableCompose(Model $m, array $elements, string $previousCompose): string
175
    {
176
        $data = $m->getDefault(); // TODO: load data
177
        
178
        $viewableForm = join('', $elements);
179
        $jsonData = json_encode($data);
180
        $templateData = [
181
            'containerTag' => $this->getViewableContainerTag(),
182
            'form' => $viewableForm,
183
            'jsonData' => $jsonData,
184
            'props' => $this->props($m)
185
        ];
186
187
        if ($this->viewableTemplate) {
188
            return $this->fillTemplate(
189
                $this->viewableTemplate,
190
                $templateData,
191
                $m
192
            );
193
        } elseif ($this->mode === self::VUE_MODE_SINGLE_FILE) {
194
            $viewableTemplate = <<<EOF
0 ignored issues
show
Unused Code introduced by
The assignment to $viewableTemplate is dead and can be removed.
Loading history...
195
<template>
196
<{{containerTag}}>
197
    {{form}}
198
</{{containerTag}}>
199
</template>
200
<script>
201
module.exports = {
202
    data: function () {
203
        return {{jsonData}};
204
    }
205
};
206
</script>
207
<style>
208
</style>
209
EOF;
210
            return $this->fillTemplate(
211
                $this->viewableTemplate,
212
                $templateData,
213
                $m
214
            );
215
        } else {
216
            $id = 'vueapp';
217
            $t = new HTMLElement(self::getViewableContainerTag(), ['id' => $id], $viewableForm, true);
0 ignored issues
show
Bug Best Practice introduced by
The method Formularium\Frontend\Vue...tViewableContainerTag() is not static, but was called statically. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

217
            $t = new HTMLElement(self::/** @scrutinizer ignore-call */ getViewableContainerTag(), ['id' => $id], $viewableForm, true);
Loading history...
218
            $script = <<<EOF
219
var app = new Vue({
220
    el: '#$id',
221
    data: $jsonData
222
});
223
EOF;
224
            $s = new HTMLElement('script', [], $script, true);
225
            return HTMLElement::factory('div', [], [$t, $s])->getRenderHTML();
226
        }
227
    }
228
229
    public function editableCompose(Model $m, array $elements, string $previousCompose): string
230
    {
231
        $data = $m->getDefault(); // TODO: load data
232
        $editableContainerTag = $this->getEditableContainerTag();
233
        $editableForm = join('', $elements);
234
        $jsonData = json_encode($data);
235
        $templateData = [
236
            'containerTag' => $this->getViewableContainerTag(),
237
            'form' => $editableForm,
238
            'jsonData' => $jsonData,
239
            'props' => $this->props($m)
240
        ];
241
242
        if ($this->viewableTemplate) {
243
            return $this->fillTemplate(
244
                $this->editableTemplate,
245
                $templateData,
246
                $m
247
            );
248
        } elseif ($this->mode === self::VUE_MODE_SINGLE_FILE) {
249
            $editableTemplate = <<<EOF
250
<template>
251
<{{containerTag}}>
252
    {{form}}
253
</{{containerTag}}>
254
</template>
255
<script>
256
module.exports = {
257
    data: function () {
258
        return {{jsonData}};
259
    }
260
};
261
</script>
262
<style>
263
</style>
264
EOF;
265
            return $this->fillTemplate(
266
                $editableTemplate,
267
                $templateData,
268
                $m
269
            );
270
        } else {
271
            $id = 'vueapp';
272
            $t = new HTMLElement($editableContainerTag, ['id' => $id], $editableForm, true);
273
            $script = <<<EOF
274
var app = new Vue({
275
    el: '#$id',
276
    data: $jsonData
277
});
278
EOF;
279
            $s = new HTMLElement('script', [], $script, true);
280
            return HTMLElement::factory('div', [], [$t, $s])->getRenderHTML();
281
        }
282
    }
283
284
    protected function fillTemplate(string $template, array $data, Model $m): string
285
    {
286
        $template = str_replace(
287
            '{{form}}',
288
            $data['form'],
289
            $template
290
        );
291
        $template = str_replace(
292
            '{{modelName}}',
293
            $m->getName(),
294
            $template
295
        );
296
        $template = str_replace(
297
            '{{modelNameLower}}',
298
            mb_strtolower($m->getName()),
299
            $template
300
        );
301
        $template = str_replace(
302
            '{{jsonData}}',
303
            $data['jsonData'],
304
            $template
305
        );
306
        $template = str_replace(
307
            '{{containerTag}}',
308
            $data['containerTag'],
309
            $template
310
        );
311
        return $template;
312
    }
313
}
314