Passed
Pull Request — master (#37)
by Bruno
10:31
created

VueCode::fillTemplate()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 21
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 14
c 1
b 0
f 0
dl 0
loc 21
rs 9.7998
cc 2
nc 2
nop 3
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\Exception\Exception;
9
use Formularium\Field;
10
use Formularium\Frontend\Vue\VueCode\Computed;
11
use Formularium\Frontend\Vue\VueCode\Prop;
12
use Formularium\HTMLNode;
13
use Formularium\Model;
14
use Formularium\RenderableParameter;
15
16
use function Safe\json_encode;
17
18
/**
19
 * Converts an array to a JS object. Unlike JSON this does serialize
20
 * data to strings, and allow functions, etc. If you need to add
21
 * strings they are expected to be previously quoted with " or '
22
 *
23
 * @param array $data
24
 * @return array
25
 */
26
function expandJS(array $data): array
27
{
28
    return array_map(function ($key, $value) {
29
        return "$key" .
30
            (
31
                is_array($value) ?
32
                ': {' . implode(",\n", expandJS($value)) . '}' :
33
                ($value ? ':' . $value : '')
34
            );
35
    }, array_keys($data), $data);
36
}
37
38
class VueCode
39
{
40
41
    /**
42
     * Appended to the field variable names to handle models stored in an object field.
43
     *
44
     * Allows you to declare the model like this:
45
     *
46
     * data() {
47
     *   return {
48
     *       model: model,
49
     *   };
50
     * },
51
     *
52
     * @var string
53
     */
54
    public $fieldModelVariable = '';
55
56
    /**
57
     * Extra props.
58
     *
59
     * @var Prop[]
60
     */
61
    public $extraProps = [];
62
63
    /**
64
     * extra data fields
65
     *
66
     * @var string[]
67
     */
68
    public $extraData = [];
69
70
    /**
71
     * The list of imports to add: import 'key' from 'value'
72
     *
73
     * @var string[]
74
     */
75
    public $imports = [];
76
77
    /**
78
     * @var Computed[]
79
     */
80
    public $computed = [];
81
82
    /**
83
     * @var string[]
84
     */
85
    public $methods = [];
86
87
    /**
88
     * @var string[]
89
     */
90
    public $other = [];
91
92
    /**
93
     * @var VueCodeAbstractRenderer
94
     */
95
    public $renderer;
96
97
    public function __construct(string $rendererClass = Vue2CodeDictRenderer::class)
98
    {
99
        $this->renderer = new $rendererClass($this);
100
    }
101
102
    /**
103
     * @param string $name
104
     * @param string $code
105
     * @return self
106
     */
107
    public function appendMethod($name, $code): self
108
    {
109
        $this->methods[$name] = $code;
110
        return $this;
111
    }
112
113
    /**
114
     * @param string $name
115
     * @param string $code
116
     * @return self
117
     */
118
    public function appendOther($name, $code): self
119
    {
120
        $this->other[$name] = $code;
121
        return $this;
122
    }
123
124
    /**
125
     * @return array
126
     */
127
    public function getExtraProps(): array
128
    {
129
        return $this->extraProps;
130
    }
131
132
    /**
133
     *
134
     * @param Prop[] $extraProps
135
     *
136
     * @return  self
137
     */
138
    public function setExtraProps(array $extraProps): self
139
    {
140
        $this->extraProps = $extraProps;
141
142
        return $this;
143
    }
144
145
    /**
146
     *
147
     * @param Prop $prop
148
     *
149
     * @return  self
150
     */
151
    public function appendExtraProp(Prop $prop): self
152
    {
153
        $this->extraProps[] = $prop;
154
155
        return $this;
156
    }
157
158
    /**
159
     * Appends to the `data` field.
160
     *
161
     * @param string $name
162
     * @param mixed $value
163
     * @return self
164
     */
165
    public function appendExtraData(string $name, $value): self
166
    {
167
        $this->extraData[$name] = $value;
168
        return $this;
169
    }
170
171
    /**
172
     * The list of imports to add: import 'key' from 'value'
173
     *
174
     * @param string $key
175
     * @param string $value
176
     * @return self
177
     */
178
    public function appendImport(string $key, string $value): self
179
    {
180
        $this->imports[$key] = $value;
181
182
        return $this;
183
    }
184
185
    /**
186
     * The list of computed to add: $ke() => $code
187
     *
188
     * @param string $key
189
     * @param string $code
190
     * @return self
191
     */
192
    public function appendComputed(Computed $computed): self
193
    {
194
        $this->computed[] = $computed;
195
196
        return $this;
197
    }
198
199
    /**
200
     * Get appended to the field variable names to handle models stored in an object field.
201
     *
202
     * @return  string
203
     */
204
    public function getFieldModelVariable(): string
205
    {
206
        return $this->fieldModelVariable;
207
    }
208
209
    /**
210
     * Set appended to the field variable names to handle models stored in an object field.
211
     *
212
     * @param  string  $fieldModelVariable  Appended to the field variable names to handle models stored in an object field.
213
     *
214
     * @return  self
215
     */
216
    public function setFieldModelVariable(string $fieldModelVariable): self
217
    {
218
        $this->fieldModelVariable = $fieldModelVariable;
219
220
        return $this;
221
    }
222
223
    /**
224
     * Converts a Datatype to a JS type
225
     *
226
     * @param Datatype|string $type
227
     * @return string
228
     */
229
    public static function mapTypeToJS($type): string
230
    {
231
        if ($type instanceof Datatype_number || $type === 'number') {
232
            return 'Number';
233
        } elseif ($type instanceof Datatype_bool || $type === 'boolean') {
234
            return 'Boolean';
235
        } elseif ($type->getBasetype() == 'relationship') { // TODO this is crappy, comes from modelarium
236
            return 'Object';
237
        }
238
        return 'String';
239
    }
240
241
    /**
242
     * Generates the javascript code.
243
     *
244
     * @param Model $m
245
     * @param HTMLNode[] $elements
246
     * @return string
247
     */
248
    public function toScript(Model $m, array $elements)
249
    {
250
        return $this->renderer->toScript($m, $elements);
251
    }
252
253
    /**
254
     * Generates the javascript code.
255
     *
256
     * @param Model $m
257
     * @param HTMLNode[] $elements
258
     * @return string
259
     */
260
    public function toVariable(Model $m, array $elements)
261
    {
262
        return $this->renderer->toVariable($m, $elements);
263
    }
264
265
    /**
266
     * Get the value of other
267
     * @return array
268
     */
269
    public function &getOther(): array
270
    {
271
        return $this->other;
272
    }
273
274
    /**
275
     * @param Model $m
276
     * @return Prop[]
277
     */
278
    public function props(Model $m): array
279
    {
280
        $props = [];
281
        foreach ($m->getFields() as $field) {
282
            /**
283
             * @var Field $field
284
             */
285
            if ($field->getRenderable(Framework::VUE_PROP, false)) {
286
                $p = new Prop(
287
                    $field->getName(),
288
                    $field->getDatatype(),
0 ignored issues
show
Bug introduced by
$field->getDatatype() of type Formularium\Datatype is incompatible with the type string expected by parameter $type of Formularium\Frontend\Vue...ode\Prop::__construct(). ( Ignorable by Annotation )

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

288
                    /** @scrutinizer ignore-type */ $field->getDatatype(),
Loading history...
289
                );
290
                if ($field->getRenderable(Datatype::REQUIRED, false)) {
291
                    $p->required = true;
292
                }
293
                $p->default = $field->getRenderable(RenderableParameter::DEFAULTVALUE, null);
294
                $props[] = $p;
295
            }
296
        }
297
298
        return array_merge($props, $this->extraProps);
299
    }
300
}
301