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 (#59)
by joseph
17:21
created

replaceDefaultValueInInterface()   B

Complexity

Conditions 10
Paths 10

Size

Total Lines 39

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 18
CRAP Score 16.4

Importance

Changes 0
Metric Value
dl 0
loc 39
rs 7.6666
c 0
b 0
f 0
ccs 18
cts 30
cp 0.6
cc 10
nc 10
nop 1
crap 16.4

How to fix   Complexity   

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\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 27
    public function __construct(
96
        Filesystem $fileSystem,
97
        CodeHelper $codeHelper,
98
        FileCreationTransaction $fileCreationTransaction,
99
        FindAndReplaceHelper $findAndReplaceHelper,
100
        TypeHelper $typeHelper,
101
        PathHelper $pathHelper
102
    ) {
103 27
        $this->fileSystem              = $fileSystem;
104 27
        $this->codeHelper              = $codeHelper;
105 27
        $this->fileCreationTransaction = $fileCreationTransaction;
106 27
        $this->findAndReplaceHelper    = $findAndReplaceHelper;
107 27
        $this->typeHelper              = $typeHelper;
108 27
        $this->pathHelper              = $pathHelper;
109 27
    }
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 27
    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 27
        $this->traitPath          = $traitPath;
139 27
        $this->interfacePath      = $interfacePath;
140 27
        $this->phpType            = $phpType;
141 27
        $this->defaultValue       = $defaultValue;
142 27
        $this->isUnique           = $isUnique;
143 27
        $this->isNullable         = (null === $defaultValue);
144 27
        $this->dbalType           = $dbalType;
145 27
        $this->className          = $className;
146 27
        $this->traitNamespace     = $traitNamespace;
147 27
        $this->interfaceNamespace = $interfaceNamespace;
148 27
        $this->generateInterface();
149
150 27
        return $this->generateTrait();
151
    }
152
153
    /**
154
     * @throws DoctrineStaticMetaException
155
     * @SuppressWarnings(PHPMD.BooleanArgumentFlag)
156
     */
157 27
    protected function generateInterface(): void
