MakeFormParamCommand::getSettersBody()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 0 Features 0
Metric Value
cc 2
eloc 4
c 3
b 0
f 0
nc 2
nop 1
dl 0
loc 8
rs 10
1
<?php
2
3
/**
4
 * Platine Framework
5
 *
6
 * Platine Framework is a lightweight, high-performance, simple and elegant
7
 * PHP Web framework
8
 *
9
 * This content is released under the MIT License (MIT)
10
 *
11
 * Copyright (c) 2020 Platine Framework
12
 *
13
 * Permission is hereby granted, free of charge, to any person obtaining a copy
14
 * of this software and associated documentation files (the "Software"), to deal
15
 * in the Software without restriction, including without limitation the rights
16
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
17
 * copies of the Software, and to permit persons to whom the Software is
18
 * furnished to do so, subject to the following conditions:
19
 *
20
 * The above copyright notice and this permission notice shall be included in all
21
 * copies or substantial portions of the Software.
22
 *
23
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
26
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
28
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
29
 * SOFTWARE.
30
 */
31
32
/**
33
 *  @file MakeFormParamCommand.php
34
 *
35
 *  The Make form parameter Command class
36
 *
37
 *  @package    Platine\Framework\Console\Command
38
 *  @author Platine Developers team
39
 *  @copyright  Copyright (c) 2020
40
 *  @license    http://opensource.org/licenses/MIT  MIT License
41
 *  @link   https://www.platine-php.com
42
 *  @version 1.0.0
43
 *  @filesource
44
 */
45
46
declare(strict_types=1);
47
48
namespace Platine\Framework\Console\Command;
49
50
use Platine\Console\Input\Reader;
51
use Platine\Console\Output\Writer;
52
use Platine\Filesystem\Filesystem;
53
use Platine\Framework\App\Application;
54
use Platine\Framework\Console\MakeCommand;
55
use Platine\Stdlib\Helper\Str;
56
57
/**
58
 * @class MakeFormParamCommand
59
 * @package Platine\Framework\Console\Command
60
 */
