Issues (157)

src/Blocks/Entities.php (4 issues)

1
<?php
2
3
namespace SoliDry\Blocks;
4
5
use Illuminate\Database\Eloquent\SoftDeletes;
6
use SoliDry\Extension\BaseFormRequest;
7
use SoliDry\Extension\BaseModel;
8
use SoliDry\Helpers\Classes;
9
use SoliDry\Helpers\Console;
10
use SoliDry\Helpers\MethodOptions;
11
use SoliDry\Helpers\MigrationsHelper;
12
use SoliDry\ApiGenerator;
13
use SoliDry\Types\CustomsInterface;
14
use SoliDry\Types\DefaultInterface;
15
use SoliDry\Types\ModelsInterface;
16
use SoliDry\Types\PhpInterface;
17
use SoliDry\Types\ApiInterface;
18
19
/**
20
 * Class FormRequest
21
 * @package SoliDry\Blocks
22
 * @property ApiGenerator generator
23
 */
24
class Entities extends FormRequestModel
25
{
26
    use ContentManager, EntitiesTrait;
0 ignored issues
show
The trait SoliDry\Blocks\EntitiesTrait requires the property $types which is not provided by SoliDry\Blocks\Entities.
Loading history...
The trait SoliDry\Blocks\ContentManager requires some properties which are not provided by SoliDry\Blocks\Entities: $options, $version, $modulesDir
Loading history...
27
    /** @var ApiGenerator $generator */
28
    private $generator;
29
    private $className;
30
31
    protected $sourceCode   = '';
32
    protected $localCode    = '';
33
    protected $isSoftDelete = false;
34
35
    public function __construct($generator)
36
    {
37
        $this->generator = $generator;
38
        $this->className = Classes::getClassName($this->generator->objectName);
39
        $isSoftDelete    = empty($this->generator->types[$this->generator->objectName . CustomsInterface::CUSTOM_TYPES_ATTRIBUTES]
40
                                 [ApiInterface::RAML_PROPS][ModelsInterface::COLUMN_DEL_AT]) === false;
41
        $this->setIsSoftDelete($isSoftDelete);
42
    }
43
44
    public function setCodeState($generator)
45
    {
46
        $this->generator = $generator;
47
    }
48
49
    /**
50
     * @return bool
51
     */
52
    public function isSoftDelete() : bool
53
    {
54
        return $this->isSoftDelete;
55
    }
56
57
    /**
58
     * @param bool $isSoftDelete
59
     */
60
    public function setIsSoftDelete(bool $isSoftDelete) : void
61
    {
62
        $this->isSoftDelete = $isSoftDelete;
63
    }
64
65
    private function setRelations()
66
    {
67
        $formRequestEntity = $this->getFormRequestEntity($this->generator->version, $this->className);
68
        /** @var BaseFormRequest $formRequest * */
69
        $formRequest = new $formRequestEntity();
70
        if (method_exists($formRequest, ModelsInterface::MODEL_METHOD_RELATIONS)) {
71
            $this->sourceCode .= PHP_EOL;
72
            $relations        = $formRequest->relations();
73
            foreach ($relations as $relationEntity) {
74
                $ucEntitty = ucfirst($relationEntity);
75
                // determine if ManyToMany, OneToMany, OneToOne rels
76
                $current = $this->getRelationType($this->generator->objectName);
77
                $related = $this->getRelationType($ucEntitty);
78
                if (empty($current) === false && empty($related) === false) {
79
                    $this->createRelationMethod($current, $related, $relationEntity);
80
                }
81
            }
82
        }
83
    }
84
85
    /**
86
     * @param string $current current entity relations
87
     * @param string $related entities from raml file based on relations method array
88
     * @param string $relationEntity
89
     */
90
    private function createRelationMethod(string $current, string $related, string $relationEntity)
91
    {
92
        $ucEntitty   = ucfirst($relationEntity);
93
        $currentRels = explode(PhpInterface::PIPE, $current);
94
        $relatedRels = explode(PhpInterface::PIPE, $related);
95
        foreach ($relatedRels as $rel) {
96
            if (strpos($rel, $this->generator->objectName) !== false) {
97
                foreach ($currentRels as $cur) {
98
                    if (strpos($cur, $ucEntitty) !== false) {
99
                        $isManyCurrent = strpos($cur, self::CHECK_MANY_BRACKETS);
100
                        $isManyRelated = strpos($rel, self::CHECK_MANY_BRACKETS);
101
                        if ($isManyCurrent === false && $isManyRelated === false) {// OneToOne
102
                            $this->setRelation($relationEntity, ModelsInterface::MODEL_METHOD_HAS_ONE);
103
                        }
104
                        if ($isManyCurrent !== false && $isManyRelated === false) {// ManyToOne
105
                            $this->setRelation($relationEntity, ModelsInterface::MODEL_METHOD_HAS_MANY);
106
                        }
107
                        if ($isManyCurrent === false && $isManyRelated !== false) {// OneToMany inverse
108
                            $this->setRelation($relationEntity, ModelsInterface::MODEL_METHOD_BELONGS_TO);
109
                        }
110
                        if ($isManyCurrent !== false && $isManyRelated !== false) {// ManyToMany
111
                            // check inversion of a pivot
112
                            $entityFile = $this->generator->formatEntitiesPath()
113
                                . PhpInterface::SLASH . $this->generator->objectName .
114
                                ucfirst($relationEntity) .
115
                                PhpInterface::PHP_EXT;
116
                            $relEntity  = $relationEntity;
117
                            $objName    = $this->generator->objectName;
118
                            if (file_exists($entityFile) === false) {
119
                                $relEntity = $this->generator->objectName;
120
                                $objName   = $relationEntity;
121
                            }
122
                            $this->setRelation(
123
                                $relationEntity, ModelsInterface::MODEL_METHOD_BELONGS_TO_MANY,
124
                                MigrationsHelper::getTableName($objName . ucfirst($relEntity))
125
                            );
126
                        }
127
                    }
128
                }
129
            }
130
        }
131
    }
132
133
    /**
134
     * @param string $ucEntity
135
     */
136
    public function setPivot(string $ucEntity)
137
    {
138
        $file = $this->generator->formatEntitiesPath() .
139
            PhpInterface::SLASH .
140
            $this->className . Classes::getClassName($ucEntity) . PhpInterface::PHP_EXT;
141
        if ($this->generator->isMerge === true) {
142
            $this->resetPivotContent($ucEntity, $file);
143
        } else {
144
            $this->setPivotContent($ucEntity);
145
        }
146
        $isCreated = FileManager::createFile(
147
            $file, $this->sourceCode,
148
            FileManager::isRegenerated($this->generator->options)
149
        );
150
        if ($isCreated) {
151
            Console::out($file . PhpInterface::SPACE . Console::CREATED, Console::COLOR_GREEN);
152
        }
153
    }
154
155
    public function createPivot()
156
    {
157
        $formRequestEntity = $this->getFormRequestEntity($this->generator->version, $this->className);
158
        /** @var BaseFormRequest $formRequest * */
159
        $formRequest = new $formRequestEntity();
160
        if (method_exists($formRequest, ModelsInterface::MODEL_METHOD_RELATIONS)) {
161
            $relations        = $formRequest->relations();
162
            $this->sourceCode .= PHP_EOL; // margin top from props
163
            foreach ($relations as $relationEntity) {
164
                $ucEntitty = ucfirst($relationEntity);
165
                $file      = $this->generator->formatEntitiesPath()
166
                    . PhpInterface::SLASH . ucfirst($relationEntity) . $this->generator->objectName .
167
                    PhpInterface::PHP_EXT;
168
                // check if inverse Entity pivot exists
169
                if (file_exists($file) === false) {
170
                    // determine if ManyToMany, OneToMany, OneToOne rels
171
                    $current = $this->getRelationType($this->generator->objectName);
172
                    $related = $this->getRelationType($ucEntitty);
173
                    if (empty($current) === false && empty($related) === false) {
174
                        $this->createPivotClass($current, $related, $relationEntity);
175
                    }
176
                }
177
            }
178
        }
179
    }
180
181
    /**
182
     * @param string $current current entity relations
183
     * @param string $related entities from raml file based on relations method array
184
     * @param string $relationEntity
185
     */
186
    private function createPivotClass(string $current, string $related, string $relationEntity)
187
    {
188
        $ucEntitty   = ucfirst($relationEntity);
189
        $currentRels = explode(PhpInterface::PIPE, $current);
190
        $relatedRels = explode(PhpInterface::PIPE, $related);
191
        foreach ($relatedRels as $rel) {
192
            if (strpos($rel, $this->generator->objectName) !== false) {
193
                foreach ($currentRels as $cur) {
194
                    if (strpos($cur, $ucEntitty) !== false) {
195
                        $isManyCurrent = strpos($cur, self::CHECK_MANY_BRACKETS);
196
                        $isManyRelated = strpos($rel, self::CHECK_MANY_BRACKETS);
197
                        if ($isManyCurrent !== false && $isManyRelated !== false) {// ManyToMany
198
                            $this->setPivot($ucEntitty);
199
                        }
200
                    }
201
                }
202
            }
203
        }
204
    }
205
206
    /**
207
     * @param string $entity
208
     * @param string $method
209
     * @param \string[] ...$args
210
     */
211
    private function setRelation(string $entity, string $method, string ...$args)
212
    {
213
        $methodOptions = new MethodOptions();
214
        $methodOptions->setName($entity);
215
        $this->startMethod($methodOptions);
216
        $toReturn = $this->getRelationReturn($entity, $method, $args);
217
        $this->setMethodReturn($toReturn);
218
        $this->endMethod(1);
219
    }
220
221
    /**
222
     * @param string $entity
223
     * @param string $method
224
     * @param \string[] ...$args
225
     * @return string
226
     */
227
    private function getRelationReturn(string $entity, string $method, array $args)
228
    {
229
        $toReturn = PhpInterface::DOLLAR_SIGN . PhpInterface::PHP_THIS
230
            . PhpInterface::ARROW . $method
231
            . PhpInterface::OPEN_PARENTHESES . Classes::getClassName($entity)
232
            . PhpInterface::DOUBLE_COLON . PhpInterface::PHP_CLASS;
233
234
        if (empty($args) === false) {
235
            foreach ($args as $val) {
236
                $toReturn .= PhpInterface::COMMA
237
                    . PhpInterface::SPACE . PhpInterface::QUOTES . $val .
238
                    PhpInterface::QUOTES;
239
            }
240
        }
241
        $toReturn .= PhpInterface::CLOSE_PARENTHESES;
242
        return $toReturn;
243
    }
244
245
    /**
246
     * Sets entity content to $sourceCode
247
     */
248
    private function setContent()
0 ignored issues
show
The method setContent() is not used, and could be removed.

This check looks for private methods that have been defined, but are not used inside the class.

Loading history...
249
    {
250
        $this->setTag();
251
        $this->setNamespace(
252
            $this->generator->entitiesDir
253
        );
254
        $baseMapper     = BaseModel::class;
255
        $baseMapperName = Classes::getName($baseMapper);
256
257
        if ($this->isSoftDelete()) {
258
            $this->setUse(SoftDeletes::class);
259
        }
260
261
        $this->setUse($baseMapper, false, true);
262
        $this->startClass($this->className, $baseMapperName);
263
        $this->setUseSoftDelete();
264
        $this->setComment(DefaultInterface::PROPS_START);
265
        $this->setPropSoftDelete();
266
        $this->createProperty(
267
            ModelsInterface::PROPERTY_PRIMARY_KEY, PhpInterface::PHP_MODIFIER_PROTECTED,
268
            ApiInterface::RAML_ID, true
269
        );
270
        $this->createProperty(
271
            ModelsInterface::PROPERTY_TABLE, PhpInterface::PHP_MODIFIER_PROTECTED,
272
            strtolower($this->generator->objectName), true
273
        );
274
        $this->createProperty(
275
            ModelsInterface::PROPERTY_TIMESTAMPS, PhpInterface::PHP_MODIFIER_PUBLIC,
276
            PhpInterface::PHP_TYPES_BOOL_FALSE
277
        );
278
        $this->setIncrementingProperty();
279
        $this->setComment(DefaultInterface::PROPS_END);
280
        $this->setComment(DefaultInterface::METHOD_START);
281
        $this->setRelations();
282
        $this->setComment(DefaultInterface::METHOD_END);
283
        $this->endClass();
284
    }
285
286
    private function setIncrementingProperty()
287
    {
288
        // O(4)
289
        $idObject = $this->generator->types[$this->generator->types[$this->generator->objectName][ApiInterface::RAML_PROPS][ApiInterface::RAML_ID]];
290
        if ($idObject[ApiInterface::RAML_TYPE] === ApiInterface::RAML_TYPE_STRING) {
291
            $this->createProperty(
292
                ModelsInterface::PROPERTY_INCREMENTING, PhpInterface::PHP_MODIFIER_PUBLIC,
293
                PhpInterface::PHP_TYPES_BOOL_FALSE
294
            );
295
        }
296
    }
297
298
    /**
299
     * Sets entity content to $sourceCode
300
     */
301
    private function resetContent()
0 ignored issues
show
The method resetContent() is not used, and could be removed.

This check looks for private methods that have been defined, but are not used inside the class.

Loading history...
302
    {
303
        $this->setBeforeProps($this->getEntityFile($this->generator->formatEntitiesPath()));
304
        $this->setComment(DefaultInterface::PROPS_START, 0);
305
        $this->createProperty(
306
            ModelsInterface::PROPERTY_PRIMARY_KEY, PhpInterface::PHP_MODIFIER_PROTECTED,
307
            ApiInterface::RAML_ID, true
308
        );
309
        $this->createProperty(
310
            ModelsInterface::PROPERTY_TABLE, PhpInterface::PHP_MODIFIER_PROTECTED,
311
            strtolower($this->generator->objectName), true
312
        );
313
        $this->createProperty(
314
            ModelsInterface::PROPERTY_TIMESTAMPS, PhpInterface::PHP_MODIFIER_PUBLIC,
315
            PhpInterface::PHP_TYPES_BOOL_FALSE
316
        );
317
        $this->setAfterProps(DefaultInterface::METHOD_START);
318
        $this->setComment(DefaultInterface::METHOD_START, 0);
319
        $this->setRelations();
320
        $this->setAfterMethods();
321
    }
322
323
    /**
324
     *  Sets pivot entity content to $sourceCode
325
     * @param string $ucEntity an entity upper case first name
326
     */
327
    private function setPivotContent(string $ucEntity)
328
    {
329
        $this->setTag();
330
        $this->setNamespace(
331
            $this->generator->entitiesDir
332
        );
333
        $baseMapper     = BaseModel::class;
334
        $baseMapperName = Classes::getName($baseMapper);
335
336
        $this->setUse($baseMapper, false, true);
337
        $this->startClass($this->className . Classes::getClassName($ucEntity), $baseMapperName);
338
        $this->setComment(DefaultInterface::PROPS_START);
339
        $this->createProperty(
340
            ModelsInterface::PROPERTY_PRIMARY_KEY, PhpInterface::PHP_MODIFIER_PROTECTED,
341
            ApiInterface::RAML_ID, true
342
        );
343
        $this->createProperty(
344
            ModelsInterface::PROPERTY_TABLE, PhpInterface::PHP_MODIFIER_PROTECTED,
345
            strtolower($this->generator->objectName . PhpInterface::UNDERSCORE . $ucEntity), true
346
        );
347
        $this->createProperty(
348
            ModelsInterface::PROPERTY_TIMESTAMPS, PhpInterface::PHP_MODIFIER_PUBLIC,
349
            PhpInterface::PHP_TYPES_BOOL_TRUE
350
        );
351
        $this->setComment(DefaultInterface::PROPS_END);
352
        $this->endClass();
353
    }
354
355
    /**
356
     *  Re-Sets pivot entity content to $sourceCode
357
     * @param string $ucEntity an entity upper case first name
358
     * @param string $file
359
     */
360
    private function resetPivotContent(string $ucEntity, string $file)
361
    {
362
        $this->setBeforeProps($file);
363
        $this->setComment(DefaultInterface::PROPS_START, 0);
364
        $this->createProperty(
365
            ModelsInterface::PROPERTY_PRIMARY_KEY, PhpInterface::PHP_MODIFIER_PROTECTED,
366
            ApiInterface::RAML_ID, true
367
        );
368
        $this->createProperty(
369
            ModelsInterface::PROPERTY_TABLE, PhpInterface::PHP_MODIFIER_PROTECTED,
370
            strtolower($this->generator->objectName . PhpInterface::UNDERSCORE . $ucEntity), true
371
        );
372
        $this->createProperty(
373
            ModelsInterface::PROPERTY_TIMESTAMPS, PhpInterface::PHP_MODIFIER_PUBLIC,
374
            PhpInterface::PHP_TYPES_BOOL_TRUE
375
        );
376
        $this->setAfterProps();
377
    }
378
}