Passed
Push — master ( 43342b...911e23 )
by Reza
14:51
created

StubParser::getInputClassNamespace()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 17
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

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

118
            $this->/** @scrutinizer ignore-call */ 
119
                   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...
119
            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...
120
        }
121
122
        foreach ($fields as $field) {
123
            $str .= 'public $'.$field.";".$this->makeTab(1);
124
        }
125
126
        return $str;
127
    }
128
129
    /**
130
     * Parse Uploading Code
131
     */
132
    public function uploadCodeParser()
133
    {
134
        $filesInput = array_keys($this->inputs, 'file');
135
        $str = '';
136
        foreach ($filesInput as $file) {
137
            // We get store path which has been defined in crud's config file
138
            $storePath = $this->store[$file] ?? "{$file}";
139
140
            // We get property value then store file in $storePath
141
            // A PHP Code for upload as a string will be created here
142
            $str .= $this->makeTab(2).'if($this->getPropertyValue(\''.$file.'\') and is_object($this->'.$file.')) {'.$this->makeTab(3);
143
            $str .= '$this->'.$file.' = $this->getPropertyValue(\''.$file.'\')->store(\''.$storePath.'\');'.$this->makeTab(2);
144
            $str .= '}'.PHP_EOL;
145
        }
146
147
        return $str;
148
    }
149
150
    /**
151
     * parse values for mount method in Livewire
152
     */
153
    public function parseSetPropertiesValue()
154
    {
155
        $fields = array_keys($this->inputs);
156
        $str = '';
157
        $action = $this->inputName;
158
        foreach ($fields as $field) {
159
            $str .= '$this->'.$field.' = $this->'.$action.'->'.$field.';'.$this->makeTab(2, end($fields) != $field);
160
        }
161
162
        return $str;
163
    }
164
165
    /**
166
     * Parse Validation rules
167
     */
168
    public function parseValidationRules()
169
    {
170
        $str = '';
171
172
        foreach ($this->validationRules as $key => $rule) {
173
            $str .= "'$key' => '$rule',".$this->makeTab(2, $rule != end($this->validationRules));
174
        }
175
176
        return $str;
177
    }
178
179
    /**
180
     * Create an array of properties in Livewire component for actions
181
     */
182
    public function parseActionInComponent()
183
    {
184
        $str = '';
185
186
        foreach ($this->inputs as $key => $field) {
187
            $newLine = ($field != end($this->inputs) or $this->hasAuth);
188
            $str .=  "'$key' => " . '$this' . "->$key,".$this->makeTab(3, $newLine);
189
        }
190
191
        if($this->hasAuth){
192
            $str .= "'user_id' => auth()->id(),";
193
        }
194
195
        return $str;
196
    }
197
198
    /**
199
     * Create Blade from stub
200
     */
201
    public function parseBlade($stub){
202
        $modelName = $this->getModelName($this->parsedModel);
203
204
        $array = [
205
            '{{ model }}' => strtolower($modelName),
206
            '{{ modelName }}' => ucfirst($modelName),
207
            '{{ data }}' => $this->parseDataInBlade(),
208
            '{{ titles }}' => $this->parseTitlesInBlade(),
209
            '{{ inputs }}' => $this->parseInputsInBlade(),
210
            '{{ routeName }}' => crud(strtolower($modelName))->route,
211
        ];
212
213
        $this->setLocaleTexts();
214
215
        return str_replace(array_keys($array), array_values($array), $stub);
216
    }
217
218
    /**
219
     * Parse <td> tags for data
220
     */
221
    public function parseDataInBlade()
222
    {
223
        $fields = $this->fields;
224
        $str = '';
225
        $modelName = strtolower($this->getModelName($this->parsedModel));
226
        foreach ($fields as $value) {
227
            if (!Str::contains($value, '.')) {
228
                if(!in_array($value, ['image', 'photo', 'profile', 'banner'])) {
229
                    $str .= '<td> {{ $' . $modelName . '->' . $value . " }} </td>" . $this->makeTab(1, end($fields) != $value);
230
                } else {
231
                    $str .= '<td><a target="_blank" href="{{ asset($' . $modelName . '->' . $value . ') }}"><img class="rounded-circle img-fluid" width="50" height="50" src="{{ asset($' . $modelName . '->' . $value . ') }}" alt="'.$value.'"></a></td>' . $this->makeTab(1, end($fields) != $value);
232
                }
233
            } else {
234
                $newValue = $this->parseDots($value);
235
                $str .= '<td> {{ $' . $modelName . '->' . $newValue .' }} </td>' . $this->makeTab(1, end($fields) != $value);
236
            }
237
        }
238
239
        return $str;
240
    }
241
242
    /**
243
     * Parse <td> tags for head
244
     */
245
    public function parseTitlesInBlade()
246
    {
247
        $fields = $this->fields;
248
        $str = '';
249
        foreach ($fields as $field) {
250
            if (!Str::contains($field, '.')) {
251
                $sortName = $field;
252
                $field = ucfirst($field);
253
                $str .= "<td style='cursor: pointer' wire:click=\"sort('$sortName')\"> <i class='fa @if(".'$sortType'." == 'desc' and ".'$sortColumn'." == '$sortName') fa-sort-amount-down ml-2 @elseif(".'$sortType == '."'asc' and ".'$sortColumn'." == '$sortName') fa-sort-amount-up ml-2 @endif'></i> {{ __('$field') }} </td>".$this->makeTab(6, end($fields) != $field);
254
            } else {
255
                $newLine = end($fields) != $field;
256
                $field = $this->parseFieldNameWithDots($field);
257
                $str .= "<td> {{ __('$field') }} </td>".$this->makeTab(6, $newLine);
258
            }
259
            $this->texts[$field] = $field;
260
        }
261
262
        return $str;
263
    }
264
265
    /**
266
     * Create inputs HTML
267
     */
268
    public function parseInputsInBlade()
269
    {
270
        $str = '';
271
        foreach ($this->inputs as $name => $type) {
272
            $title = ucfirst($name);
273
            $this->texts[$title] = ucfirst($name);
274
            $class = $this->getInputClassNamespace($type);
275
            $str .= (new $class($name, $this->inputName))->render();
276
        }
277
278
        return $str;
279
    }
280
281
    /**
282
     * Tab Maker (Each tabs mean 4 space)
283
     */
284
    public function makeTab($count, $newLine = true){
285
        $count = $count * 4;
286
        $tabs = str_repeat(' ', $count);
287
288
        return $newLine ? "\n".$tabs : $tabs;
289
    }
290
291
    public function parseDots($string)
292
    {
293
        return str_replace('.', '->', $string);
294
    }
295
296
    public function parseFieldNameWithDots($field)
297
    {
298
        $array = explode('.', $field);
299
        $str = '';
300
        foreach ($array as $value){
301
            $str .= ucfirst($value)." ";
302
        }
303
304
        return trim($str);
305
    }
306
307
    public function getInputClassNamespace($type)
308
    {
309
        $type = is_array($type) ? array_key_first($type) : $type;
310
311
        $classMap = [
312
            'password' => Password::class,
313
            'text' => Text::class,
314
            'file' => FileInput::class,
315
            'email' => Email::class,
316
            'number' => Number::class,
317
            'textarea' => Textarea::class,
318
            'select' => Select::class,
319
            'ckeditor' => Ckeditor::class,
320
            'checkbox' => Checkbox::class,
321
        ];
322
323
        return $classMap[$type];
324
    }
325
326
}
327