Passed
Pull Request — master (#37)
by Bruno
07:17
created

Vue2CodeDictRenderer::getTemplateData()   B

Complexity

Conditions 5
Paths 12

Size

Total Lines 78
Code Lines 49

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 49
c 0
b 0
f 0
dl 0
loc 78
rs 8.8016
cc 5
nc 12
nop 2

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\Exception\Exception;
7
use Formularium\Field;
8
use Formularium\Frontend\Vue\VueCode\Computed;
9
use Formularium\Frontend\Vue\VueCode\Prop;
10
use Formularium\HTMLNode;
11
use Formularium\Model;
12
use Formularium\RenderableParameter;
13
14
use function Safe\json_encode;
15
16
class Vue2CodeDictRenderer extends VueCodeAbstractRenderer
17
{
18
    /**
19
     * Generates template data for rendering
20
     *
21
     * @param Model $m
22
     * @param HTMLNode[] $elements $elements
23
     * @return array
24
     */
25
    public function getTemplateData(Model $m, array $elements): array
26
    {
27
        // get the props array with all js data
28
        $props = $this->vueCode->props($m);
29
        // get only props names
30
        $propsNames = array_map(
31
            function ($p) {
32
                return $p->name;
33
            },
34
            $props
35
        );
36
        /**
37
         * @var array $propsNames
38
         */
39
        $propsNames = array_combine($propsNames, $propsNames);
40
        // get the binding
41
        $propsBind = array_map(
42
            function (Prop $p) {
43
                return $p->toBind();
44
            },
45
            $props
46
        );
47
48
        // get data, and avoid anything that is already declared in props
49
        $data = [];
50
        foreach (array_merge($m->getDefault(), $m->getData(), $this->vueCode->extraData) as $k => $v) {
51
            if (array_key_exists($k, $propsNames)) {
52
                continue;
53
            }
54
            $data[$k] = $v;
55
        }
56
        // ensure it's a dict even if empty
57
        if ($data === []) {
58
            $jsonData = '{}';
59
        } else {
60
            $jsonData = json_encode($data, JSON_PRETTY_PRINT);
61
        }
62
63
        $templateData = [
64
            'jsonData' => $jsonData,
65
            'propsCode' => implode(
66
                "\n",
67
                array_map(function (Prop $p) {
68
                    return $p->toStruct();
69
                }, $props)
70
            ),
71
            'propsBind' => implode(' ', $propsBind),
72
            'imports' => implode(
73
                "\n",
74
                array_map(function ($key, $value) {
75
                    return "import $key from \"$value\";";
76
                }, array_keys($this->vueCode->imports), $this->vueCode->imports)
77
            ),
78
            'computedCode' => implode(
79
                "\n",
80
                array_map(
81
                    function (Computed $c) {
82
                        return $c->toStruct();
83
                    },
84
                    $this->vueCode->computed
85
                )
86
            ),
87
            'otherData' => implode(
88
                ",\n",
89
                expandJS($this->vueCode->other)
90
            ),
91
            'methodsCode' => implode(
92
                "\n",
93
                array_map(function ($key, $value) {
94
                    return "$key { $value },";
95
                }, array_keys($this->vueCode->methods), $this->vueCode->methods)
96
            ),
97
        ];
98
        if ($templateData['otherData']) {
99
            $templateData['otherData'] .= ",\n";
100
        }
101
102
        return $templateData;
103
    }
104
105
    protected function fillTemplate(string $template, array $data, Model $m): string
106
    {
107
        foreach ($data as $name => $value) {
108
            $template = str_replace(
109
                '{{' . $name . '}}',
110
                $value,
111
                $template
112
            );
113
        }
114
115
        $template = str_replace(
116
            '{{modelName}}',
117
            $m->getName(),
118
            $template
119
        );
120
        $template = str_replace(
121
            '{{modelNameLower}}',
122
            mb_strtolower($m->getName()),
123
            $template
124
        );
125
        return $template;
126
    }
127
128
    /**
129
     * Generates the javascript code.
130
     *
131
     * @param Model $m
132
     * @param HTMLNode[] $elements
133
     * @return string
134
     */
135
    public function toScript(Model $m, array $elements)
136
    {
137
        $templateData = $this->getTemplateData($m, $elements);
138
139
        $viewableTemplate = <<<EOF
140
{{imports}}
141
142
export default {
143
    {{otherData}}
144
    data() {
145
        return {{jsonData}};
146
    },
147
    computed: { {{computedCode}} },
148
    props: { {{propsCode}} },
149
    methods: { {{methodsCode}} }
150
};
151
EOF;
152
153
        return $this->fillTemplate(
154
            $viewableTemplate,
155
            $templateData,
156
            $m
157
        );
158
    }
159
160
    /**
161
     * Generates the javascript code.
162
     *
163
     * @param Model $m
164
     * @param HTMLNode[] $elements
165
     * @return string
166
     */
167
    public function toClassScript(Model $m, array $elements)
168
    {
169
        $templateData = $this->getTemplateData($m, $elements);
170
171
        $viewableTemplate = <<<EOF
172
{{imports}}
173
174
@Component({ components: { } })
175
export default class {{name}} extends Vue {
176
    {{otherData}}
177
    data() {
178
        return {{jsonData}};
179
    },
180
    computed: { {{computedCode}} },
181
182
    @Prop({})
183
184
    {{methodsCode}}
185
};
186
EOF;
187
188
        $templateData['className'] = $m->getName(); // TODO
189
190
191
        return $this->fillTemplate(
192
            $viewableTemplate,
193
            $templateData,
194
            $m
195
        );
196
    }
197
198
199
    /**
200
     * Generates the javascript code.
201
     *
202
     * @param Model $m
203
     * @param HTMLNode[] $elements
204
     * @return string
205
     */
206
    public function toVariable(Model $m, array $elements)
207
    {
208
        $templateData = $this->getTemplateData($m, $elements);
209
210
        $viewableTemplate = <<<EOF
211
    {{otherData}}
212
    data() {
213
        return {{jsonData}};
214
    },
215
    computed: { {{computedCode}} },
216
    props: {{propsCode}},
217
    methods: { {{methodsCode}} }
218
EOF;
219
220
        return $this->fillTemplate(
221
            $viewableTemplate,
222
            $templateData,
223
            $m
224
        );
225
    }
226
}
227