Completed
Push — master ( eb83f4...bb238e )
by Maximilian
14s
created

src/Builder/FormContractor.php (1 issue)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
/*
4
 * This file is part of the Sonata Project package.
5
 *
6
 * (c) Thomas Rabaix <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace Sonata\DoctrinePHPCRAdminBundle\Builder;
13
14
use Doctrine\ODM\PHPCR\Mapping\ClassMetadata;
15
use Sonata\AdminBundle\Admin\AdminInterface;
16
use Sonata\AdminBundle\Admin\FieldDescriptionInterface;
17
use Sonata\AdminBundle\Builder\FormContractorInterface;
18
use Symfony\Component\Form\FormFactoryInterface;
19
20
class FormContractor implements FormContractorInterface
21
{
22
    /**
23
     * @var FormFactoryInterface
24
     */
25
    protected $formFactory;
26
27
    /**
28
     * @param FormFactoryInterface $formFactory
29
     */
30
    public function __construct(FormFactoryInterface $formFactory)
31
    {
32
        $this->formFactory = $formFactory;
33
    }
34
35
    /**
36
     * The method defines the correct default settings for the provided FieldDescription.
37
     *
38
     * {@inheritdoc}
39
     *
40
     * @throws \RuntimeException if the $fieldDescription does not specify a type
41
     */
42
    public function fixFieldDescription(AdminInterface $admin, FieldDescriptionInterface $fieldDescription)
43
    {
44
        $metadata = null;
45
        if ($admin->getModelManager()->hasMetadata($admin->getClass())) {
46
            /** @var \Doctrine\ODM\PHPCR\Mapping\ClassMetadata $metadata */
47
            $metadata = $admin->getModelManager()->getMetadata($admin->getClass());
48
49
            // set the default field mapping
50
            if (isset($metadata->mappings[$fieldDescription->getName()])) {
51
                $fieldDescription->setFieldMapping($metadata->mappings[$fieldDescription->getName()]);
52
            }
53
54
            // set the default association mapping
55
            if ($metadata->hasAssociation($fieldDescription->getName())) {
56
                $fieldDescription->setAssociationMapping($metadata->getAssociation($fieldDescription->getName()));
57
            }
58
        }
59
60
        if (!$fieldDescription->getType()) {
61
            throw new \RuntimeException(sprintf(
62
                'Please define a type for field `%s` in `%s`',
63
                $fieldDescription->getName(),
64
                get_class($admin)
65
            ));
66
        }
67
68
        $fieldDescription->setAdmin($admin);
69
        $fieldDescription->setOption('edit', $fieldDescription->getOption('edit', 'standard'));
70
71
        $mappingTypes = array(
72
            ClassMetadata::MANY_TO_ONE,
73
            ClassMetadata::MANY_TO_MANY,
74
            'children',
75
            'child',
76
            'parent',
77
            'referrers',
78
        );
79
80
        if ($metadata && $metadata->hasAssociation($fieldDescription->getName()) && in_array($fieldDescription->getMappingType(), $mappingTypes)) {
81
            $admin->attachAdminClass($fieldDescription);
82
        }
83
    }
84
85
    /**
86
     * @return FormFactoryInterface
87
     */
88
    public function getFormFactory()
89
    {
90
        return $this->formFactory;
91
    }
92
93
    /**
94
     * {@inheritdoc}
95
     */
96
    public function getFormBuilder($name, array $options = array())
97
    {
98
        return $this->getFormFactory()->createNamedBuilder(
99
            $name,
100
            'Symfony\Component\Form\Extension\Core\Type\FormType',
101
            null,
102
            $options);
103
    }
104
105
    /**
106
     * {@inheritdoc}
107
     *
108
     * @throws \LogicException if a sonata_type_model field does not have a
109
     *                         target model configured
110
     */
111
    public function getDefaultOptions($type, FieldDescriptionInterface $fieldDescription)
112
    {
113
        $options = array();
114
        $options['sonata_field_description'] = $fieldDescription;
115
116
        switch ($type) {
117
            case 'Sonata\DoctrinePHPCRAdminBundle\Form\Type\TreeModelType':
118
            case 'doctrine_phpcr_odm_tree':
119
                $options['class'] = $fieldDescription->getTargetEntity();
120
                $options['model_manager'] = $fieldDescription->getAdmin()->getModelManager();
121
122
                break;
123
            case 'Sonata\AdminBundle\Form\Type\ModelType':
124
            case 'sonata_type_model':
125
            case 'Sonata\AdminBundle\Form\Type\ModelTypeList':
126
            case 'sonata_type_model_list':
127
                if ('child' !== $fieldDescription->getMappingType() && !$fieldDescription->getTargetEntity()) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $fieldDescription->getTargetEntity() of type string|null is loosely compared to false; this is ambiguous if the string can be empty. You might want to explicitly use === null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
128
                    throw new \LogicException(sprintf(
129
                        'The field "%s" in class "%s" does not have a target model defined. Please specify the "targetDocument" attribute in the mapping for this class.',
130
                        $fieldDescription->getName(),
131
                        $fieldDescription->getAdmin()->getClass()
132
                    ));
133
                }
134
135
                $options['class'] = $fieldDescription->getTargetEntity();
136
                $options['model_manager'] = $fieldDescription->getAdmin()->getModelManager();
137
138
                break;
139
            case 'Sonata\AdminBundle\Form\Type\AdminType':
140
            case 'sonata_type_admin':
141
                if (!$fieldDescription->getAssociationAdmin()) {
142
                    throw $this->getAssociationAdminException($fieldDescription);
143
                }
144
145
                $options['data_class'] = $fieldDescription->getAssociationAdmin()->getClass();
146
                $fieldDescription->setOption('edit', $fieldDescription->getOption('edit', 'admin'));
147
148
                break;
149
            case 'Sonata\CoreBundle\Form\Type\CollectionType':
150
            case 'sonata_type_collection':
151
                if (!$fieldDescription->getAssociationAdmin()) {
152
                    throw $this->getAssociationAdminException($fieldDescription);
153
                }
154
155
                $options['type'] = 'Sonata\AdminBundle\Form\Type\AdminType';
156
                $options['modifiable'] = true;
157
                $options['type_options'] = array(
158
                    'sonata_field_description' => $fieldDescription,
159
                    'data_class' => $fieldDescription->getAssociationAdmin()->getClass(),
160
                );
161
162
            break;
163
        }
164
165
        return $options;
166
    }
167
168
    /**
169
     * @param FieldDescriptionInterface $fieldDescription
170
     *
171
     * @return \LogicException
172
     */
173
    protected function getAssociationAdminException(FieldDescriptionInterface $fieldDescription)
174
    {
175
        $msg = sprintf('The current field `%s` is not linked to an admin. Please create one', $fieldDescription->getName());
176
        if (in_array($fieldDescription->getMappingType(), array(ClassMetadata::MANY_TO_ONE, ClassMetadata::MANY_TO_MANY, 'referrers'))) {
177
            if ($fieldDescription->getTargetEntity()) {
178
                $msg .= " for the target document: `{$fieldDescription->getTargetEntity()}`";
179
            }
180
            $msg .= ', specify the `targetDocument` in the Reference, or the `referringDocument` in the Referrers or use the option `admin_code` to link it.';
181
        } else {
182
            $msg .= ' and use the option `admin_code` to link it.';
183
        }
184
185
        return new \LogicException($msg);
186
    }
187
}
188