158
    {
159
        try {
160 27
            $this->fileSystem->copy(
161 27
                $this->pathHelper->resolvePath(FieldGenerator::FIELD_INTERFACE_TEMPLATE_PATH),
162 27
                $this->interfacePath
163
            );
164 27
            $this->interfacePostCopy($this->interfacePath);
165 27
            $this->codeHelper->replaceTypeHintsInFile(
166 27
                $this->interfacePath,
167 27
                $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 27
                $this->dbalType,
169 27
                $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 27
    }
179
180
    /**
181
     * @param string $filePath
182
     *
183
     * @throws \RuntimeException
184
     * @throws DoctrineStaticMetaException
185
     */
186 27
    protected function postCopy(
187
        string $filePath
188
    ): void {
189 27
        $this->fileCreationTransaction::setPathCreated($filePath);
190 27
        $this->findAndReplaceHelper->replaceName(
191 27
            $this->codeHelper->classy($this->className),
192 27
            $filePath,
193 27
            FieldGenerator::FIND_ENTITY_FIELD_NAME
194
        );
195 27
        $this->findAndReplaceHelper->findReplace(
196 27
            $this->codeHelper->consty(FieldGenerator::FIND_ENTITY_FIELD_NAME),
197 27
            $this->codeHelper->consty($this->className),
198 27
            $filePath
199
        );
200 27
        $this->codeHelper->tidyNamespacesInFile($filePath);
201 27
        $this->setGetterToIsForBools($filePath);
202 27
    }
203
204
205 27
    protected function setGetterToIsForBools(
206
        string $filePath
207
    ): void {
208 27
        if ($this->phpType !== 'bool') {
209 27
            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 27
    protected function traitPostCopy(
224
        string $filePath
225
    ): void {
226 27
        $this->findAndReplaceHelper->replaceFieldTraitNamespace($this->traitNamespace, $filePath);
227 27
        $this->findAndReplaceHelper->replaceFieldInterfaceNamespace($this->interfaceNamespace, $filePath);
228 27
        $this->postCopy($filePath);
229 27
    }
230
231
    /**
232
     * @param string $filePath
233
     *
234
     * @throws DoctrineStaticMetaException
235
     */
236 27
    protected function interfacePostCopy(
237
        string $filePath
238
    ): void {
239 27
        $this->findAndReplaceHelper->replaceFieldInterfaceNamespace($this->interfaceNamespace, $filePath);
240 27
        $this->replaceDefaultValueInInterface($filePath);
241 27
        $this->postCopy($filePath);
242 27
    }
243
244
    /**
245
     * @param string $filePath
246
     * @SuppressWarnings(PHPMD.CyclomaticComplexity)
247
     */
248 27
    protected function replaceDefaultValueInInterface(
249
        string $filePath
250
    ): void {
251 27
        $defaultType = $this->typeHelper->getType($this->defaultValue);
252
        switch (true) {
253 27
            case $defaultType === 'null':
254 26
                $replace = 'null';
255 26
                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 27
        $this->findAndReplaceHelper->findReplace("'defaultValue'", $replace, $filePath);
287 27
    }
288
289
290
    /**
291
     * @return string
292
     * @throws DoctrineStaticMetaException
293
     * @SuppressWarnings(PHPMD.StaticAccess)
294
     * @SuppressWarnings(PHPMD.BooleanArgumentFlag)
295
     */
296 27
    protected function generateTrait(): string
297
    {
298
        try {
299 27
            $this->fileSystem->copy(
300 27
                $this->pathHelper->resolvePath(FieldGenerator::FIELD_TRAIT_TEMPLATE_PATH),
301 27
                $this->traitPath
302
            );
303 27
            $this->fileCreationTransaction::setPathCreated($this->traitPath);
304 27
            $this->traitPostCopy($this->traitPath);
305 27
            $trait = PhpTrait::fromFile($this->traitPath);
306 27
            $trait->setMethod($this->getPropertyMetaMethod());
307 27
            $trait->addUseStatement('\\'.MappingHelper::class);
308 27
            $trait->addUseStatement('\\'.ClassMetadataBuilder::class);
309 27
            $this->codeHelper->generate($trait, $this->traitPath);
310 27
            $this->codeHelper->replaceTypeHintsInFile(
311 27
                $this->traitPath,
312 27
                $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 27
                $this->dbalType,
314 27
                $this->isNullable
315
            );
316
317 27
            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 27
    protected function getPropertyMetaMethod(): PhpMethod
333
    {
334 27
        $classy = $this->codeHelper->classy($this->className);
335 27
        $consty = $this->codeHelper->consty($this->className);
336 27
        $name   = UsesPHPMetaDataInterface::METHOD_PREFIX_GET_PROPERTY_DOCTRINE_META.$classy;
337 27
        $method = PhpMethod::create($name);
338 27
        $method->setStatic(true);
339 27
        $method->setVisibility('public');
340 27
        $method->setParameters(
341 27
            [PhpParameter::create('builder')->setType('ClassMetadataBuilder')]
342
        );
343 27
        $mappingHelperMethodName = 'setSimple'.ucfirst(strtolower($this->dbalType)).'Fields';
344
345
        $methodBody = "
346 27
        MappingHelper::$mappingHelperMethodName(
347 27
            [{$classy}FieldInterface::PROP_{$consty}],
348
            \$builder,
349 27
            {$classy}FieldInterface::DEFAULT_{$consty}
350
        );                        
351
";
352 27
        if (\in_array($this->dbalType, MappingHelper::UNIQUEABLE_TYPES, true)) {
353 27
            $isUniqueString = $this->isUnique ? 'true' : 'false';
354
            $methodBody     = "
355 27
        MappingHelper::$mappingHelperMethodName(
356 27
            [{$classy}FieldInterface::PROP_{$consty}],
357
            \$builder,
358 27
            {$classy}FieldInterface::DEFAULT_{$consty},
359 27
            $isUniqueString
360
        );                        
361
";
362
        }
363 27
        $method->setBody($methodBody);
364 27
        $method->setDocblock(
365 27
            Docblock::create()
366 27
                    ->appendTag(
367 27
                        UnknownTag::create('SuppressWarnings(PHPMD.StaticAccess)')
368
                    )
369
        );
370
371 27
        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