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 ( 51c99d...a4bf8a )
by joseph
24s queued 11s
created

getPropertyMetaMethodForDatetime()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 40

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

Changes 0
Metric Value
dl 0
loc 40
rs 9.28
c 0
b 0
f 0
ccs 0
cts 25
cp 0
cc 3
nc 3
nop 0
crap 12
1
<?php declare(strict_types=1);
2
3
namespace EdmondsCommerce\DoctrineStaticMeta\CodeGeneration\Generator\Field;
4
5
use Doctrine\ORM\Mapping\Builder\ClassMetadataBuilder;
6
use EdmondsCommerce\DoctrineStaticMeta\CodeGeneration\CodeHelper;
7
use EdmondsCommerce\DoctrineStaticMeta\CodeGeneration\Generator\FileCreationTransaction;
8
use EdmondsCommerce\DoctrineStaticMeta\CodeGeneration\Generator\FindAndReplaceHelper;
9
use EdmondsCommerce\DoctrineStaticMeta\CodeGeneration\PathHelper;
10
use EdmondsCommerce\DoctrineStaticMeta\CodeGeneration\TypeHelper;
11
use EdmondsCommerce\DoctrineStaticMeta\Entity\Interfaces\UsesPHPMetaDataInterface;
12
use EdmondsCommerce\DoctrineStaticMeta\Exception\DoctrineStaticMetaException;
13
use EdmondsCommerce\DoctrineStaticMeta\MappingHelper;
14
use gossi\codegen\model\PhpMethod;
15
use gossi\codegen\model\PhpParameter;
16
use gossi\codegen\model\PhpTrait;
17
use gossi\docblock\Docblock;
18
use gossi\docblock\tags\UnknownTag;
19
use Symfony\Component\Filesystem\Filesystem;
20
21
/**
22
 * Class DbalFieldGenerator
23
 *
24
 * @package EdmondsCommerce\DoctrineStaticMeta\CodeGeneration\Generator\Field
25
 * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
26
 * @SuppressWarnings(PHPMD.TooManyFields)
27
 */
