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.
Passed
Pull Request — master (#106)
by Ross
18:39 queued 15:49
created

EntityGenerator::createEntityRepository()   A

Complexity

Conditions 3
Paths 26

Size

Total Lines 56
Code Lines 45

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

Changes 0
Metric Value
eloc 45
dl 0
loc 56
rs 9.2
c 0
b 0
f 0
ccs 0
cts 45
cp 0
cc 3
nc 26
nop 1
crap 12

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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->createEntityRepository($entityFqn);
59 4
            if (true === $generateSpecificEntitySaver) {
60
                $this->createEntitySaver($entityFqn);
61
            }
62
63 4
            $this->createInterface($entityFqn);
64
65 4
            return $this->createEntity($entityFqn);
66
        } catch (\Exception $e) {
67
            throw new DoctrineStaticMetaException(
68
                'Exception in ' . __METHOD__ . ': ' . $e->getMessage(),
69
                $e->getCode(),
70
                $e
71
            );
72
        }
73
    }
74
75
    /**
76
     * @param string $entityFullyQualifiedName
77
     *
78
     * @throws DoctrineStaticMetaException
79
     */
80
    protected function createEntityTest(string $entityFullyQualifiedName): void
81
    {
82
        try {
83
            $abstractTestPath = $this->pathToProjectRoot . '/'
84
                                . $this->testSubFolderName
85
                                . '/' . AbstractGenerator::ENTITIES_FOLDER_NAME
86
                                . '/AbstractEntityTest.php';
87
            if (!$this->getFilesystem()->exists($abstractTestPath)) {
88
                $this->getFilesystem()->copy(self::ABSTRACT_ENTITY_TEST_TEMPLATE_PATH, $abstractTestPath);
89
                $this->fileCreationTransaction::setPathCreated($abstractTestPath);
90
                $this->findAndReplaceHelper->findReplace(
91
                    self::FIND_PROJECT_NAMESPACE,
92
                    rtrim($this->projectRootNamespace, '\\'),
93
                    $abstractTestPath
94
                );
95
            }
96
97
            $phpunitBootstrapPath = $this->pathToProjectRoot . '/'
98
                                    . $this->testSubFolderName . '/bootstrap.php';
99
            if (!$this->getFilesystem()->exists($phpunitBootstrapPath)) {
100
                $this->getFilesystem()->copy(self::PHPUNIT_BOOTSTRAP_TEMPLATE_PATH, $phpunitBootstrapPath);
101
                $this->fileCreationTransaction::setPathCreated($phpunitBootstrapPath);
102
            }
103
104
            list($filePath, $className, $namespace) = $this->parseAndCreate(
105
                $entityFullyQualifiedName . 'Test',
106
                $this->testSubFolderName,
107
                self::ENTITY_TEST_TEMPLATE_PATH
108
            );
109
            $this->findAndReplaceHelper->findReplace(
110
                self::FIND_ENTITIES_NAMESPACE,
111
                $this->namespaceHelper->tidy($namespace),
112
                $filePath
113
            );
114
115
            $this->findAndReplaceHelper->replaceName($className, $filePath, self::FIND_ENTITY_NAME . 'Test');
116
            $this->findAndReplaceHelper->replaceProjectNamespace($this->projectRootNamespace, $filePath);
117
            $this->findAndReplaceHelper->replaceEntityRepositoriesNamespace($namespace, $filePath);
118
            $this->findAndReplaceHelper->findReplace(
119
                'use FQNFor\AbstractEntityTest;',
120
                'use ' . $this->namespaceHelper->tidy(
121
                    $this->projectRootNamespace
122
                    . '\\' . AbstractGenerator::ENTITIES_FOLDER_NAME
123
                    . '\\AbstractEntityTest;'
124
                ),
125
                $filePath
126
            );
127
        } catch (\Exception $e) {
128
            throw new DoctrineStaticMetaException(
129
                'Exception in ' . __METHOD__ . ': ' . $e->getMessage(),
130
                $e->getCode(),
131
                $e
132
            );
133
        }
134
    }
135
136
    /**
137
     * @throws DoctrineStaticMetaException
138
     */
139
    protected function parseAndCreate(
140
        string $fullyQualifiedName,
141
        string $subDir,
142
        string $templatePath
143
    ): array {
144
        try {
145
            list($className, $namespace, $subDirectories) = $this->parseFullyQualifiedName(
146
                $fullyQualifiedName,
147
                $subDir
148
            );
149
            $filePath = $this->pathHelper->copyTemplateAndGetPath(
150
                $this->pathToProjectRoot,
151
                $templatePath,
152
                $className,
153
                $subDirectories
154
            );
155
156
            return [$filePath, $className, $this->namespaceHelper->tidy($namespace)];
157
        } catch (\Exception $e) {
158
            throw new DoctrineStaticMetaException(
159
                'Exception in ' . __METHOD__ . ': ' . $e->getMessage(),
160
                $e->getCode(),
161
                $e
162
            );
163
        }
164
    }
