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 ( fe6969...c3c1f4 )
by joseph
18s queued 12s
created

EntityGenerator::createEntityRepository()   A

Complexity

Conditions 3
Paths 20

Size

Total Lines 53
Code Lines 42

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 37
CRAP Score 3.0151

Importance

Changes 0
Metric Value
eloc 42
dl 0
loc 53
ccs 37
cts 42
cp 0.881
rs 9.248
c 0
b 0
f 0
nc 20
nop 1
cc 3
crap 3.0151

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