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

src/Builder/ListBuilder.php (2 issues)

Labels
Severity

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\FieldDescriptionCollection;
17
use Sonata\AdminBundle\Admin\FieldDescriptionInterface;
18
use Sonata\AdminBundle\Builder\ListBuilderInterface;
19
use Sonata\AdminBundle\Guesser\TypeGuesserInterface;
20
21
class ListBuilder implements ListBuilderInterface
22
{
23
    /**
24
     * @var TypeGuesserInterface
25
     */
26
    protected $guesser;
27
28
    /**
29
     * @var array
30
     */
31
    protected $templates;
32
33
    /**
34
     * @param TypeGuesserInterface $guesser
35
     * @param array                $templates
36
     */
37
    public function __construct(TypeGuesserInterface $guesser, array $templates = array())
38
    {
39
        $this->guesser = $guesser;
40
        $this->templates = $templates;
41
    }
42
43
    /**
44
     * {@inheritdoc}
45
     */
46
    public function getBaseList(array $options = array())
47
    {
48
        return new FieldDescriptionCollection();
49
    }
50
51
    /**
52
     * {@inheritdoc}
53
     */
54
    public function buildField($type, FieldDescriptionInterface $fieldDescription, AdminInterface $admin)
55
    {
56
        if ($type == null) {
57
            $guessType = $this->guesser->guessType($admin->getClass(), $fieldDescription->getName(), $admin->getModelManager());
58
            $fieldDescription->setType($guessType->getType());
59
        } else {
60
            $fieldDescription->setType($type);
61
        }
62
63
        $this->fixFieldDescription($admin, $fieldDescription);
64
    }
65
66
    /**
67
     * {@inheritdoc}
68
     */
69
    public function addField(FieldDescriptionCollection $list, $type, FieldDescriptionInterface $fieldDescription, AdminInterface $admin)
70
    {
71
        $this->buildField($type, $fieldDescription, $admin);
72
        $admin->addListFieldDescription($fieldDescription->getName(), $fieldDescription);
73
74
        $list->add($fieldDescription);
75
    }
76
77
    /**
78
     * {@inheritdoc}
79
     *
80
     * @throws \RuntimeException if the $fieldDescription does not have a type
81
     */
82
    public function fixFieldDescription(AdminInterface $admin, FieldDescriptionInterface $fieldDescription)
83
    {
84
        if ($fieldDescription->getName() == '_action' || $fieldDescription->getType() === 'actions') {
85
            $this->buildActionFieldDescription($fieldDescription);
86
        }
87
88
        $fieldDescription->setAdmin($admin);
89
        $metadata = null;
90
91
        if ($admin->getModelManager()->hasMetadata($admin->getClass())) {
92
            /** @var ClassMetadata $metadata */
93
            $metadata = $admin->getModelManager()->getMetadata($admin->getClass());
94
95
            // TODO sort on parent associations or node name
96
            $defaultSortable = true;
97
            if ($metadata->hasAssociation($fieldDescription->getName())
98
                || $metadata->nodename === $fieldDescription->getName()
99
            ) {
100
                $defaultSortable = false;
101
            }
102
103
            // TODO get and set parent association mappings, see
104
            // https://github.com/sonata-project/SonataDoctrinePhpcrAdminBundle/issues/106
105
            //$fieldDescription->setParentAssociationMappings($parentAssociationMappings);
106
107
            // set the default field mapping
108
            if (isset($metadata->mappings[$fieldDescription->getName()])) {
109
                $fieldDescription->setFieldMapping($metadata->mappings[$fieldDescription->getName()]);
110
                if ($fieldDescription->getOption('sortable') !== false) {
111
                    $fieldDescription->setOption(
112
                        'sortable',
113
                        $fieldDescription->getOption('sortable', $defaultSortable)
114
                    );
115
                    $fieldDescription->setOption(
116
                        'sort_parent_association_mappings',
117
                        $fieldDescription->getOption(
118
                            'sort_parent_association_mappings',
119
                            $fieldDescription->getParentAssociationMappings()
120
                        )
121
                    );
122
                    $fieldDescription->setOption(
123
                        'sort_field_mapping',
124
                        $fieldDescription->getOption(
125
                            'sort_field_mapping',
126
                            $fieldDescription->getFieldMapping()
127
                        )
128
                    );
129
                }
130
            }
131
132
            // set the default association mapping
133
            if (isset($metadata->associationMappings[$fieldDescription->getName()])) {
0 ignored issues
show
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...
134
                $fieldDescription->setAssociationMapping($metadata->associationMappings[$fieldDescription->getName()]);
0 ignored issues
show
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
            }
136
137
            $fieldDescription->setOption(
138
                '_sort_order',
139
                $fieldDescription->getOption('_sort_order', 'ASC')
140
            );
141
        }
142
143
        if (!$fieldDescription->getType()) {
144
            throw new \RuntimeException(sprintf(
145
                'Please define a type for field `%s` in `%s`',
146
                $fieldDescription->getName(),
147
                get_class($admin)
148
            ));
149
        }
150
151
        $fieldDescription->setOption(
152
            'code',
153
            $fieldDescription->getOption('code', $fieldDescription->getName())
154
        );
155
        $fieldDescription->setOption(
156
            'label',
157
            $fieldDescription->getOption('label', $fieldDescription->getName())
158
        );
159
160
        if (!$fieldDescription->getTemplate()) {
161
            $fieldDescription->setTemplate($this->getTemplate($fieldDescription->getType()));
162
163
            if ($fieldDescription->getMappingType() == ClassMetadata::MANY_TO_ONE) {
164
                $fieldDescription->setTemplate('SonataAdminBundle:CRUD/Association:list_many_to_one.html.twig');
165
            }
166
167
            if ($fieldDescription->getMappingType() == ClassMetadata::MANY_TO_MANY) {
168
                $fieldDescription->setTemplate('SonataAdminBundle:CRUD/Association:list_many_to_many.html.twig');
169
            }
170
171
            if ($fieldDescription->getMappingType() == 'child' || $fieldDescription->getMappingType() == 'parent') {
172
                $fieldDescription->setTemplate('SonataAdminBundle:CRUD/Association:list_one_to_one.html.twig');
173
            }
174
175
            if ($fieldDescription->getMappingType() == 'children' || $fieldDescription->getMappingType() == 'referrers') {
176
                $fieldDescription->setTemplate('SonataAdminBundle:CRUD/Association:list_one_to_many.html.twig');
177
            }
178
        }
179
180
        $mappingTypes = array(
181
            ClassMetadata::MANY_TO_ONE,
182
            ClassMetadata::MANY_TO_MANY,
183
            'children',
184
            'child',
185
            'parent',
186
            'referrers',
187
        );
188
189
        if ($metadata
190
            && $metadata->hasAssociation($fieldDescription->getName())
191
            && in_array($fieldDescription->getMappingType(), $mappingTypes)
192
        ) {
193
            $admin->attachAdminClass($fieldDescription);
194
        }
195
    }
196
197
    /**
198
     * @param FieldDescriptionInterface $fieldDescription
199
     *
200
     * @return FieldDescriptionInterface
201
     */
202
    public function buildActionFieldDescription(FieldDescriptionInterface $fieldDescription)
203
    {
204
        if (null === $fieldDescription->getTemplate()) {
205
            $fieldDescription->setTemplate('SonataAdminBundle:CRUD:list__action.html.twig');
206
        }
207
208
        if (null === $fieldDescription->getType()) {
209
            $fieldDescription->setType('actions');
210
        }
211
212
        if (null === $fieldDescription->getOption('name')) {
213
            $fieldDescription->setOption('name', 'Action');
214
        }
215
216
        if (null === $fieldDescription->getOption('code')) {
217
            $fieldDescription->setOption('code', 'Action');
218
        }
219
220
        if (null !== $fieldDescription->getOption('actions')) {
221
            $actions = $fieldDescription->getOption('actions');
222
            foreach ($actions as $k => $action) {
223
                if (!isset($action['template'])) {
224
                    $actions[$k]['template'] = sprintf('SonataAdminBundle:CRUD:list__action_%s.html.twig', $k);
225
                }
226
            }
227
228
            $fieldDescription->setOption('actions', $actions);
229
        }
230
231
        return $fieldDescription;
232
    }
233
234
    /**
235
     * @param string $type
236
     *
237
     * @return string
238
     */
239
    private function getTemplate($type)
240
    {
241
        if (!isset($this->templates[$type])) {
242
            return;
243
        }
244
245
        return $this->templates[$type];
246
    }
247
}
248