Factory   A
last analyzed

Complexity

Total Complexity 28

Size/Duplication

Total Lines 167
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 9

Importance

Changes 3
Bugs 2 Features 0
Metric Value
wmc 28
c 3
b 2
f 0
lcom 1
cbo 9
dl 0
loc 167
rs 10

8 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 7 1
A setPrefixAndReplacement() 0 5 3
C createNamedBuilder() 0 29 7
A setSecurityTokenStorage() 0 4 1
A resolveType() 0 19 3
D createBuilderForProperty() 0 35 9
A getUser() 0 6 2
A getUserAwareChoiceBuilder() 0 9 2
1
<?php
2
3
namespace DoS\ResourceBundle\Form;
4
5
use Doctrine\ORM\EntityRepository;
6
use Symfony\Component\Form\Exception\UnexpectedTypeException;
7
use Symfony\Component\Form\FormBuilderInterface;
8
use Symfony\Component\Form\FormFactory;
9
use Symfony\Component\Form\FormRegistryInterface;
10
use Symfony\Component\Form\FormTypeInterface;
11
use Symfony\Component\Form\ResolvedFormTypeInterface;
12
use Symfony\Component\Form\ResolvedFormTypeFactoryInterface;
13
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
14
use DoS\UserBundle\Model\UserInterface;
15
16
class Factory extends FormFactory
17
{
18
    protected $pattern;
19
    protected $replacement = 'dos_';
20
21
    /**
22
     * @var FormRegistryInterface
23
     */
24
    private $registry;
0 ignored issues
show
Comprehensibility introduced by
Consider using a different property name as you override a private property of the parent class.
Loading history...
25
26
    /**
27
     * @var ResolvedFormTypeFactoryInterface
28
     */
29
    private $resolvedTypeFactory;
0 ignored issues
show
Comprehensibility introduced by
Consider using a different property name as you override a private property of the parent class.
Loading history...
30
31
    public function __construct(FormRegistryInterface $registry, ResolvedFormTypeFactoryInterface $resolvedTypeFactory)
32
    {
33
        $this->registry = $registry;
34
        $this->resolvedTypeFactory = $resolvedTypeFactory;
35
36
        parent::__construct($registry, $resolvedTypeFactory);
37
    }
38
39
    /**
40
     * @var TokenStorageInterface
41
     */
42
    protected $tokenStorage;
43
44
    /**
45
     * @param TokenStorageInterface $tokenStorage
46
     */
47
    public function setSecurityTokenStorage(TokenStorageInterface $tokenStorage)
48
    {
49
        $this->tokenStorage = $tokenStorage;
50
    }
51
52
    /**
53
     * @param string $pattern ereg pattern
54
     * @param string $replacement
55
     */
56
    public function setPrefixAndReplacement($pattern = null, $replacement = null)
57
    {
58
        $this->pattern = $pattern ?: $this->pattern;
59
        $this->replacement = $replacement ?: $this->replacement;
60
    }
61
62
    /**
63
     * @inheritdoc
64
     */
65
    public function createNamedBuilder($name, $type = 'form', $data = null, array $options = array())
66
    {
67
        if ($this->pattern) {
68
            $name = preg_replace($this->pattern, $this->replacement, $name);
69
70
            if (null !== $data && !array_key_exists('data', $options)) {
71
                $options['data'] = $data;
72
            }
73
74
            if ($type instanceof FormTypeInterface) {
75
                $type = $this->resolveType($type);
76
            } elseif (is_string($type)) {
77
                $type = $this->registry->getType($type);
78
            } elseif (!$type instanceof ResolvedFormTypeInterface) {
79
                throw new UnexpectedTypeException($type, 'string, Symfony\Component\Form\ResolvedFormTypeInterface or Symfony\Component\Form\FormTypeInterface');
80
            }
81
        }
82
83
        $builder = $type->createBuilder($this, $name, $options);
0 ignored issues
show
Bug introduced by
It seems like $type is not always an object, but can also be of type string. Maybe add an additional type check?

If a variable is not always an object, we recommend to add an additional type check to ensure your method call is safe:

function someFunction(A $objectMaybe = null)
{
    if ($objectMaybe instanceof A) {
        $objectMaybe->doSomething();
    }
}
Loading history...
84
85
        // set default user
86
        $builder->setAttribute('user_aware', $this->getUser());
87
88
        // Explicitly call buildForm() in order to be able to override either
89
        // createBuilder() or buildForm() in the resolved form type
90
        $type->buildForm($builder, $builder->getOptions());
91
92
        return $builder;
93
    }
94
95
    /**
96
     * @inheritdoc
97
     */
98
    private function resolveType(FormTypeInterface $type)
0 ignored issues
show
Bug introduced by
Consider using a different method name as you override a private method of the parent class.

Overwriting private methods is generally fine as long as you also use private visibility. It might still be preferable for understandability to use a different method name.

Loading history...
99
    {
100
        $parentType = $type->getParent();
101
102
        if ($parentType instanceof FormTypeInterface) {
103
            $parentType = $this->resolveType($parentType);
104
        } elseif (null !== $parentType) {
105
            $parentType = $this->registry->getType($parentType);
106
        }
107
108
        return $this->resolvedTypeFactory->createResolvedType(
109
            $type,
110
            // Type extensions are not supported for unregistered type instances,
111
            // i.e. type instances that are passed to the FormFactory directly,
112
            // nor for their parents, if getParent() also returns a type instance.
113
            array(),
114
            $parentType
115
        );
116
    }
117
118
    /**
119
     * {@inheritdoc}
120
     */
121
    public function createBuilderForProperty($class, $property, $data = null, array $options = array())
122
    {
123
        if (null === $guesser = $this->registry->getTypeGuesser()) {
124
            return $this->createNamedBuilder($property, 'text', $data, $options);
125
        }
126
127
        $typeGuess = $guesser->guessType($class, $property);
128
        $maxLengthGuess = $guesser->guessMaxLength($class, $property);
129
        $requiredGuess = $guesser->guessRequired($class, $property);
130
        $patternGuess = $guesser->guessPattern($class, $property);
131
132
        $type = $typeGuess ? $typeGuess->getType() : 'text';
133
134
        $maxLength = $maxLengthGuess ? $maxLengthGuess->getValue() : null;
135
        $pattern = $patternGuess ? $patternGuess->getValue() : null;
136
137
        if (null !== $pattern) {
138
            $options = array_replace_recursive(array('attr' => array('pattern' => $pattern)), $options);
139
        }
140
141
        if (null !== $maxLength) {
142
            $options = array_replace_recursive(array('attr' => array('maxlength' => $maxLength)), $options);
143
        }
144
145
        if ($requiredGuess) {
146
            $options = array_merge(array('required' => $requiredGuess->getValue()), $options);
147
        }
148
149
        // user options may override guessed options
150
        if ($typeGuess) {
151
            $options = array_merge($typeGuess->getOptions(), $options);
152
        }
153
154
        return $this->createNamedBuilder($property, $type, $data, $options);
155
    }
156
157
    /**
158
     * @return UserInterface
159
     */
160
    private function getUser()
161
    {
162
        $token = $this->tokenStorage->getToken();
163
164
        return $token ? $token->getUser() : null;
165
    }
166
167
    /**
168
     * @param FormBuilderInterface $builder
169
     * @param UserInterface|null   $user
170
     *
171
     * @return callable
172
     */
173
    public static function getUserAwareChoiceBuilder(FormBuilderInterface $builder, UserInterface $user = null)
174
    {
175
        return function (EntityRepository $objectRepository) use ($builder, $user) {
176
            return $objectRepository->createQueryBuilder('o')
177
                ->andWhere('o.user = :user')
178
                ->setParameter('user', $user ?: $builder->getAttribute('user_aware'))
179
            ;
180
        };
181
    }
182
}
183