Passed
Push — master ( f3eaf1...0fde80 )
by Reza
04:06
created

StubParser::parseSetPropertiesValue()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 11
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 1
Metric Value
cc 2
eloc 7
nc 2
nop 0
dl 0
loc 11
rs 10
c 2
b 0
f 1
1
<?php
2
3
namespace EasyPanel\Parsers;
4
5
use Illuminate\Support\Facades\File;
6
use Illuminate\Support\Str;
7
use EasyPanel\Parsers\HTMLInputs\InputList;
8
use EasyPanel\Parsers\Fields\Field;
9
use EasyPanel\Parsers\HTMLInputs\BaseInput;
10
11
class StubParser
12
{
13
14
    public $texts = [];
15
    private $inputName;
16
    private $parsedModel;
17
18
    private $fields;
19
    private $inputs;
20
    private $validationRules;
21
    private $hasAuth;
22
    private $store;
23
24
    public function __construct($inputName, $parsedModel)
25
    {
26
        $this->inputName = $inputName;
27
        $this->parsedModel = $parsedModel;
28
    }
29
30
    public function setValidationRules($rules)
31
    {
32
        $this->validationRules = $rules;
33
    }
34
35
    public function setStore($store)
36
    {
37
        $this->store = $store;
38
    }
39
40
    public function setAuthType(bool $hasAuth){
41
        $this->hasAuth = $hasAuth;
42
    }
43
44
    public function setFields(array $fields){
45
        $this->fields = $fields;
46
    }
47
48
    public function setInputs(array $inputs){
49
        $this->inputs = $inputs;
50
    }
51
52
    public function replaceModel($stub)
53
    {
54
        $modelNamespace = $this->parsedModel;
55
        $modelName = $this->getModelName($modelNamespace);
56
57
        $array = [
58
            '{{ modelName }}' => ucfirst($modelName),
59
            '{{ modelNamespace }}' => $modelNamespace,
60
            '{{ uploadFile }}' => $this->uploadCodeParser(),
61
            '{{ model }}' => strtolower($modelName),
62
            '{{ properties }}' => $this->parseProperties(),
63
            '{{ rules }}' => $this->parseValidationRules(),
64
            '{{ fields }}' => $this->parseActionInComponent(),
65
            '{{ setProperties }}' => $this->parseSetPropertiesValue(),
66
        ];
67
68
        return str_replace(array_keys($array), array_values($array), $stub);
69
    }
70
71
    /**
72
     * Make Locale files
73
     */
74
    public function setLocaleTexts()
75
    {
76
        $this->texts[ucfirst($this->inputName)] = ucfirst($this->inputName);
77
        $this->texts[ucfirst(Str::plural($this->inputName))] = ucfirst(Str::plural($this->inputName));
78
        $files = File::glob(resource_path('lang').'/*_panel.json');
79
80
        foreach ($files as $file) {
81
            $decodedFile = json_decode(File::get($file), 1);
82
            $texts = $this->texts;
83
            foreach ($texts as $key => $text) {
84
                if (array_key_exists($key, $decodedFile)){
85
                    unset($texts[$text]);
86
                }
87
            }
88
            $array = array_merge($decodedFile, $texts);
89
            File::put($file, json_encode($array, JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE));
90
        }
91
    }
92
93
    /**
94
     * Get model name from namespace
95
     */
96
    public function getModelName($modelNamespace)
97
    {
98
        $array = explode('\\', $modelNamespace);
99
100
        return end($array);
101
    }
102
103
    /**
104
     * Parse properties in Livewire component
105
     */
106
    public function parseProperties()
107
    {
108
        $fields = array_keys($this->inputs);
109
        $str = '';
110
111
        if(in_array($this->inputName, $fields)){
112
            $this->error("Model name must not equal to column names, fix it and rerun command with -f flag");
0 ignored issues
show
Bug introduced by
The method error() does not exist on EasyPanel\Parsers\StubParser. ( Ignorable by Annotation )

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

112
            $this->/** @scrutinizer ignore-call */ 
113
                   error("Model name must not equal to column names, fix it and rerun command with -f flag");

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
113
            die;
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
114
        }
115
116
        foreach ($fields as $field) {
117
            $str .= 'public $'.$field.";".$this->makeTab(1);
118
        }
119
120
        return $str;
121
    }
122
123
    /**
124
     * Parse Uploading Code
125
     */
126
    public function uploadCodeParser()
127
    {
128
        $filesInput = array_keys($this->inputs, 'file');
129
        $str = '';
130
        foreach ($filesInput as $file) {
131
            // We get store path which has been defined in crud's config file
132
            $storePath = $this->store[$file] ?? "{$file}";
133
134
            // We get property value then store file in $storePath
135
            // A PHP Code for upload as a string will be created here
136
            $str .= $this->makeTab(2).'if($this->getPropertyValue(\''.$file.'\') and is_object($this->'.$file.')) {'.$this->makeTab(3);
137
            $str .= '$this->'.$file.' = $this->getPropertyValue(\''.$file.'\')->store(\''.$storePath.'\');'.$this->makeTab(2);
138
            $str .= '}'.PHP_EOL;
139
        }
140
141
        return $str;
142
    }
143
144
    /**
145
     * parse values for mount method in Livewire
146
     */
147
    public function parseSetPropertiesValue()
148
    {
149
        $fields = array_keys($this->inputs);
150
        $str = '';
151
        $action = $this->inputName;
152
        foreach ($fields as $field) {
153
            $str .= '$this->'.$field.' = $this->'.$action.'->'.$field.';';
154
            $str .= $this->makeTab(2, end($fields) != $field);
155
        }
156
157
        return $str;
158
    }
159
160
    /**
161
     * Parse Validation rules
162
     */
163
    public function parseValidationRules()
164
    {
165
        $str = '';
166
167
        foreach ($this->validationRules as $key => $rule) {
168
            $str .= "'$key' => '$rule',";
169
            $str .= $this->makeTab(2, $key != array_key_last($this->validationRules));
170
        }
171
172
        return $str;
173
    }
174
175
    /**
176
     * Create an array of properties in Livewire component for actions
177
     */
178
    public function parseActionInComponent()
179
    {
180
        $str = '';
181
182
        foreach ($this->inputs as $key => $field) {
183
            $newLine = ($field != end($this->inputs) or $this->hasAuth);
184
            $str .=  "'$key' => " . '$this' . "->$key,".$this->makeTab(3, $newLine);
185
        }
186
187
        if($this->hasAuth){
188
            $str .= "'user_id' => auth()->id(),";
189
        }
190
191
        return $str;
192
    }
193
194
    /**
195
     * Create Blade from stub
196
     */
197
    public function parseBlade($stub){
198
        $modelName = $this->getModelName($this->parsedModel);
199
200
        $array = [
201
            '{{ model }}' => strtolower($modelName),
202
            '{{ modelName }}' => ucfirst($modelName),
203
            '{{ data }}' => $this->parseDataInBlade(),
204
            '{{ titles }}' => $this->parseTitlesInBlade(),
205
            '{{ inputs }}' => $this->parseInputsInBlade(),
206
            '{{ routeName }}' => crud(strtolower($modelName))->route,
207
        ];
208
209
        $this->setLocaleTexts();
210
211
        return str_replace(array_keys($array), array_values($array), $stub);
212
    }
213
214
    /**
215
     * Parse <td> tags for data
216
     */
217
    public function parseDataInBlade()
218
    {
219
        $fields = $this->fields;
220
        $str = '';
221
        $modelName = strtolower($this->getModelName($this->parsedModel));
222
        foreach ($fields as $key => $field) {
223
            $normalizedField = $this->normalizeField($field);
224
            $str .= $normalizedField->setModel($modelName)->setKey($key)->renderData();
225
226
            $str .= $this->makeTab(1, false);
227
        }
228
229
        return $str;
230
    }
231
232
    /**
233
     * Parse <td> tags for head
234
     */
235
    public function parseTitlesInBlade()
236
    {
237
        $fields = $this->fields;
238
        $modelName = $this->getModelNameInLowerCase();
239
240
        $str = '';
241
        foreach ($fields as $key => $field) {
242
            // We will normalize the field value because most of users prefer to use simple mode
243
            // And they pass string and we will change it to a Field class object
244
            $normalizedField = $this->normalizeField($field);
245
246
            // Then we set the model and key to render the stub and get the string
247
            // The returned string concatenates with previous rendered fields
248
            $str .= $normalizedField->setModel($modelName)->setKey($key)->renderTitle();
249
250
            // To show the rendered html tag more readable and cleaner in view we make some tab
251
            $str .= $this->makeTab(7, false);
252
253
            // After all of this process, the Title will be pushed to the translatable list
254
            $this->texts[$field->getTitle()] = $field->getTitle();
255
        }
256
257
        return $str;
258
    }
259
260
    /**
261
     * Create inputs HTML
262
     */
263
    public function parseInputsInBlade()
264
    {
265
        $str = '';
266
        foreach ($this->inputs as $key => $type) {
267
            $inputObject = $this->normalizeInput($key, $type);
268
            $str .= $inputObject->setKey($key)->setAction($this->inputName)->render();
269
270
            $this->texts[$inputObject->getTitle()] = $inputObject->getTitle();
271
            if ($placeholder = $inputObject->getPlaceholder()){
272
                $this->texts[$placeholder] = $placeholder;
273
            }
274
        }
275
276
        return $str;
277
    }
278
279
    /**
280
     * Tab Maker (Each tabs mean 4 space)
281
     */
282
    public function makeTab($count, $newLine = true){
283
        $count = $count * 4;
284
        $tabs = str_repeat(' ', $count);
285
286
        return $newLine ? "\n".$tabs : $tabs;
287
    }
288
289
    public function getInputClassNamespace($type)
290
    {
291
        $type = is_array($type) ? array_key_first($type) : $type;
292
293
        return InputList::get($type);
294
    }
295
296
    private function normalizeField($field)
297
    {
298
        if($field instanceof Field){
299
            return $field;
300
        }
301
302
        $title = str_replace('.', ' ', $field);
303
        $title = ucwords($title);
304
        return Field::title($title);
305
    }
306
307
    private function normalizeInput($key, $input){
308
        if ($input instanceof BaseInput){
309
            return $input;
310
        }
311
312
        $type = is_array($input) ? array_key_first($input) : $input;
313
        $title = ucwords($key);
314
315
        return $this->getInputClassNamespace($type)::label($title);
316
    }
317
318
    private function getModelNameInLowerCase()
319
    {
320
        return strtolower($this->getModelName($this->parsedModel));
321
    }
322
323
}
324