Passed
Push — master ( a31e1b...94e3ad )
by Reza
03:28
created

StubParser::getModelNameInLowerCase()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

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

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