EnumTypeGuesser::guessType()   B
last analyzed

Complexity

Conditions 6
Paths 5

Size

Total Lines 42

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 42
rs 8.6257
c 0
b 0
f 0
cc 6
nc 5
nop 2
1
<?php
2
/*
3
 * This file is part of the FreshDoctrineEnumBundle.
4
 *
5
 * (c) Artem Henvald <[email protected]>
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 */
10
11
declare(strict_types=1);
12
13
namespace Fresh\DoctrineEnumBundle\Form;
14
15
use Doctrine\Persistence\ManagerRegistry;
16
use Fresh\DoctrineEnumBundle\DBAL\Types\AbstractEnumType;
17
use Fresh\DoctrineEnumBundle\Exception\EnumType\EnumTypeIsRegisteredButClassDoesNotExistException;
18
use Symfony\Bridge\Doctrine\Form\DoctrineOrmTypeGuesser;
19
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
20
use Symfony\Component\Form\Guess\Guess;
21
use Symfony\Component\Form\Guess\TypeGuess;
22
23
/**
24
 * EnumTypeGuesser.
25
 *
26
 * @author Artem Henvald <[email protected]>
27
 * @author Jaik Dean <[email protected]>
28
 */
29
class EnumTypeGuesser extends DoctrineOrmTypeGuesser
30
{
31
    /** @var string[] */
32
    private $registeredEnumTypes = [];
33
34
    /**
35
     * @param ManagerRegistry $registry
36
     * @param mixed[]         $registeredTypes
37
     */
38
    public function __construct(ManagerRegistry $registry, array $registeredTypes)
39
    {
40
        parent::__construct($registry);
41
42
        foreach ($registeredTypes as $type => $details) {
43
            $this->registeredEnumTypes[$type] = $details['class'];
44
        }
45
    }
46
47
    /**
48
     * @param string $class
49
     * @param string $property
50
     *
51
     * @throws EnumTypeIsRegisteredButClassDoesNotExistException
52
     *
53
     * @return TypeGuess|null
54
     */
55
    public function guessType(string $class, string $property): ?TypeGuess
56
    {
57
        $classMetadata = $this->getMetadata($class);
58
59
        // If no metadata for this class - can't guess anything
60
        if (!$classMetadata) {
61
            return null;
62
        }
63
64
        /** @var \Doctrine\ORM\Mapping\ClassMetadataInfo $metadata */
65
        [$metadata] = $classMetadata;
0 ignored issues
show
Bug introduced by
The variable $metadata does not exist. Did you mean $classMetadata?

This check looks for variables that are accessed but have not been defined. It raises an issue if it finds another variable that has a similar name.

The variable may have been renamed without also renaming all references.

Loading history...
66
        $fieldType = $metadata->getTypeOfField($property);
0 ignored issues
show
Bug introduced by
The variable $metadata does not exist. Did you mean $classMetadata?

This check looks for variables that are accessed but have not been defined. It raises an issue if it finds another variable that has a similar name.

The variable may have been renamed without also renaming all references.

Loading history...
67
68
        // This is not one of the registered ENUM types
69
        if (!\is_string($fieldType) || !isset($this->registeredEnumTypes[$fieldType])) {
70
            return null;
71
        }
72
73
        $registeredEnumTypeFQCN = $this->registeredEnumTypes[$fieldType];
74
75
        if (!\class_exists($registeredEnumTypeFQCN)) {
76
            $exceptionMessage = \sprintf(
77
                'ENUM type "%s" is registered as "%s", but that class does not exist',
78
                $fieldType,
79
                $registeredEnumTypeFQCN
80
            );
81
82
            throw new EnumTypeIsRegisteredButClassDoesNotExistException($exceptionMessage);
83
        }
84
85
        if (!\is_subclass_of($registeredEnumTypeFQCN, AbstractEnumType::class)) {
0 ignored issues
show
Bug introduced by
Due to PHP Bug #53727, is_subclass_of might return inconsistent results on some PHP versions if \Fresh\DoctrineEnumBundl...AbstractEnumType::class can be an interface. If so, you could instead use ReflectionClass::implementsInterface.
Loading history...
86
            return null;
87
        }
88
89
        /** @var AbstractEnumType $registeredEnumTypeFQCN */
90
        $parameters = [
91
            'choices' => $registeredEnumTypeFQCN::getChoices(), // Get the choices from the fully qualified class name
92
            'required' => !$metadata->isNullable($property),
0 ignored issues
show
Bug introduced by
The variable $metadata does not exist. Did you mean $classMetadata?

This check looks for variables that are accessed but have not been defined. It raises an issue if it finds another variable that has a similar name.

The variable may have been renamed without also renaming all references.

Loading history...
93
        ];
94
95
        return new TypeGuess(ChoiceType::class, $parameters, Guess::VERY_HIGH_CONFIDENCE);
96
    }
97
}
98