Completed
Push — 3.x ( 7b8913...94af5b )
by
unknown
01:20
created

src/Builder/FormContractor.php (4 issues)

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
declare(strict_types=1);
4
5
/*
6
 * This file is part of the Sonata Project package.
7
 *
8
 * (c) Thomas Rabaix <[email protected]>
9
 *
10
 * For the full copyright and license information, please view the LICENSE
11
 * file that was distributed with this source code.
12
 */
13
14
namespace Sonata\DoctrineMongoDBAdminBundle\Builder;
15
16
use Doctrine\ODM\MongoDB\Mapping\ClassMetadata;
17
use Sonata\AdminBundle\Admin\AdminInterface;
18
use Sonata\AdminBundle\Admin\FieldDescriptionInterface;
19
use Sonata\AdminBundle\Builder\FormContractorInterface;
20
use Sonata\AdminBundle\Form\Type\AdminType;
21
use Sonata\AdminBundle\Form\Type\ModelAutocompleteType;
22
use Sonata\AdminBundle\Form\Type\ModelHiddenType;
23
use Sonata\AdminBundle\Form\Type\ModelListType;
24
use Sonata\AdminBundle\Form\Type\ModelType;
25
use Sonata\AdminBundle\Form\Type\ModelTypeList;
26
use Sonata\CoreBundle\Form\Type\CollectionType as DeprecatedCollectionType;
27
use Sonata\Form\Type\CollectionType;
28
use Symfony\Component\Form\Extension\Core\Type\FormType;
29
use Symfony\Component\Form\FormFactoryInterface;
30
31
class FormContractor implements FormContractorInterface
32
{
33
    /**
34
     * @deprecated since version 3.1.0, to be removed in 4.0
35
     *
36
     * @var FormFactoryInterface
37
     */
38
    protected $fieldFactory;
39
40
    /**
41
     * @var FormFactoryInterface
42
     */
43
    private $formFactory;
44
45
    public function __construct(FormFactoryInterface $formFactory)
46
    {
47
        $this->formFactory = $formFactory;
48
    }
49
50
    public function fixFieldDescription(AdminInterface $admin, FieldDescriptionInterface $fieldDescription)
51
    {
52
        if ($admin->getModelManager()->hasMetadata($admin->getClass())) {
53
            $metadata = $admin->getModelManager()->getMetadata($admin->getClass());
54
55
            // set the default field mapping
56
            if (isset($metadata->fieldMappings[$fieldDescription->getName()])) {
57
                $fieldDescription->setFieldMapping($metadata->fieldMappings[$fieldDescription->getName()]);
58
            }
59
60
            // set the default association mapping
61
            if (isset($metadata->associationMappings[$fieldDescription->getName()])) {
62
                $fieldDescription->setAssociationMapping($metadata->associationMappings[$fieldDescription->getName()]);
63
            }
64
        }
65
66
        if (!$fieldDescription->getType()) {
67
            throw new \RuntimeException(sprintf(
68
                'Please define a type for field `%s` in `%s`',
69
                $fieldDescription->getName(),
70
                \get_class($admin)
71
            ));
72
        }
73
74
        $fieldDescription->setAdmin($admin);
75
        $fieldDescription->setOption('edit', $fieldDescription->getOption('edit', 'standard'));
76
77
        if (\in_array($fieldDescription->getMappingType(), [ClassMetadata::ONE, ClassMetadata::MANY], true)) {
78
            $admin->attachAdminClass($fieldDescription);
79
        }
80
    }
81
82
    /**
83
     * @return FormFactoryInterface
84
     */
85
    public function getFormFactory()
86
    {
87
        return $this->formFactory;
88
    }
89
90
    public function getFormBuilder($name, array $options = [])
91
    {
92
        return $this->getFormFactory()->createNamedBuilder($name, FormType::class, null, $options);
93
    }
94
95
    public function getDefaultOptions($type, FieldDescriptionInterface $fieldDescription)
96
    {
97
        $options = [];
98
        $options['sonata_field_description'] = $fieldDescription;
99
100
        if ($this->checkFormClass($type, [
101
            ModelType::class,
102
            ModelTypeList::class,
103
            ModelListType::class,
104
            ModelHiddenType::class,
105
            ModelAutocompleteType::class,
106
        ])) {
107
            if ('list' === $fieldDescription->getOption('edit')) {
108
                throw new \LogicException(
109
                    'The ``Sonata\AdminBundle\Form\Type\ModelType`` type does not accept an ``edit`` option anymore,'
110
                    .' please review the UPGRADE-2.1.md file from the SonataAdminBundle'
111
                );
112
            }
113
114
            $options['class'] = $fieldDescription->getTargetEntity();
0 ignored issues
show
Deprecated Code introduced by
The method Sonata\AdminBundle\Admin...face::getTargetEntity() has been deprecated with message: since sonata-project/admin-bundle 3.69. Use `getTargetModel()` instead.

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
115
            $options['model_manager'] = $fieldDescription->getAdmin()->getModelManager();
116
117
            if ($this->checkFormClass($type, [ModelAutocompleteType::class])) {
118
                if (!$fieldDescription->getAssociationAdmin()) {
119
                    throw new \RuntimeException(sprintf(
120
                        'The current field `%s` is not linked to an admin.'
121
                        .' Please create one for the target entity: `%s`',
122
                        $fieldDescription->getName(),
123
                        $fieldDescription->getTargetEntity()
0 ignored issues
show
Deprecated Code introduced by
The method Sonata\AdminBundle\Admin...face::getTargetEntity() has been deprecated with message: since sonata-project/admin-bundle 3.69. Use `getTargetModel()` instead.

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
124
                    ));
125
                }
126
            }
127
        } elseif ($this->checkFormClass($type, [AdminType::class])) {
128
            if (!$fieldDescription->getAssociationAdmin()) {
129
                throw new \RuntimeException(sprintf(
130
                    'The current field `%s` is not linked to an admin.'
131
                    .' Please create one for the target entity : `%s`',
132
                    $fieldDescription->getName(),
133
                    $fieldDescription->getTargetEntity()
0 ignored issues
show
Deprecated Code introduced by
The method Sonata\AdminBundle\Admin...face::getTargetEntity() has been deprecated with message: since sonata-project/admin-bundle 3.69. Use `getTargetModel()` instead.

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
134
                ));
135
            }
136
137
            if (!\in_array($fieldDescription->getMappingType(), [ClassMetadata::ONE, ClassMetadata::MANY], true)) {
138
                throw new \RuntimeException(sprintf(
139
                    'You are trying to add `sonata_type_admin` field `%s` which is not One-To-One or  Many-To-One.'
140
                    .' Maybe you want `sonata_type_collection` instead?',
141
                    $fieldDescription->getName()
142
                ));
143
            }
144
145
            // set sensitive default value to have a component working fine out of the box
146
            $options['btn_add'] = false;
147
            $options['delete'] = false;
148
149
            $options['data_class'] = $fieldDescription->getAssociationAdmin()->getClass();
150
            $fieldDescription->setOption('edit', $fieldDescription->getOption('edit', 'admin'));
151
        } elseif ($this->checkFormClass($type, [
152
            CollectionType::class,
153
            DeprecatedCollectionType::class,
154
        ])) {
155
            if (!$fieldDescription->getAssociationAdmin()) {
156
                throw new \RuntimeException(sprintf(
157
                    'The current field `%s` is not linked to an admin.'
158
                    .' Please create one for the target entity : `%s`',
159
                    $fieldDescription->getName(),
160
                    $fieldDescription->getTargetEntity()
0 ignored issues
show
Deprecated Code introduced by
The method Sonata\AdminBundle\Admin...face::getTargetEntity() has been deprecated with message: since sonata-project/admin-bundle 3.69. Use `getTargetModel()` instead.

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
161
                ));
162
            }
163
164
            $options['type'] = AdminType::class;
165
            $options['modifiable'] = true;
166
            $options['type_options'] = [
167
                'sonata_field_description' => $fieldDescription,
168
                'data_class' => $fieldDescription->getAssociationAdmin()->getClass(),
169
            ];
170
        }
171
172
        return $options;
173
    }
174
175
    /**
176
     * @param string $type
177
     * @param array  $classes
178
     *
179
     * @return array
180
     */
181
    private function checkFormClass($type, $classes)
182
    {
183
        return array_filter($classes, static function ($subclass) use ($type) {
184
            return is_a($type, $subclass, true);
185
        });
186
    }
187
}
188