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

DbalFieldGenerator::postCopy()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 16
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 12
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 16
rs 9.4285
c 0
b 0
f 0
ccs 12
cts 12
cp 1
cc 1
eloc 11
nc 1
nop 1
crap 1
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\TypeHelper;
10
use EdmondsCommerce\DoctrineStaticMeta\Entity\Interfaces\UsesPHPMetaDataInterface;
11
use EdmondsCommerce\DoctrineStaticMeta\Exception\DoctrineStaticMetaException;
12
use EdmondsCommerce\DoctrineStaticMeta\MappingHelper;
13
use gossi\codegen\model\PhpMethod;
14
use gossi\codegen\model\PhpParameter;
15
use gossi\codegen\model\PhpTrait;
16
use gossi\docblock\Docblock;
17
use gossi\docblock\tags\UnknownTag;
18
use Symfony\Component\Filesystem\Filesystem;
19
20
/**
21
 * Class DbalFieldGenerator
22
 *
23
 * @package EdmondsCommerce\DoctrineStaticMeta\CodeGeneration\Generator\Field
24
 * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
25
 */
26
class DbalFieldGenerator
27
{
28
    /**
29
     * @var string
30
     */
31
    protected $traitPath;
32
    /**
33
     * @var string
34
     */
35
    protected $interfacePath;
36
    /**
37
     * @var null|string
38
     */
39
    protected $phpType;
40
    /**
41
     * @var null
42
     */
43
    protected $defaultValue;
44
    /**
45
     * @var bool
46
     */
47
    protected $isUnique;
48
    /**
49
     * @var bool
50
     */
51
    protected $isNullable;
52
    /**
53
     * @var string
54
     */
55
    protected $dbalType;
56
    /**
57
     * @var Filesystem
58
     */
59
    protected $fileSystem;
60
    /**
61
     * @var CodeHelper
62
     */
63
    protected $codeHelper;
64
    /**
65
     * @var FileCreationTransaction
66
     */
67
    protected $fileCreationTransaction;
68
    /**
69
     * @var FindAndReplaceHelper
70
     */
71
    protected $findAndReplaceHelper;
72
    /**
73
     * @var string
74
     */
75
    protected $className;
76
    /**
77
     * @var TypeHelper
78
     */
79
    protected $typeHelper;
80
    /**
81
     * @var string
82
     */
83
    protected $traitNamespace;
84
    /**
85
     * @var string
86
     */
87
    protected $interfaceNamespace;
88
89 24
    public function __construct(
90
        Filesystem $fileSystem,
91
        CodeHelper $codeHelper,
92
        FileCreationTransaction $fileCreationTransaction,
93
        FindAndReplaceHelper $findAndReplaceHelper,
94
        TypeHelper $typeHelper
95
96
    ) {
97 24
        $this->fileSystem              = $fileSystem;
98 24
        $this->codeHelper              = $codeHelper;
99 24
        $this->fileCreationTransaction = $fileCreationTransaction;
100 24
        $this->findAndReplaceHelper    = $findAndReplaceHelper;
101 24
        $this->typeHelper              = $typeHelper;
102 24
    }
103
104
    /**
105
     * @param string      $className
106
     * @param string      $traitPath
107
     * @param string      $interfacePath
108
     * @param string      $dbalType
109
     * @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...
110
     * @param bool        $isUnique
111
     * @param null|string $phpType
112
     *
113
     * @param string      $traitNamespace
114
     * @param string      $interfaceNamespace
115
     *
116
     * @return string
117
     * @throws DoctrineStaticMetaException
118
     * @SuppressWarnings(PHPMD.BooleanArgumentFlag)
119
     */
120 24
    public function create(
121
        string $className,
122
        string $traitPath,
123
        string $interfacePath,
124
        string $dbalType,
125
        $defaultValue = null,
126
        bool $isUnique = false,
127
        ?string $phpType = null,
128
        string $traitNamespace,
129
        string $interfaceNamespace
130
    ): string {
131 24
        $this->traitPath          = $traitPath;
132 24
        $this->interfacePath      = $interfacePath;
133 24
        $this->phpType            = $phpType;
134 24
        $this->defaultValue       = $defaultValue;
135 24
        $this->isUnique           = $isUnique;
136 24
        $this->isNullable         = (null === $defaultValue);
137 24
        $this->dbalType           = $dbalType;
138 24
        $this->className          = $className;
139 24
        $this->traitNamespace     = $traitNamespace;
140 24
        $this->interfaceNamespace = $interfaceNamespace;
141 24
        $this->generateInterface();
142
143 24
        return $this->generateTrait();
144
    }
145
146
    /**
147
     * @throws DoctrineStaticMetaException
148
     * @SuppressWarnings(PHPMD.BooleanArgumentFlag)
149
     */
150 24
    protected function generateInterface(): void
151
    {
152
        try {
153 24
            $this->fileSystem->copy(
154 24
                $this->codeHelper->resolvePath(FieldGenerator::FIELD_INTERFACE_TEMPLATE_PATH),
155 24
                $this->interfacePath
156
            );
157 24
            $this->interfacePostCopy($this->interfacePath);
158 24
            $this->codeHelper->replaceTypeHintsInFile(
159 24
                $this->interfacePath,
160 24
                $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

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

305
                /** @scrutinizer ignore-type */ $this->phpType,
Loading history...
306 24
                $this->dbalType,
307 24
                $this->isNullable
308
            );
309
310 24
            return $trait->getQualifiedName();
311
        } catch (\Exception $e) {
312
            throw new DoctrineStaticMetaException(
313
                'Error in '.__METHOD__.': '.$e->getMessage(),
314
                $e->getCode(),
315
                $e
316
            );
317
        }
318
    }
319
320
    /**
321
     * @return PhpMethod
322
     * @SuppressWarnings(PHPMD.StaticAccess)
323
     * @SuppressWarnings(PHPMD.BooleanArgumentFlag)
324
     */
325 24
    protected function getPropertyMetaMethod(): PhpMethod
326
    {
327 24
        $classy = $this->codeHelper->classy($this->className);
328 24
        $consty = $this->codeHelper->consty($this->className);
329 24
        $name   = UsesPHPMetaDataInterface::METHOD_PREFIX_GET_PROPERTY_DOCTRINE_META.$classy;
330 24
        $method = PhpMethod::create($name);
331 24
        $method->setStatic(true);
332 24
        $method->setVisibility('public');
333 24
        $method->setParameters(
334 24
            [PhpParameter::create('builder')->setType('ClassMetadataBuilder')]
335
        );
336 24
        $mappingHelperMethodName = 'setSimple'.ucfirst(strtolower($this->dbalType)).'Fields';
337
338
        $methodBody = "
339 24
        MappingHelper::$mappingHelperMethodName(
340 24
            [{$classy}FieldInterface::PROP_{$consty}],
341
            \$builder,
342 24
            {$classy}FieldInterface::DEFAULT_{$consty}
343
        );                        
344
";
345 24
        if (\in_array($this->dbalType, MappingHelper::UNIQUEABLE_TYPES, true)) {
346 24
            $isUniqueString = $this->isUnique ? 'true' : 'false';
347
            $methodBody     = "
348 24
        MappingHelper::$mappingHelperMethodName(
349 24
            [{$classy}FieldInterface::PROP_{$consty}],
350
            \$builder,
351 24
            {$classy}FieldInterface::DEFAULT_{$consty},
352 24
            $isUniqueString
353
        );                        
354
";
355
        }
356 24
        $method->setBody($methodBody);
357 24
        $method->setDocblock(
358 24
            Docblock::create()
359 24
                    ->appendTag(
360 24
                        UnknownTag::create('SuppressWarnings(PHPMD.StaticAccess)')
361
                    )
362
        );
363
364 24
        return $method;
365
    }
366
367
368
}
369