28
class DbalFieldGenerator
29
{
30
    /**
31
     * @var string
32
     */
33
    protected $traitPath;
34
    /**
35
     * @var string
36
     */
37
    protected $interfacePath;
38
    /**
39
     * @var null|string
40
     */
41
    protected $phpType;
42
    /**
43
     * @var null
44
     */
45
    protected $defaultValue;
46
    /**
47
     * @var bool
48
     */
49
    protected $isUnique;
50
    /**
51
     * @var bool
52
     */
53
    protected $isNullable;
54
    /**
55
     * @var string
56
     */
57
    protected $dbalType;
58
    /**
59
     * @var Filesystem
60
     */
61
    protected $fileSystem;
62
    /**
63
     * @var CodeHelper
64
     */
65
    protected $codeHelper;
66
    /**
67
     * @var FileCreationTransaction
68
     */
69
    protected $fileCreationTransaction;
70
    /**
71
     * @var FindAndReplaceHelper
72
     */
73
    protected $findAndReplaceHelper;
74
    /**
75
     * @var string
76
     */
77
    protected $className;
78
    /**
79
     * @var TypeHelper
80
     */
81
    protected $typeHelper;
82
    /**
83
     * @var string
84
     */
85
    protected $traitNamespace;
86
    /**
87
     * @var string
88
     */
89
    protected $interfaceNamespace;
90
    /**
91
     * @var PathHelper
92
     */
93
    protected $pathHelper;
94
95 28
    public function __construct(
96
        Filesystem $fileSystem,
97
        CodeHelper $codeHelper,
98
        FileCreationTransaction $fileCreationTransaction,
99
        FindAndReplaceHelper $findAndReplaceHelper,
100
        TypeHelper $typeHelper,
101
        PathHelper $pathHelper
102
    ) {
103 28
        $this->fileSystem              = $fileSystem;
104 28
        $this->codeHelper              = $codeHelper;
105 28
        $this->fileCreationTransaction = $fileCreationTransaction;
106 28
        $this->findAndReplaceHelper    = $findAndReplaceHelper;
107 28
        $this->typeHelper              = $typeHelper;
108 28
        $this->pathHelper              = $pathHelper;
109 28
    }
110
111
    /**
112
     * @param string      $className
113
     * @param string      $traitPath
114
     * @param string      $interfacePath
115
     * @param string      $dbalType
116
     * @param null        $defaultValue
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $defaultValue is correct as it would always require null to be passed?
Loading history...
117
     * @param bool        $isUnique
118
     * @param null|string $phpType
119
     *
120
     * @param string      $traitNamespace
121
     * @param string      $interfaceNamespace
122
     *
123
     * @return string
124
     * @throws DoctrineStaticMetaException
125
     * @SuppressWarnings(PHPMD.BooleanArgumentFlag)
126
     */
127 28
    public function create(
128
        string $className,
129
        string $traitPath,
130
        string $interfacePath,
131
        string $dbalType,
132
        $defaultValue = null,
133
        bool $isUnique = false,
134
        ?string $phpType = null,
135
        string $traitNamespace,
136
        string $interfaceNamespace
137
    ): string {
138 28
        $this->traitPath          = $traitPath;
139 28
        $this->interfacePath      = $interfacePath;
140 28
        $this->phpType            = $phpType;
141 28
        $this->defaultValue       = $defaultValue;
142 28
        $this->isUnique           = $isUnique;
143 28
        $this->isNullable         = (null === $defaultValue);
144 28
        $this->dbalType           = $dbalType;
145 28
        $this->className          = $className;
146 28
        $this->traitNamespace     = $traitNamespace;
147 28
        $this->interfaceNamespace = $interfaceNamespace;
148 28
        $this->generateInterface();
149
150 28
        return $this->generateTrait();
151
    }
152
153
    /**
154
     * @throws DoctrineStaticMetaException
155
     * @SuppressWarnings(PHPMD.BooleanArgumentFlag)
156
     */
157 28
    protected function generateInterface(): void
158
    {
159
        try {
160 28
            $this->fileSystem->copy(
161 28
                $this->pathHelper->resolvePath(FieldGenerator::FIELD_INTERFACE_TEMPLATE_PATH),
162 28
                $this->interfacePath
163
            );
164 28
            $this->interfacePostCopy($this->interfacePath);
165 28
            $this->codeHelper->replaceTypeHintsInFile(
166 28
                $this->interfacePath,
167 28
                $this->phpType,
0 ignored issues
show
Bug introduced by
It seems like $this->phpType can also be of type null; however, parameter $type of EdmondsCommerce\Doctrine...eplaceTypeHintsInFile() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

167
                /** @scrutinizer ignore-type */ $this->phpType,
Loading history...
168 28
                $this->dbalType,
169 28
                $this->isNullable
170
            );
171
        } catch (\Exception $e) {
172
            throw new DoctrineStaticMetaException(
173
                'Error in '.__METHOD__.': '.$e->getMessage(),
174
                $e->getCode(),
175
                $e
176
            );
177
        }
178 28
    }
179
180
    /**
181
     * @param string $filePath
182
     *
183
     * @throws \RuntimeException
184
     * @throws DoctrineStaticMetaException
185
     */
186 28
    protected function postCopy(
187
        string $filePath
188
    ): void {
189 28
        $this->fileCreationTransaction::setPathCreated($filePath);
190 28
        $this->findAndReplaceHelper->replaceName(
191 28
            $this->codeHelper->classy($this->className),
192 28
            $filePath,
193 28
            FieldGenerator::FIND_ENTITY_FIELD_NAME
194
        );
195 28
        $this->findAndReplaceHelper->findReplace(
196 28
            $this->codeHelper->consty(FieldGenerator::FIND_ENTITY_FIELD_NAME),
197 28
            $this->codeHelper->consty($this->className),
198 28
            $filePath
199
        );
200 28
        $this->codeHelper->tidyNamespacesInFile($filePath);
201 28
        $this->setGetterToIsForBools($filePath);
202 28
    }
203
204
205 28
    protected function setGetterToIsForBools(
206
        string $filePath
207
    ): void {
208 28
        if ($this->phpType !== 'bool') {
209 28
            return;
210
        }
211 17
        $replaceName = $this->codeHelper->getGetterMethodNameForBoolean($this->codeHelper->classy($this->className));
212 17
        $findName    = 'get'.$this->codeHelper->classy($this->className);
213 17
        $this->findAndReplaceHelper->findReplace($findName, $replaceName, $filePath);
214 17
    }
215
216
217
    /**
218
     * @param string $filePath
219
     *
220
     * @throws \RuntimeException
221
     * @throws DoctrineStaticMetaException
222
     */
223 28
    protected function traitPostCopy(
224
        string $filePath
225
    ): void {
226 28
        $this->findAndReplaceHelper->replaceFieldTraitNamespace($this->traitNamespace, $filePath);
227 28
        $this->findAndReplaceHelper->replaceFieldInterfaceNamespace($this->interfaceNamespace, $filePath);
228 28
        $this->postCopy($filePath);
229 28
    }
230
231
    /**
232
     * @param string $filePath
233
     *
234
     * @throws DoctrineStaticMetaException
235
     */
236 28
    protected function interfacePostCopy(
237
        string $filePath
238
    ): void {
239 28
        $this->findAndReplaceHelper->replaceFieldInterfaceNamespace($this->interfaceNamespace, $filePath);
240 28
        $this->replaceDefaultValueInInterface($filePath);
241 28
        $this->postCopy($filePath);
242 28
    }
243
244
    /**
245
     * @param string $filePath
246
     * @SuppressWarnings(PHPMD.CyclomaticComplexity)
247
     */
248 28
    protected function replaceDefaultValueInInterface(
249
        string $filePath
250
    ): void {
251 28
        $defaultType = $this->typeHelper->getType($this->defaultValue);
252
        switch (true) {
253 28
            case $defaultType === 'null':
254 27
                $replace = 'null';
255 27
                break;
256 1
            case $this->phpType === 'string':
257
                $replace = "'$this->defaultValue'";
258
                break;
259 1
            case $this->phpType === 'bool':
260 1
                $replace = true === $this->defaultValue ? 'true' : 'false';
261 1
                break;
262 1
            case $this->phpType === 'float':
263 1
                $replace = (string)$this->defaultValue;
264 1
                if (false === strpos($replace, '.')) {
265 1
                    $replace .= '.0';
266
                }
267 1
                break;
268 1
            case $this->phpType === 'int':
269 1
                $replace = (string)$this->defaultValue;
270 1
                break;
271
            case $this->phpType === 'DateTime':
272
                if ($this->defaultValue !== null) {
273
                    throw new \InvalidArgumentException(
274
                        'Invalid default value '.$this->defaultValue
275
                        .'Currently we only support null as a default for DateTime'
276
                    );
277
                }
278
                $replace = 'null';
279
                break;
280
            default:
281
                throw new \RuntimeException(
282
                    'failed to calculate replace based on defaultType '.$defaultType
283
                    .' and phpType '.$this->phpType.' in '.__METHOD__
284
                );
285
        }
286 28
        $this->findAndReplaceHelper->findReplace("'defaultValue'", $replace, $filePath);
287 28
    }
288
289
290
    /**
291
     * @return string
292
     * @throws DoctrineStaticMetaException
293
     * @SuppressWarnings(PHPMD.StaticAccess)
294
     * @SuppressWarnings(PHPMD.BooleanArgumentFlag)
295
     */
296 28
    protected function generateTrait(): string
297
    {
298
        try {
299 28
            $this->fileSystem->copy(
300 28
                $this->pathHelper->resolvePath(FieldGenerator::FIELD_TRAIT_TEMPLATE_PATH),
301 28
                $this->traitPath
302
            );
303 28
            $this->fileCreationTransaction::setPathCreated($this->traitPath);
304 28
            $this->traitPostCopy($this->traitPath);
305 28
            $trait = PhpTrait::fromFile($this->traitPath);
306 28
            $trait->setMethod($this->getPropertyMetaMethod());
307 28
            $trait->addUseStatement('\\'.MappingHelper::class);
308 28
            $trait->addUseStatement('\\'.ClassMetadataBuilder::class);
309 28
            $this->codeHelper->generate($trait, $this->traitPath);
310 28
            $this->codeHelper->replaceTypeHintsInFile(
311 28
                $this->traitPath,
312 28
                $this->phpType,
0 ignored issues
show
Bug introduced by
It seems like $this->phpType can also be of type null; however, parameter $type of EdmondsCommerce\Doctrine...eplaceTypeHintsInFile() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

312
                /** @scrutinizer ignore-type */ $this->phpType,
Loading history...
313 28
                $this->dbalType,
314 28
                $this->isNullable
315
            );
316
317 28
            return $trait->getQualifiedName();
318
        } catch (\Exception $e) {
319
            throw new DoctrineStaticMetaException(
320
                'Error in '.__METHOD__.': '.$e->getMessage(),
321
                $e->getCode(),
322
                $e
323
            );
324
        }
325
    }
326
327
    /**
328
     * @return PhpMethod
329
     * @SuppressWarnings(PHPMD.StaticAccess)
330
     * @SuppressWarnings(PHPMD.BooleanArgumentFlag)
331
     */
332 28
    protected function getPropertyMetaMethod(): PhpMethod
333
    {
334 28
        $classy = $this->codeHelper->classy($this->className);
335 28
        $consty = $this->codeHelper->consty($this->className);
336 28
        $name   = UsesPHPMetaDataInterface::METHOD_PREFIX_GET_PROPERTY_DOCTRINE_META.$classy;
337 28
        $method = PhpMethod::create($name);
338 28
        $method->setStatic(true);
339 28
        $method->setVisibility('public');
340 28
        $method->setParameters(
341 28
            [PhpParameter::create('builder')->setType('ClassMetadataBuilder')]
342
        );
343 28
        $mappingHelperMethodName = 'setSimple'.ucfirst(strtolower($this->dbalType)).'Fields';
344
345
        $methodBody = "
346 28
        MappingHelper::$mappingHelperMethodName(
347 28
            [{$classy}FieldInterface::PROP_{$consty}],
348
            \$builder,
349 28
            {$classy}FieldInterface::DEFAULT_{$consty}
350
        );                        
351
";
352 28
        if (\in_array($this->dbalType, MappingHelper::UNIQUEABLE_TYPES, true)) {
353 28
            $isUniqueString = $this->isUnique ? 'true' : 'false';
354
            $methodBody     = "
355 28
        MappingHelper::$mappingHelperMethodName(
356 28
            [{$classy}FieldInterface::PROP_{$consty}],
357
            \$builder,
358 28
            {$classy}FieldInterface::DEFAULT_{$consty},
359 28
            $isUniqueString
360
        );                        
361
";
362
        }
363 28
        $method->setBody($methodBody);
364 28
        $method->setDocblock(
365 28
            Docblock::create()
366 28
                    ->appendTag(
367 28
                        UnknownTag::create('SuppressWarnings(PHPMD.StaticAccess)')
368
                    )
369
        );
370
371 28
        return $method;
372
    }
373
374
    /**
375
     * @return PhpMethod
376
     * @SuppressWarnings(PHPMD.StaticAccess)
377
     * @SuppressWarnings(PHPMD.BooleanArgumentFlag)
378
     */
379
    protected function getPropertyMetaMethodForDatetime(): PhpMethod
380
    {
381
        $classy = $this->codeHelper->classy($this->className);
382
        $consty = $this->codeHelper->consty($this->className);
383
        $name   = UsesPHPMetaDataInterface::METHOD_PREFIX_GET_PROPERTY_DOCTRINE_META.$classy;
384
        $method = PhpMethod::create($name);
385
        $method->setStatic(true);
386
        $method->setVisibility('public');
387
        $method->setParameters(
388
            [PhpParameter::create('builder')->setType('ClassMetadataBuilder')]
389
        );
390
        $mappingHelperMethodName = 'setSimple'.ucfirst(strtolower($this->dbalType)).'Fields';
391
392
        $methodBody = "
393
        MappingHelper::$mappingHelperMethodName(
394
            [{$classy}FieldInterface::PROP_{$consty}],
395
            \$builder,
396
            {$classy}FieldInterface::DEFAULT_{$consty}
397
        );                        
398
";
399
        if (\in_array($this->dbalType, MappingHelper::UNIQUEABLE_TYPES, true)) {
400
            $isUniqueString = $this->isUnique ? 'true' : 'false';
401
            $methodBody     = "
402
        MappingHelper::$mappingHelperMethodName(
403
            [{$classy}FieldInterface::PROP_{$consty}],
404
            \$builder,
405
            {$classy}FieldInterface::DEFAULT_{$consty},
406
            $isUniqueString
407
        );                        
408
";
409
        }
410
        $method->setBody($methodBody);
411
        $method->setDocblock(
412
            Docblock::create()
413
                    ->appendTag(
414
                        UnknownTag::create('SuppressWarnings(PHPMD.StaticAccess)')
415
                    )
416
        );
417
418
        return $method;
419
    }
420
}
421