165
166
    /**
167
     * @param string $entityFullyQualifiedName
168
     *
169
     * @throws DoctrineStaticMetaException
170
     */
171
    protected function createEntityRepository(string $entityFullyQualifiedName): void
172
    {
173
        try {
174
            $abstractRepositoryPath = $this->pathToProjectRoot
175
                                      . '/' . $this->srcSubFolderName
176
                                      . '/' . AbstractGenerator::ENTITY_REPOSITORIES_FOLDER_NAME
177
                                      . '/AbstractEntityRepository.php';
178
            if (!$this->getFilesystem()->exists($abstractRepositoryPath)) {
179
                $this->getFilesystem()->copy(
180
                    self::ABSTRACT_ENTITY_REPOSITORY_TEMPLATE_PATH,
181
                    $abstractRepositoryPath
182
                );
183
                $this->fileCreationTransaction::setPathCreated($abstractRepositoryPath);
184
                $this->findAndReplaceHelper->replaceEntityRepositoriesNamespace(
185
                    $this->projectRootNamespace . '\\'
186
                    . AbstractGenerator::ENTITY_REPOSITORIES_NAMESPACE,
187
                    $abstractRepositoryPath
188
                );
189
            }
190
            $entityRepositoryFqn = \str_replace(
191
                '\\' . AbstractGenerator::ENTITIES_FOLDER_NAME . '\\',
192
                '\\' . AbstractGenerator::ENTITY_REPOSITORIES_NAMESPACE . '\\',
193
                $entityFullyQualifiedName
194
            ) . 'Repository';
195
196
            list($filePath, $className, $namespace) = $this->parseAndCreate(
197
                $entityRepositoryFqn,
198
                $this->srcSubFolderName,
199
                self::REPOSITORIES_TEMPLATE_PATH
200
            );
201
            $this->findAndReplaceHelper->findReplace(
202
                self::FIND_ENTITY_REPOSITORIES_NAMESPACE,
203
                $this->namespaceHelper->tidy($namespace),
204
                $filePath
205
            );
206
            $classInterface = preg_replace('#Repository$#', 'Interface', $className);
207
208
            $this->findAndReplaceHelper->replaceName($className, $filePath, self::FIND_ENTITY_NAME . 'Repository');
209
            $this->findAndReplaceHelper->replaceProjectNamespace($this->projectRootNamespace, $filePath);
210
            $this->findAndReplaceHelper->replaceEntityRepositoriesNamespace($namespace, $filePath);
211
            $this->findAndReplaceHelper->replaceEntityInterfaceNamespace($namespace, $filePath);
212
            $this->findAndReplaceHelper->replaceName($classInterface, $filePath, self::FIND_ENTITY_NAME . 'Interface');
213
            $this->findAndReplaceHelper->findReplace(
214
                'use FQNFor\AbstractEntityRepository;',
215
                'use ' . $this->namespaceHelper->tidy(
216
                    $this->projectRootNamespace
217
                    . '\\' . AbstractGenerator::ENTITY_REPOSITORIES_NAMESPACE
218
                    . '\\AbstractEntityRepository;'
219
                ),
220
                $filePath
221
            );
222
        } catch (\Exception $e) {
223
            throw new DoctrineStaticMetaException(
224
                'Exception in ' . __METHOD__ . ': ' . $e->getMessage(),
225
                $e->getCode(),
226
                $e
227
            );
228
        }
229
    }
230
231
    /**
232
     * Create an entity saver
233
     *
234
     * @param string $entityFqn
235
     *
236
     * @throws DoctrineStaticMetaException
237
     * @SuppressWarnings(PHPMD.StaticAccess)
238
     */
239
    protected function createEntitySaver(string $entityFqn): void
240
    {
241
        $entitySaverFqn = \str_replace(
242
            '\\' . AbstractGenerator::ENTITIES_FOLDER_NAME . '\\',
243
            AbstractGenerator::ENTITY_SAVERS_NAMESPACE . '\\',
244
            $entityFqn
245
        ) . 'Saver';
246
247
248
        $entitySaver = new PhpClass();
249
        $entitySaver
250
            ->setQualifiedName($entitySaverFqn)
251
            ->setParentClassName('\\' . AbstractEntitySpecificSaver::class)
252
            ->setInterfaces(
253
                [
254
                    PhpInterface::fromFile(__DIR__ . '/../../Entity/Savers/EntitySaverInterface.php'),
255
                ]
256
            );
257
258
        list($className, , $subDirectories) = $this->parseFullyQualifiedName(
259
            $entitySaverFqn,
260
            $this->srcSubFolderName
261
        );
262
263
        $filePath = $this->createSubDirectoriesAndGetPath($subDirectories);
264
265
        $this->codeHelper->generate($entitySaver, $filePath . '/' . $className . '.php');
266
    }
