GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Completed
Push — master ( d980e5...ab4a69 )
by joseph
13s queued 11s
created

Builder::setEnumOptionsOnInterface()   A

Complexity

Conditions 5
Paths 10

Size

Total Lines 46
Code Lines 31

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 30

Importance

Changes 0
Metric Value
eloc 31
dl 0
loc 46
ccs 0
cts 43
cp 0
rs 9.1128
c 0
b 0
f 0
cc 5
nc 10
nop 2
crap 30
1
<?php declare(strict_types=1);
2
3
namespace EdmondsCommerce\DoctrineStaticMeta\Builder;
4
5
use EdmondsCommerce\DoctrineStaticMeta\CodeGeneration\CodeHelper;
6
use EdmondsCommerce\DoctrineStaticMeta\CodeGeneration\Generator\Embeddable\ArchetypeEmbeddableGenerator;
7
use EdmondsCommerce\DoctrineStaticMeta\CodeGeneration\Generator\Embeddable\EntityEmbeddableSetter;
8
use EdmondsCommerce\DoctrineStaticMeta\CodeGeneration\Generator\EntityGenerator;
9
use EdmondsCommerce\DoctrineStaticMeta\CodeGeneration\Generator\Field\EntityFieldSetter;
10
use EdmondsCommerce\DoctrineStaticMeta\CodeGeneration\Generator\Field\FieldGenerator;
11
use EdmondsCommerce\DoctrineStaticMeta\CodeGeneration\Generator\RelationsGenerator;
12
use gossi\codegen\model\PhpClass;
13
use gossi\codegen\model\PhpConstant;
14
use gossi\codegen\model\PhpInterface;
15
use gossi\codegen\model\PhpTrait;
16
use ts\Reflection\ReflectionClass;
17
18
class Builder
19
{
20
21
    /**
22
     * @var EntityGenerator
23
     */
24
    protected $entityGenerator;
25
    /**
26
     * @var FieldGenerator
27
     */
28
    protected $fieldGenerator;
29
    /**
30
     * @var EntityFieldSetter
31
     */
32
    protected $fieldSetter;
33
    /**
34
     * @var RelationsGenerator
35
     */
36
    protected $relationsGenerator;
37
    /**
38
     * @var ArchetypeEmbeddableGenerator
39
     */
40
    protected $archetypeEmbeddableGenerator;
41
    /**
42
     * @var EntityEmbeddableSetter
43
     */
44
    protected $embeddableSetter;
45
    /**
46
     * @var CodeHelper
47
     */
48
    protected $codeHelper;
49
50
    public function __construct(
51
        EntityGenerator $entityGenerator,
52
        FieldGenerator $fieldGenerator,
53
        EntityFieldSetter $fieldSetter,
54
        RelationsGenerator $relationsGenerator,
55
        ArchetypeEmbeddableGenerator $archetypeEmbeddableGenerator,
56
        EntityEmbeddableSetter $embeddableSetter,
57
        CodeHelper $codeHelper
58
    ) {
59
        $this->entityGenerator              = $entityGenerator;
60
        $this->fieldGenerator               = $fieldGenerator;
61
        $this->fieldSetter                  = $fieldSetter;
62
        $this->relationsGenerator           = $relationsGenerator;
63
        $this->archetypeEmbeddableGenerator = $archetypeEmbeddableGenerator;
64
        $this->embeddableSetter             = $embeddableSetter;
65
        $this->codeHelper                   = $codeHelper;
66
    }
67
68
    /**
69
     * @return EntityGenerator
70
     */
71
    public function getEntityGenerator(): EntityGenerator
72
    {
73
        return $this->entityGenerator;
74
    }
75
76
    /**
77
     * @return FieldGenerator
78
     */
79
    public function getFieldGenerator(): FieldGenerator
80
    {
81
        return $this->fieldGenerator;
82
    }
83
84
    /**
85
     * @return EntityFieldSetter
86
     */
87
    public function getFieldSetter(): EntityFieldSetter
88
    {
89
        return $this->fieldSetter;
90
    }
91
92
    /**
93
     * @return RelationsGenerator
94
     */
95
    public function getRelationsGenerator(): RelationsGenerator
96
    {
97
        return $this->relationsGenerator;
98
    }
99
100
    /**
101
     * @return ArchetypeEmbeddableGenerator
102
     */
103
    public function getArchetypeEmbeddableGenerator(): ArchetypeEmbeddableGenerator
104
    {
105
        return $this->archetypeEmbeddableGenerator;
106
    }
107
108
    /**
109
     * @return EntityEmbeddableSetter
110
     */
111
    public function getEmbeddableSetter(): EntityEmbeddableSetter
112
    {
113
        return $this->embeddableSetter;
114
    }
115
116
    /**
117
     * @param array $entityFqns
118
     *
119
     * @return Builder
120
     * @throws \EdmondsCommerce\DoctrineStaticMeta\Exception\DoctrineStaticMetaException
121
     */
122
    public function generateEntities(array $entityFqns): self
123
    {
124
        foreach ($entityFqns as $entityFqn) {
125
            $this->entityGenerator->generateEntity($entityFqn);
126
        }
127
128
        return $this;
129
    }
130
131
    /**
132
     * @param array $entityRelationEntity
133
     *
134
     * @return Builder
135
     * @throws \EdmondsCommerce\DoctrineStaticMeta\Exception\DoctrineStaticMetaException
136
     */
137
    public function setEntityRelations(array $entityRelationEntity): self
138
    {
139
        foreach ($entityRelationEntity as [$owningEntityFqn, $hasType, $ownedEntityFqn]) {
140
            $this->relationsGenerator->setEntityHasRelationToEntity($owningEntityFqn, $hasType, $ownedEntityFqn);
141
        }
142
143
        return $this;
144
    }
145
146
    /**
147
     * @param array $fields
148
     *
149
     * @return array $traitFqns
150
     */
151
    public function generateFields(array $fields): array
152
    {
153
        $traitFqns = [];
154
        foreach ($fields as [$fieldFqn, $fieldType]) {
155
            try {
156
                $traitFqns[] = $this->fieldGenerator->generateField($fieldFqn, $fieldType);
157
            } catch (\Exception $e) {
158
                throw new \RuntimeException(
159
                    'Failed building field with $fieldFqn: ' . $fieldFqn . ' and $fieldType ' . $fieldType,
160
                    $e->getCode(),
161
                    $e
162
                );
163
            }
164
        }
165
166
        return $traitFqns;
167
    }
168
169
    /**
170
     * @param string $entityFqn
171
     * @param array  $fieldFqns
172
     *
173
     * @return Builder
174
     * @throws \EdmondsCommerce\DoctrineStaticMeta\Exception\DoctrineStaticMetaException
175
     */
176
    public function setFieldsToEntity(string $entityFqn, array $fieldFqns): self
177
    {
178
        foreach ($fieldFqns as $fieldFqn) {
179
            $this->fieldSetter->setEntityHasField($entityFqn, $fieldFqn);
180
        }
181
182
        return $this;
183
    }
184
185
    /**
186
     * @param array $embeddables
187
     *
188
     * @return array $traitFqns
189
     * @throws \EdmondsCommerce\DoctrineStaticMeta\Exception\DoctrineStaticMetaException
190
     * @throws \ReflectionException
191
     */
192
    public function generateEmbeddables(array $embeddables): array
193
    {
194
        $traitFqns = [];
195
        foreach ($embeddables as [$archetypeEmbeddableObjectFqn, $newEmbeddableObjectClassName]) {
196
            $traitFqns[] = $this->archetypeEmbeddableGenerator->createFromArchetype(
197
                $archetypeEmbeddableObjectFqn,
198
                $newEmbeddableObjectClassName
199
            );
200
        }
201
202
        return $traitFqns;
203
    }
204
205
    /**
206
     * @param string $entityFqn
207
     * @param array  $embeddableTraitFqns
208
     *
209
     * @return Builder
210
     */
211
    public function setEmbeddablesToEntity(string $entityFqn, array $embeddableTraitFqns): self
212
    {
213
        foreach ($embeddableTraitFqns as $embeddableTraitFqn) {
214
            $this->embeddableSetter->setEntityHasEmbeddable($entityFqn, $embeddableTraitFqn);
215
        }
216
217
        return $this;
218
    }
219
220
    public function setEnumOptionsOnInterface(string $pathToInterface, array $options): void
221
    {
222
        $basename  = basename($pathToInterface);
223
        $classy    = substr($basename, 0, strpos($basename, 'FieldInterface'));
224
        $consty    = $this->codeHelper->consty($classy);
225
        $interface = PhpInterface::fromFile($pathToInterface);
226
        $constants = $interface->getConstants();
227
        foreach ($constants as $constant) {
228
            /**
229
             * @var $constant PhpConstant
230
             */
231
            if (0 === strpos($constant->getName(), $consty . '_OPTION')) {
232
                $interface->removeConstant($constant);
233
            }
234
            if (0 === strpos($constant->getName(), 'DEFAULT')) {
235
                $interface->removeConstant($constant);
236
            }
237
        }
238
        $optionConsts = [];
239
        foreach ($options as $option) {
240
            $name           = \str_replace(
241
                '__',
242
                '_',
243
                $consty . '_OPTION_' . $this->codeHelper->consty(
244
                    \str_replace(' ', '_', $option)
245
                )
246
            );
247
            $optionConsts[] = 'self::' . $name;
248
            $constant       = new PhpConstant($name, $option);
249
            $interface->setConstant($constant);
250
        }
251
        $interface->setConstant(
252
            new PhpConstant(
253
                $consty . '_OPTIONS',
254
                '[' . implode(",\n", $optionConsts) . ']',
255
                true
256
            )
257
        );
258
        $interface->setConstant(
259
            new PhpConstant(
260
                'DEFAULT_' . $consty,
261
                current($optionConsts),
262
                true
263
            )
264
        );
265
        $this->codeHelper->generate($interface, $pathToInterface);
266
    }
267
268
    public function injectTraitInToClass(string $traitFqn, string $classFqn): void
269
    {
270
        $classFilePath = $this->getFileName($classFqn);
271
        $class         = PhpClass::fromFile($classFilePath);
272
        $trait         = PhpTrait::fromFile($this->getFileName($traitFqn));
273
        $traits        = $class->getTraits();
274
        $exists        = array_search($traitFqn, $traits, true);
275
        if ($exists !== false) {
276
            return;
277
        }
278
        $class->addTrait($trait);
279
        $this->codeHelper->generate($class, $classFilePath);
280
    }
281
282
    public function extendInterfaceWithInterface(string $interfaceToExtendFqn, string $interfaceToAddFqn): void
283
    {
284
        $toExtendFilePath = $this->getFileName($interfaceToExtendFqn);
285
        $toExtend         = PhpInterface::fromFile($toExtendFilePath);
286
        $toAdd            = PhpInterface::fromFile($this->getFileName($interfaceToAddFqn));
287
        $exists           = $toExtend->getInterfaces()->contains($interfaceToAddFqn);
288
        if ($exists !== false) {
289
            return;
290
        }
291
        $toExtend->addInterface($toAdd);
292
        $this->codeHelper->generate($toExtend, $toExtendFilePath);
293
    }
294
295
    public function removeIdTraitFromClass(string $classFqn): void
296
    {
297
        $traitFqn = "DSM\\Fields\\Traits\\PrimaryKey\\IdFieldTrait";
298
        $this->removeTraitFromClass($classFqn, $traitFqn);
299
    }
300
301
    public function removeTraitFromClass(string $classFqn, string $traitFqn): void
302
    {
303
        $classPath = $this->getFileName($classFqn);
304
        $class     = PhpClass::fromFile($classPath);
305
        $traits    = $class->getTraits();
306
        if ($class->getUseStatements()->contains($traitFqn) === true) {
307
            $class->removeUseStatement($traitFqn);
308
        }
309
        $index = array_search($traitFqn, $traits, true);
310
        if ($index === false) {
311
            $shortNameParts = explode('\\', $traitFqn);
312
            $shortName      = (string) array_pop($shortNameParts);
313
            $index          = array_search($shortName, $traits, true);
314
        }
315
        if ($index === false) {
316
            return;
317
        }
318
        unset($traits[$index]);
319
        $reflectionClass = new ReflectionClass(PhpClass::class);
320
        $property        = $reflectionClass->getProperty('traits');
321
        $property->setAccessible(true);
322
        $property->setValue($class, $traits);
323
        $this->codeHelper->generate($class, $classPath);
324
    }
325
326
    private function getFileName(string $typeFqn): string
327
    {
328
        $reflectionClass = new ReflectionClass($typeFqn);
329
330
        return $reflectionClass->getFileName();
331
    }
332
}
333