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 ( c22d50...0bd9a0 )
by joseph
18s queued 11s
created

EntityGenerator::getUseUuidPrimaryKey()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
eloc 1
dl 0
loc 3
rs 10
c 0
b 0
f 0
ccs 0
cts 2
cp 0
cc 1
nc 1
nop 0
crap 2
1
<?php declare(strict_types=1);
2
3
namespace EdmondsCommerce\DoctrineStaticMeta\CodeGeneration\Generator;
4
5
use EdmondsCommerce\DoctrineStaticMeta\Entity\Repositories\AbstractEntityRepository;
6
use EdmondsCommerce\DoctrineStaticMeta\Entity\Savers\AbstractEntitySpecificSaver;
7
use EdmondsCommerce\DoctrineStaticMeta\Exception\DoctrineStaticMetaException;
8
use EdmondsCommerce\DoctrineStaticMeta\MappingHelper;
9
use gossi\codegen\model\PhpClass;
10
use gossi\codegen\model\PhpInterface;
11
12
class EntityGenerator extends AbstractGenerator
13
{
14
    /**
15
     * Flag to determine if a UUID primary key should be used for this entity.
16
     *
17
     * @var bool
18
     */
19
    protected $useUuidPrimaryKey = false;
20
21
    /**
22
     * @param string $entityFqn
23
     *
24
     * @param bool   $generateSpecificEntitySaver
25
     *
26
     * @return string - absolute path to created file
27
     * @throws DoctrineStaticMetaException
28
     * @SuppressWarnings(PHPMD.StaticAccess)
29
     * @SuppressWarnings(PHPMD.BooleanArgumentFlag)
30
     */
31 4
    public function generateEntity(
32
        string $entityFqn,
33
        bool $generateSpecificEntitySaver = false
34
    ): string {
35
        try {
36 4
            if (false === \ts\stringContains($entityFqn, '\\' . AbstractGenerator::ENTITIES_FOLDER_NAME . '\\')) {
37
                throw new \RuntimeException(
38
                    'Fully qualified name [' . $entityFqn
39
                    . '] does not include the Entities folder name ['
40
                    . AbstractGenerator::ENTITIES_FOLDER_NAME
41
                    . ']. Please ensure you pass in the full namespace qualified entity name'
42
                );
43
            }
44
45 4
            $shortName = MappingHelper::getShortNameForFqn($entityFqn);
46 4
            $plural    = MappingHelper::getPluralForFqn($entityFqn);
47 4
            $singular  = MappingHelper::getSingularForFqn($entityFqn);
48
49 4
            if (\strtolower($shortName) === $plural) {
50
                throw new \RuntimeException(
51
                    'Plural entity name used [' . $plural . ']. '
52
                    . 'Only singular entity names are allowed. '
53
                    . 'Please update this to [' . $singular . ']'
54
                );
55
            }
56
57 4
            $this->createEntityTest($entityFqn);
58 4
            $this->createEntityFixture($entityFqn);
59 4
            $this->createEntityRepository($entityFqn);
60 4
            if (true === $generateSpecificEntitySaver) {
61
                $this->createEntitySaver($entityFqn);
62
            }
63
64 4
            $this->createInterface($entityFqn);
65
66 4
            return $this->createEntity($entityFqn);
67
        } catch (\Exception $e) {
68
            throw new DoctrineStaticMetaException(
69
                'Exception in ' . __METHOD__ . ': ' . $e->getMessage(),
70
                $e->getCode(),
71
                $e
72
            );
73
        }
74
    }
75
76
    /**
77
     * @param string $entityFullyQualifiedName
78
     *
79
     * @throws DoctrineStaticMetaException
80
     */
81
    protected function createEntityTest(string $entityFullyQualifiedName): void
82
    {
83
        try {
84
            $abstractTestPath = $this->pathToProjectRoot . '/'
85
                                . $this->testSubFolderName
86
                                . '/' . AbstractGenerator::ENTITIES_FOLDER_NAME
87
                                . '/AbstractEntityTest.php';
88
            if (!$this->getFilesystem()->exists($abstractTestPath)) {
89
                $this->getFilesystem()->copy(self::ABSTRACT_ENTITY_TEST_TEMPLATE_PATH, $abstractTestPath);
90
                $this->fileCreationTransaction::setPathCreated($abstractTestPath);
91
                $this->findAndReplaceHelper->findReplace(
92
                    self::FIND_PROJECT_NAMESPACE,
93
                    rtrim($this->projectRootNamespace, '\\'),
94
                    $abstractTestPath
95
                );
96
            }
97
98
            $phpunitBootstrapPath = $this->pathToProjectRoot . '/'
99
                                    . $this->testSubFolderName . '/bootstrap.php';
100
            if (!$this->getFilesystem()->exists($phpunitBootstrapPath)) {
101
                $this->getFilesystem()->copy(self::PHPUNIT_BOOTSTRAP_TEMPLATE_PATH, $phpunitBootstrapPath);
102
                $this->fileCreationTransaction::setPathCreated($phpunitBootstrapPath);
103
            }
104
105
            list($filePath, $className, $namespace) = $this->parseAndCreate(
106
                $entityFullyQualifiedName . 'Test',
107
                $this->testSubFolderName,
108
                self::ENTITY_TEST_TEMPLATE_PATH
109
            );
110
            $this->findAndReplaceHelper->findReplace(
111
                self::FIND_ENTITIES_NAMESPACE,
112
                $this->namespaceHelper->tidy($namespace),
113
                $filePath
114
            );
115
116
            $this->findAndReplaceHelper->replaceName($className, $filePath, self::FIND_ENTITY_NAME . 'Test');
117
            $this->findAndReplaceHelper->replaceProjectNamespace($this->projectRootNamespace, $filePath);
118
            $this->findAndReplaceHelper->replaceEntityRepositoriesNamespace($namespace, $filePath);
119
            $this->findAndReplaceHelper->findReplace(
120
                'use FQNFor\AbstractEntityTest;',
121
                'use ' . $this->namespaceHelper->tidy(
122
                    $this->projectRootNamespace
123
                    . '\\' . AbstractGenerator::ENTITIES_FOLDER_NAME
124
                    . '\\AbstractEntityTest;'
125
                ),
126
                $filePath
127
            );
128
        } catch (\Exception $e) {
129
            throw new DoctrineStaticMetaException(
130
                'Exception in ' . __METHOD__ . ': ' . $e->getMessage(),
131
                $e->getCode(),
132
                $e
133
            );
134
        }
135
    }
136
137
    protected function createEntityFixture(string $entityFullyQualifiedName): void
138
    {
139
140
        list($filePath, $className, $namespace) = $this->parseAndCreate(
141
            $this->namespaceHelper->getFixtureFqnFromEntityFqn($entityFullyQualifiedName),
142
            $this->testSubFolderName,
143
            self::ENTITY_FIXTURE_TEMPLATE_PATH
144
        );
145
        $this->findAndReplaceHelper->findReplace(
146
            'TemplateNamespace\Assets\EntityFixtures',
147
            $this->namespaceHelper->tidy($namespace),
148
            $filePath
149
        );
150
        $this->findAndReplaceHelper->replaceName($className, $filePath, self::FIND_ENTITY_NAME . 'Fixture');
151
        $this->findAndReplaceHelper->replaceProjectNamespace($this->projectRootNamespace, $filePath);
152
    }
153
154
    /**
155
     * @throws DoctrineStaticMetaException
156
     */
157
    protected function parseAndCreate(
158
        string $fullyQualifiedName,
159
        string $subDir,
160
        string $templatePath
161
    ): array {
162
        try {
163
            list($className, $namespace, $subDirectories) = $this->parseFullyQualifiedName(
164
                $fullyQualifiedName,
165
                $subDir
166
            );
167
            $filePath = $this->pathHelper->copyTemplateAndGetPath(
168
                $this->pathToProjectRoot,
169
                $templatePath,
170
                $className,
171
                $subDirectories
172
            );
173
174
            return [$filePath, $className, $this->namespaceHelper->tidy($namespace)];
175
        } catch (\Exception $e) {
176
            throw new DoctrineStaticMetaException(
177
                'Exception in ' . __METHOD__ . ': ' . $e->getMessage(),
178
                $e->getCode(),
179
                $e
180
            );
181
        }
182
    }
183
184
    /**
185
     * @param string $entityFullyQualifiedName
186
     *
187
     * @throws DoctrineStaticMetaException
188
     */
189
    protected function createEntityRepository(string $entityFullyQualifiedName): void
190
    {
191
        try {
192
            $abstractRepositoryPath = $this->pathToProjectRoot
193
                                      . '/' . $this->srcSubFolderName
194
                                      . '/' . AbstractGenerator::ENTITY_REPOSITORIES_FOLDER_NAME
195
                                      . '/AbstractEntityRepository.php';
196
            if (!$this->getFilesystem()->exists($abstractRepositoryPath)) {
197
                $this->getFilesystem()->copy(
198
                    self::ABSTRACT_ENTITY_REPOSITORY_TEMPLATE_PATH,
199
                    $abstractRepositoryPath
200
                );
201
                $this->fileCreationTransaction::setPathCreated($abstractRepositoryPath);
202
                $this->findAndReplaceHelper->replaceEntityRepositoriesNamespace(
203
                    $this->projectRootNamespace . '\\'
204
                    . AbstractGenerator::ENTITY_REPOSITORIES_NAMESPACE,
205
                    $abstractRepositoryPath
206
                );
207
            }
208
            $entityRepositoryFqn = \str_replace(
209
                '\\' . AbstractGenerator::ENTITIES_FOLDER_NAME . '\\',
210
                '\\' . AbstractGenerator::ENTITY_REPOSITORIES_NAMESPACE . '\\',
211
                $entityFullyQualifiedName
212
            ) . 'Repository';
213
214
            list($filePath, $className, $namespace) = $this->parseAndCreate(
215
                $entityRepositoryFqn,
216
                $this->srcSubFolderName,
217
                self::REPOSITORIES_TEMPLATE_PATH
218
            );
219
            $this->findAndReplaceHelper->findReplace(
220
                self::FIND_ENTITY_REPOSITORIES_NAMESPACE,
221
                $this->namespaceHelper->tidy($namespace),
222
                $filePath
223
            );
224
            $classInterfaceNamespace = \str_replace(
225
                '\\' . AbstractGenerator::ENTITIES_FOLDER_NAME . '\\',
226
                '\\' . AbstractGenerator::ENTITY_INTERFACE_NAMESPACE . '\\',
227
                $entityFullyQualifiedName
228
            ) . 'Interface';
229
            $classInterface = preg_replace('#Repository$#', 'Interface', $className);
230
231
            $this->findAndReplaceHelper->replaceEntityInterfaceNamespace($classInterfaceNamespace, $filePath);
232
            $this->findAndReplaceHelper->replaceName($className, $filePath, self::FIND_ENTITY_NAME . 'Repository');
233
            $this->findAndReplaceHelper->replaceProjectNamespace($this->projectRootNamespace, $filePath);
234
            $this->findAndReplaceHelper->replaceEntityRepositoriesNamespace($namespace, $filePath);
235
            $this->findAndReplaceHelper->replaceName($classInterface, $filePath, self::FIND_ENTITY_NAME . 'Interface');
236
            $this->findAndReplaceHelper->findReplace(
237
                'use FQNFor\AbstractEntityRepository;',
238
                'use ' . $this->namespaceHelper->tidy(
239
                    $this->projectRootNamespace
240
                    . '\\' . AbstractGenerator::ENTITY_REPOSITORIES_NAMESPACE
241
                    . '\\AbstractEntityRepository;'
242
                ),
243
                $filePath
244
            );
245
        } catch (\Exception $e) {
246
            throw new DoctrineStaticMetaException(
247
                'Exception in ' . __METHOD__ . ': ' . $e->getMessage(),
248
                $e->getCode(),
249
                $e
250
            );
251
        }
252
    }
253
254
    /**
255
     * Create an entity saver
256
     *
257
     * @param string $entityFqn
258
     *
259
     * @throws DoctrineStaticMetaException
260
     * @SuppressWarnings(PHPMD.StaticAccess)
261
     */
262
    protected function createEntitySaver(string $entityFqn): void
263
    {
264
        $entitySaverFqn = \str_replace(
265
            '\\' . AbstractGenerator::ENTITIES_FOLDER_NAME . '\\',
266
            AbstractGenerator::ENTITY_SAVERS_NAMESPACE . '\\',
267
            $entityFqn
268
        ) . 'Saver';
269
270
271
        $entitySaver = new PhpClass();
272
        $entitySaver
273
            ->setQualifiedName($entitySaverFqn)
274
            ->setParentClassName('\\' . AbstractEntitySpecificSaver::class)
275
            ->setInterfaces(
276
                [
277
                    PhpInterface::fromFile(__DIR__ . '/../../Entity/Savers/EntitySaverInterface.php'),
278
                ]
279
            );
280
281
        list($className, , $subDirectories) = $this->parseFullyQualifiedName(
282
            $entitySaverFqn,
283
            $this->srcSubFolderName
284
        );
285
286
        $filePath = $this->createSubDirectoriesAndGetPath($subDirectories);
287
288
        $this->codeHelper->generate($entitySaver, $filePath . '/' . $className . '.php');
289
    }
290
291
    /**
292
     * @param string $entityFullyQualifiedName
293
     *
294
     * @throws DoctrineStaticMetaException
295
     */
296
    protected function createInterface(string $entityFullyQualifiedName): void
297
    {
298
        $entityInterfaceFqn = \str_replace(
299
            '\\' . AbstractGenerator::ENTITIES_FOLDER_NAME . '\\',
300
            '\\' . AbstractGenerator::ENTITY_INTERFACE_NAMESPACE . '\\',
301
            $entityFullyQualifiedName
302
        ) . 'Interface';
303
304
        list($className, $namespace, $subDirectories) = $this->parseFullyQualifiedName(
305
            $entityInterfaceFqn,
306
            $this->srcSubFolderName
307
        );
308
309
        $filePath = $this->pathHelper->copyTemplateAndGetPath(
310
            $this->pathToProjectRoot,
311
            self::ENTITY_INTERFACE_TEMPLATE_PATH,
312
            $className,
313
            $subDirectories
314
        );
315
316
        $this->findAndReplaceHelper->replaceName($className, $filePath, self::FIND_ENTITY_NAME . 'Interface');
317
        $this->findAndReplaceHelper->replaceEntityInterfaceNamespace($namespace, $filePath);
318
    }
319
320
    protected function createEntity(
321
        string $entityFullyQualifiedName
322
    ): string {
323
        list($filePath, $className, $namespace) = $this->parseAndCreate(
324
            $entityFullyQualifiedName,
325
            $this->srcSubFolderName,
326
            self::ENTITY_TEMPLATE_PATH
327
        );
328
        $this->findAndReplaceHelper->replaceName($className, $filePath, static::FIND_ENTITY_NAME);
329
        $this->findAndReplaceHelper->replaceEntitiesNamespace($namespace, $filePath);
330
        $this->findAndReplaceHelper->replaceEntityRepositoriesNamespace(
331
            \str_replace(
332
                '\\' . AbstractGenerator::ENTITIES_FOLDER_NAME,
333
                '\\' . AbstractGenerator::ENTITY_REPOSITORIES_NAMESPACE,
334
                $namespace
335
            ),
336
            $filePath
337
        );
338
339
        if ($this->getUseUuidPrimaryKey()) {
340
            $this->findAndReplaceHelper->findReplace(
341
                'IdFieldTrait',
342
                'UuidFieldTrait',
343
                $filePath
344
            );
345
        }
346
347
        $interfaceNamespace = \str_replace(
348
            '\\' . AbstractGenerator::ENTITIES_FOLDER_NAME,
349
            '\\' . AbstractGenerator::ENTITY_INTERFACE_NAMESPACE,
350
            $namespace
351
        );
352
353
        $this->findAndReplaceHelper->replaceEntityInterfaceNamespace($interfaceNamespace, $filePath);
354
355
        return $filePath;
356
    }
357
358
    public function getUseUuidPrimaryKey(): bool
359
    {
360
        return $this->useUuidPrimaryKey;
361
    }
362
363
    public function setUseUuidPrimaryKey(bool $useUuidPrimaryKey): self
364
    {
365
        $this->useUuidPrimaryKey = $useUuidPrimaryKey;
366
367
        return $this;
368
    }
369
370
    /**
371
     * Create the abstract entity repository factory if it doesn't currently exist
372
     */
373
    protected function createAbstractEntityRepositoryFactory(): void
374
    {
375
        $abstractRepositoryFactoryPath = $this->pathToProjectRoot
376
                                         . '/' . $this->srcSubFolderName
377
                                         . '/' . AbstractGenerator::ENTITY_REPOSITORIES_FOLDER_NAME
378
                                         . '/AbstractEntityRepositoryFactory.php';
379
380
        if ($this->getFilesystem()->exists($abstractRepositoryFactoryPath)) {
381
            return;
382
        }
383
384
        $abstractFactoryFqn = $this->projectRootNamespace
385
                              . AbstractGenerator::ENTITY_REPOSITORIES_NAMESPACE
386
                              . '\\AbstractEntityRepositoryFactory';
387
388
        $abstractFactory = new PhpClass();
389
        $abstractFactory
390
            ->setUseStatements([AbstractEntityRepository::class . ' as DSMRepositoryFactory'])
391
            ->setQualifiedName($abstractFactoryFqn)
392
            ->setParentClassName('DSMRepositoryFactory');
393
394
        $this->codeHelper->generate($abstractFactory, $abstractRepositoryFactoryPath);
395
    }
396
}
397