267
268
    /**
269
     * @param string $entityFullyQualifiedName
270
     *
271
     * @throws DoctrineStaticMetaException
272
     */
273
    protected function createInterface(string $entityFullyQualifiedName): void
274
    {
275
        $entityInterfaceFqn = \str_replace(
276
            '\\' . AbstractGenerator::ENTITIES_FOLDER_NAME . '\\',
277
            '\\' . AbstractGenerator::ENTITY_INTERFACE_NAMESPACE . '\\',
278
            $entityFullyQualifiedName
279
        ) . 'Interface';
280
281
        list($className, $namespace, $subDirectories) = $this->parseFullyQualifiedName(
282
            $entityInterfaceFqn,
283
            $this->srcSubFolderName
284
        );
285
286
        $filePath = $this->pathHelper->copyTemplateAndGetPath(
287
            $this->pathToProjectRoot,
288
            self::ENTITY_INTERFACE_TEMPLATE_PATH,
289
            $className,
290
            $subDirectories
291
        );
292
293
        $this->findAndReplaceHelper->replaceName($className, $filePath, self::FIND_ENTITY_NAME . 'Interface');
294
        $this->findAndReplaceHelper->replaceEntityInterfaceNamespace($namespace, $filePath);
295
    }
296
297
    protected function createEntity(
298
        string $entityFullyQualifiedName
299
    ): string {
300
        list($filePath, $className, $namespace) = $this->parseAndCreate(
301
            $entityFullyQualifiedName,
302
            $this->srcSubFolderName,
303
            self::ENTITY_TEMPLATE_PATH
304
        );
305
        $this->findAndReplaceHelper->replaceName($className, $filePath, static::FIND_ENTITY_NAME);
306
        $this->findAndReplaceHelper->replaceEntitiesNamespace($namespace, $filePath);
307
        $this->findAndReplaceHelper->replaceEntityRepositoriesNamespace(
308
            \str_replace(
309
                '\\' . AbstractGenerator::ENTITIES_FOLDER_NAME,
310
                '\\' . AbstractGenerator::ENTITY_REPOSITORIES_NAMESPACE,
311
                $namespace
312
            ),
313
            $filePath
314
        );
315
316
        if ($this->getUseUuidPrimaryKey()) {
317
            $this->findAndReplaceHelper->findReplace(
318
                'IdFieldTrait',
319
                'UuidFieldTrait',
320
                $filePath
321
            );
322
        }
323
324
        $interfaceNamespace = \str_replace(
325
            '\\' . AbstractGenerator::ENTITIES_FOLDER_NAME,
326
            '\\' . AbstractGenerator::ENTITY_INTERFACE_NAMESPACE,
327
            $namespace
328
        );
329
330
        $this->findAndReplaceHelper->replaceEntityInterfaceNamespace($interfaceNamespace, $filePath);
331
332
        return $filePath;
333
    }
334
335
    public function getUseUuidPrimaryKey(): bool
336
    {
337
        return $this->useUuidPrimaryKey;
338
    }
339
340
    public function setUseUuidPrimaryKey(bool $useUuidPrimaryKey): self
341
    {
342
        $this->useUuidPrimaryKey = $useUuidPrimaryKey;
343
344
        return $this;
345
    }
346
347
    /**
348
     * Create the abstract entity repository factory if it doesn't currently exist
349
     */
350
    protected function createAbstractEntityRepositoryFactory(): void
351
    {
352
        $abstractRepositoryFactoryPath = $this->pathToProjectRoot
353
                                         . '/' . $this->srcSubFolderName
354
                                         . '/' . AbstractGenerator::ENTITY_REPOSITORIES_FOLDER_NAME
355
                                         . '/AbstractEntityRepositoryFactory.php';
356
357
        if ($this->getFilesystem()->exists($abstractRepositoryFactoryPath)) {
358
            return;
359
        }
360
361
        $abstractFactoryFqn = $this->projectRootNamespace
362
                              . AbstractGenerator::ENTITY_REPOSITORIES_NAMESPACE
363
                              . '\\AbstractEntityRepositoryFactory';
364
365
        $abstractFactory = new PhpClass();
366
        $abstractFactory
367
            ->setUseStatements([AbstractEntityRepository::class . ' as DSMRepositoryFactory'])
368
            ->setQualifiedName($abstractFactoryFqn)
369
            ->setParentClassName('DSMRepositoryFactory');
370
371
        $this->codeHelper->generate($abstractFactory, $abstractRepositoryFactoryPath);
372
    }
373
}
374