61
class MakeFormParamCommand extends MakeCommand
62
{
63
    /**
64
     * {@inheritdoc}
65
     */
66
    protected string $type = 'form parameter';
67
68
    /**
69
     * Whether to create instance from entity
70
     * @var bool
71
     */
72
    protected bool $createInstanceFormEntity = false;
73
74
    /**
75
     * The list of properties entity field maps
76
     * @var array<string, string>
77
     */
78
    protected array $fromEntityMaps = [];
79
80
    /**
81
     * Create new instance
82
     * @param Application $application
83
     * @param Filesystem $filesystem
84
     */
85
    public function __construct(
86
        Application $application,
87
        Filesystem $filesystem
88
    ) {
89
        parent::__construct($application, $filesystem);
90
91
        $this->setName('make:param')
92
               ->setDescription('Command to generate new form parameter class');
93
    }
94
95
    /**
96
     * {@inheritdoc}
97
     */
98
    public function interact(Reader $reader, Writer $writer): void
99
    {
100
        parent::interact($reader, $writer);
101
102
        $properties = [];
103
104
        $io = $this->io();
105
        $writer->boldYellow('Enter the properties list (empty value to finish):', true);
106
        $value = '';
107
        while ($value !== null) {
108
            $value = $io->prompt('Property name', null, null, false);
109
110
            if (!empty($value)) {
111
                $value = trim($value);
112
                $type = 'string';
113
                $required = true;
114
                $default = null;
115
116
                // 0 = field name, 1 = data type, 2 = required (true/false), 3 = default value
117
                $values = (array) explode(':', $value);
118
                if (!empty($values[0])) {
119
                    $value = $values[0];
120
                }
121
122
                if (isset($values[1]) && !empty($values[1])) {
123
                    $type = $values[1];
124
                }
125
126
                if (isset($values[2])) {
127
                    $required = in_array($values[2], ['true', '1', 'yes', 'on', 'y']) ;
128
                }
129
130
                if (isset($values[3])) {
131
                    $default = $values[3];
132
                }
133
134
                $name = Str::camel($value, true);
135
136
                $properties[$name] = [
137
                    'name' => $name,
138
                    'short' => $type, // needed by super class
139
                    'type' => $type,
140
                    'required' => $required,
141
                    'default' => $default,
142
                ];
143
            }
144
        }
145
146
        $this->properties = $properties;
147
148
        if (count($this->properties) > 0) {
149
            $this->createInstanceFormEntity = $io->confirm('Create instance from entity ?', 'y');
150
151
            if ($this->createInstanceFormEntity) {
152
                $list = [];
153
                foreach ($this->properties as $name => $info) {
154
                    $value = $io->prompt(
155
                        sprintf('Entity field name for [%s] (just enter to ignore)', $name),
156
                        null,
157
                        null,
158
                        false
159
                    );
160
161
                    if (!empty($value)) {
162
                        $list[$name] = $value;
163
                    }
164
                }
165
166
                if (count($list) > 0) {
167
                    $this->fromEntityMaps = $list;
168
                }
169
            }
170
        }
171
    }
172
173
    /**
174
     * {@inheritdoc}
175
     */
176
    public function getClassTemplate(): string
177
    {
178
        return <<<EOF
179
        <?php
180
        
181
        declare(strict_types=1);
182
        
183
        namespace %namespace%;
184
        
185
        use Platine\Framework\Form\Param\BaseParam;
186
        %uses%
187
188
        /**
189
        * @class %classname%
190
        * @package %namespace%
191
        * %template_entity%
192
        */
193
        class %classname% extends BaseParam
194
        {
195
            %properties%
196
            %from_entity%
197
            %getters%
198
            %setters%
199
        }
200
        
201
        EOF;
202
    }
203
204
    /**
205
     * {@inheritdoc}
206
     */
207
    protected function createClass(): string
208
    {
209
        $content = parent::createClass();
210
211
        $fromEntity = $this->getFromEntityBody($content);
212
        $setters = $this->getSettersBody($fromEntity);
213
214
        return $this->getGettersBody($setters);
215
    }
216
217
    /**
218
     * Return the setters body
219
     * @param string $content
220
     * @return string
221
     */
222
    protected function getSettersBody(string $content): string
223
    {
224
        $result = '';
225
        foreach ($this->properties as $info) {
226
            $result .= $this->getSetterTemplate($info);
227
        }
228
229
        return str_replace('%setters%', $result, $content);
230
    }
231
232
    /**
233
     * Return the getter body
234
     * @param string $content
235
     * @return string
236
     */
237
    protected function getGettersBody(string $content): string
238
    {
239
        $result = '';
240
241
        foreach ($this->properties as $info) {
242
            $result .= $this->getGetterTemplate($info);
243
        }
244
245
        return str_replace('%getters%', $result, $content);
246
    }
247
248
    /**
249
     * Return the setter template
250
     * @param array<string, mixed> $info
251
     * @return string
252
     */
253
    protected function getSetterTemplate(array $info): string
254
    {
255
        $name = $info['name'];
256
        $type = $info['type'];
257
        $typeDockBlock = $type;
258
        $typeArg = $type;
259
        $required = $info['required'];
260
        if ($required === false) {
261
            $typeDockBlock .= '|null';
262
            $typeArg = '?' . $typeArg;
263
        }
264
        $cleanName = Str::snake($name, ' ');
265
        $setterName = 'set' . Str::ucfirst($name);
266
267
        return <<<EOF
268
        /**
269
            * Set the $cleanName value 
270
            * @param $typeDockBlock \$$name 
271
            * @return \$this
272
            */
273
           public function $setterName($typeArg \$$name): self
274
           {
275
               \$this->$name = \$$name;
276
                
277
               return \$this;
278
           }
279
           
280
           
281
        EOF;
282
    }
283
284
    /**
285
     * Return the getter template
286
     * @param array<string, mixed> $info
287
     * @return string
288
     */
289
    protected function getGetterTemplate(array $info): string
290
    {
291
        $name = $info['name'];
292
        $type = $info['type'];
293
        $typeDockBlock = $type;
294
        $typeReturn = $type;
295
        $required = $info['required'];
296
        if ($required === false) {
297
            $typeDockBlock .= '|null';
298
            $typeReturn = '?' . $typeReturn;
299
        }
300
        $cleanName = Str::snake($name, ' ');
301
        $getterName = 'get' . Str::ucfirst($name);
302
303
        return <<<EOF
304
        /**
305
            * Return the $cleanName value 
306
            * @return $typeDockBlock
307
            */
308
           public function $getterName(): $typeReturn
309
           {
310
               return \$this->$name;
311
           }
312
           
313
           
314
        EOF;
315
    }
316
317
    /**
318
     * Return the from entity body
319
     * @param string $content
320
     * @return string
321
     */
322
    protected function getFromEntityBody(string $content): string
323
    {
324
        $result = '';
325
        $templateEntity = '';
326
        if ($this->createInstanceFormEntity && count($this->fromEntityMaps) > 0) {
327
            $templateEntity = '@template TEntity as Entity';
328
            $result = <<<EOF
329
            /**
330
                * @param TEntity \$entity
331
                * @return \$this
332
                */
333
               public function fromEntity(Entity \$entity): self
334
               {
335
                
336
            EOF;
337
            foreach ($this->fromEntityMaps as $property => $map) {
338
                $result .= <<<EOF
339
                \$this->$property = \$entity->$map;
340
                
341
            EOF;
342
            }
343
344
            $result .= <<<EOF
345
                
346
                   return \$this;
347
               }
348
            
349
            EOF;
350
        }
351
352
        $template = (string) str_replace('%from_entity%', $result, $content);
353
354
        return str_replace('%template_entity%', $templateEntity, $template);
355
    }
356
357
    /**
358
     * {@inheritdoc}
359
     */
360
    protected function getPropertyTemplate(string $className, array $info): string
361
    {
362
        $name = $info['name'];
363
        $cleanName = Str::snake($name, ' ');
364
365
        $default = $info['default'];
366
        $type = $info['type'];
367
        $typeDockBlock = $type;
368
        $typeProp = $type;
369
        $required = $info['required'];
370
        if ($required === false) {
371
            $typeDockBlock .= '|null';
372
            $typeProp = '?' . $typeProp;
373
        }
374
375
        if ($default === null && $required === false) {
376
            $default = 'null';
377
        }
378
379
        if ($default !== null) {
380
            if ($type === 'string' && empty($default)) {
381
                $default = '\'\'';
382
            }
383
384
            $default = ' = ' . $default;
385
        } else {
386
            $default = '';
387
        }
388
389
        return <<<EOF
390
        /**
391
            * The $cleanName field
392
            * @var $typeDockBlock
393
            */
394
            protected $typeProp \$$name$default;
395
        
396
            
397
        EOF;
398
    }
399
400
    /**
401
     * {@inheritdoc}
402
     */
403
    protected function getUsesContent(): string
404
    {
405
        if ($this->createInstanceFormEntity === false) {
406
            return '';
407
        }
408
409
        return <<<EOF
410
        use Platine\Orm\Entity; 
411
        
412
        EOF;
413
    }
414
}
415