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
Pull Request — master (#54)
by joseph
28:13 queued 24:17
created

EntityGenerator   A

Complexity

Total Complexity 22

Size/Duplication

Total Lines 342
Duplicated Lines 0 %

Test Coverage

Coverage 82.81%

Importance

Changes 0
Metric Value
wmc 22
dl 0
loc 342
ccs 159
cts 192
cp 0.8281
rs 10
c 0
b 0
f 0

10 Methods

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