Completed
Pull Request — 2.x (#521)
by Maximilian
02:22
created

ListBuilder::buildActionFieldDescription()   B

Complexity

Conditions 8
Paths 32

Size

Total Lines 31

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 31
rs 8.1795
c 0
b 0
f 0
cc 8
nc 32
nop 1
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\FieldDescriptionCollection;
17
use Sonata\AdminBundle\Admin\FieldDescriptionInterface;
18
use Sonata\AdminBundle\Builder\ListBuilderInterface;
19
use Sonata\AdminBundle\Guesser\TypeGuesserInterface;
20
use Symfony\Component\Form\Guess\TypeGuess;
21
22
class ListBuilder implements ListBuilderInterface
23
{
24
    /**
25
     * @var TypeGuesserInterface
26
     */
27
    protected $guesser;
28
29
    /**
30
     * @var array
31
     */
32
    protected $templates;
33
34
    /**
35
     * @param TypeGuesserInterface $guesser
36
     * @param array                $templates
37
     */
38
    public function __construct(TypeGuesserInterface $guesser, array $templates = [])
39
    {
40
        $this->guesser = $guesser;
41
        $this->templates = $templates;
42
    }
43
44
    /**
45
     * {@inheritdoc}
46
     */
47
    public function getBaseList(array $options = [])
48
    {
49
        return new FieldDescriptionCollection();
50
    }
51
52
    /**
53
     * {@inheritdoc}
54
     */
55
    public function buildField($type, FieldDescriptionInterface $fieldDescription, AdminInterface $admin)
56
    {
57
        if (null == $type) {
58
            $guessType = $this->guesser->guessType($admin->getClass(), $fieldDescription->getName(), $admin->getModelManager());
59
            $fieldDescription->setType(($guessType instanceof TypeGuess ? $guessType->getType() : null));
60
        } else {
61
            $fieldDescription->setType($type);
62
        }
63
64
        $this->fixFieldDescription($admin, $fieldDescription);
65
    }
66
67
    /**
68
     * {@inheritdoc}
69
     */
70
    public function addField(FieldDescriptionCollection $list, $type, FieldDescriptionInterface $fieldDescription, AdminInterface $admin)
71
    {
72
        $this->buildField($type, $fieldDescription, $admin);
73
        $admin->addListFieldDescription($fieldDescription->getName(), $fieldDescription);
74
75
        $list->add($fieldDescription);
76
    }
77
78
    /**
79
     * {@inheritdoc}
80
     *
81
     * @throws \RuntimeException if the $fieldDescription does not have a type
82
     */
83
    public function fixFieldDescription(AdminInterface $admin, FieldDescriptionInterface $fieldDescription)
84
    {
85
        if ('_action' == $fieldDescription->getName() || 'actions' === $fieldDescription->getType()) {
86
            $this->buildActionFieldDescription($fieldDescription);
87
        }
88
89
        $fieldDescription->setAdmin($admin);
90
        $metadata = null;
91
92
        if ($admin->getModelManager()->hasMetadata($admin->getClass())) {
93
            /** @var ClassMetadata $metadata */
94
            $metadata = $admin->getModelManager()->getMetadata($admin->getClass());
95
96
            // TODO sort on parent associations or node name
97
            $defaultSortable = true;
98
            if ($metadata->hasAssociation($fieldDescription->getName())
99
                || $metadata->nodename === $fieldDescription->getName()
100
            ) {
101
                $defaultSortable = false;
102
            }
103
104
            // TODO get and set parent association mappings, see
105
            // https://github.com/sonata-project/SonataDoctrinePhpcrAdminBundle/issues/106
106
            //$fieldDescription->setParentAssociationMappings($parentAssociationMappings);
107
108
            // set the default field mapping
109
            if (isset($metadata->mappings[$fieldDescription->getName()])) {
110
                $fieldDescription->setFieldMapping($metadata->mappings[$fieldDescription->getName()]);
111
                if (false !== $fieldDescription->getOption('sortable')) {
112
                    $fieldDescription->setOption(
113
                        'sortable',
114
                        $fieldDescription->getOption('sortable', $defaultSortable)
115
                    );
116
                    $fieldDescription->setOption(
117
                        'sort_parent_association_mappings',
118
                        $fieldDescription->getOption(
119
                            'sort_parent_association_mappings',
120
                            $fieldDescription->getParentAssociationMappings()
121
                        )
122
                    );
123
                    $fieldDescription->setOption(
124
                        'sort_field_mapping',
125
                        $fieldDescription->getOption(
126
                            'sort_field_mapping',
127
                            $fieldDescription->getFieldMapping()
128
                        )
129
                    );
130
                }
131
            }
132
133
            // set the default association mapping
134
            if (isset($metadata->associationMappings[$fieldDescription->getName()])) {
0 ignored issues
show
Bug introduced by
The property associationMappings does not seem to exist. Did you mean mappings?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
135
                $fieldDescription->setAssociationMapping($metadata->associationMappings[$fieldDescription->getName()]);
0 ignored issues
show
Bug introduced by
The property associationMappings does not seem to exist. Did you mean mappings?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
136
            }
137
138
            $fieldDescription->setOption(
139
                '_sort_order',
140
                $fieldDescription->getOption('_sort_order', 'ASC')
141
            );
142
        }
143
144
        if (!$fieldDescription->getType()) {
145
            throw new \RuntimeException(sprintf(
146
                'Please define a type for field `%s` in `%s`',
147
                $fieldDescription->getName(),
148
                get_class($admin)
149
            ));
150
        }
151
152
        $fieldDescription->setOption(
153
            'code',
154
            $fieldDescription->getOption('code', $fieldDescription->getName())
155
        );
156
        $fieldDescription->setOption(
157
            'label',
158
            $fieldDescription->getOption('label', $fieldDescription->getName())
159
        );
160
161
        if (!$fieldDescription->getTemplate()) {
162
            $fieldDescription->setTemplate($this->getTemplate($fieldDescription->getType()));
163
164
            if (ClassMetadata::MANY_TO_ONE == $fieldDescription->getMappingType()) {
165
                $fieldDescription->setTemplate('@SonataAdmin/CRUD/Association/list_many_to_one.html.twig');
166
            }
167
168
            if (ClassMetadata::MANY_TO_MANY == $fieldDescription->getMappingType()) {
169
                $fieldDescription->setTemplate('@SonataAdmin/CRUD/Association/list_many_to_many.html.twig');
170
            }
171
172
            if ('child' == $fieldDescription->getMappingType() || 'parent' == $fieldDescription->getMappingType()) {
173
                $fieldDescription->setTemplate('@SonataAdmin/CRUD/Association/list_one_to_one.html.twig');
174
            }
175
176
            if ('children' == $fieldDescription->getMappingType() || 'referrers' == $fieldDescription->getMappingType()) {
177
                $fieldDescription->setTemplate('@SonataAdmin/CRUD/Association/list_one_to_many.html.twig');
178
            }
179
        }
180
181
        $mappingTypes = [
182
            ClassMetadata::MANY_TO_ONE,
183
            ClassMetadata::MANY_TO_MANY,
184
            'children',
185
            'child',
186
            'parent',
187
            'referrers',
188
        ];
189
190
        if ($metadata
191
            && $metadata->hasAssociation($fieldDescription->getName())
192
            && in_array($fieldDescription->getMappingType(), $mappingTypes)
193
        ) {
194
            $admin->attachAdminClass($fieldDescription);
195
        }
196
    }
197
198
    /**
199
     * @param FieldDescriptionInterface $fieldDescription
200
     *
201
     * @return FieldDescriptionInterface
202
     */
203
    public function buildActionFieldDescription(FieldDescriptionInterface $fieldDescription)
204
    {
205
        if (null === $fieldDescription->getTemplate()) {
206
            $fieldDescription->setTemplate('@SonataAdmin/CRUD/list__action.html.twig');
207
        }
208
209
        if (null === $fieldDescription->getType()) {
210
            $fieldDescription->setType('actions');
211
        }
212
213
        if (null === $fieldDescription->getOption('name')) {
214
            $fieldDescription->setOption('name', 'Action');
215
        }
216
217
        if (null === $fieldDescription->getOption('code')) {
218
            $fieldDescription->setOption('code', 'Action');
219
        }
220
221
        if (null !== $fieldDescription->getOption('actions')) {
222
            $actions = $fieldDescription->getOption('actions');
223
            foreach ($actions as $k => $action) {
224
                if (!isset($action['template'])) {
225
                    $actions[$k]['template'] = sprintf('@SonataAdmin/CRUD/list__action_%s.html.twig', $k);
226
                }
227
            }
228
229
            $fieldDescription->setOption('actions', $actions);
230
        }
231
232
        return $fieldDescription;
233
    }
234
235
    /**
236
     * @param string $type
237
     *
238
     * @return string
239
     */
240
    private function getTemplate($type)
241
    {
242
        if (!isset($this->templates[$type])) {
243
            return;
244
        }
245
246
        return $this->templates[$type];
247
    }
248
}
249