ModelFilter   A
last analyzed

Complexity

Total Complexity 27

Size/Duplication

Total Lines 151
Duplicated Lines 0 %

Coupling/Cohesion

Components 2
Dependencies 2

Importance

Changes 0
Metric Value
wmc 27
lcom 2
cbo 2
dl 0
loc 151
rs 10
c 0
b 0
f 0

7 Methods

Rating   Name   Duplication   Size   Complexity  
A handleScalar() 0 16 4
A filter() 0 18 6
A getDefaultOptions() 0 11 1
A getRenderSettings() 0 10 1
A handleMultiple() 0 19 5
A fixIdentifier() 0 17 4
A getIdentifierField() 0 18 6
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\Filter;
15
16
use Doctrine\Bundle\MongoDBBundle\Form\Type\DocumentType;
17
use Doctrine\Common\Collections\Collection;
18
use Doctrine\ODM\MongoDB\Mapping\ClassMetadata;
19
use MongoDB\BSON\ObjectId;
20
use MongoDB\Exception\InvalidArgumentException;
21
use Sonata\AdminBundle\Datagrid\ProxyQueryInterface;
22
use Sonata\AdminBundle\Form\Type\Filter\DefaultType;
23
use Sonata\Form\Type\EqualType;
24
25
class ModelFilter extends Filter
26
{
27
    /**
28
     * @param string $alias
29
     * @param string $field
30
     * @param mixed  $data
31
     */
32
    public function filter(ProxyQueryInterface $queryBuilder, $alias, $field, $data): void
33
    {
34
        if (!$data || !\is_array($data) || !\array_key_exists('value', $data)) {
35
            return;
36
        }
37
38
        if ($data['value'] instanceof Collection) {
39
            $data['value'] = $data['value']->toArray();
40
        }
41
42
        $field = $this->getIdentifierField($field);
43
44
        if (\is_array($data['value'])) {
45
            $this->handleMultiple($queryBuilder, $alias, $field, $data);
46
        } else {
47
            $this->handleScalar($queryBuilder, $alias, $field, $data);
48
        }
49
    }
50
51
    public function getDefaultOptions()
52
    {
53
        return [
54
            'mapping_type' => false,
55
            'field_name' => false,
56
            'field_type' => DocumentType::class,
57
            'field_options' => [],
58
            'operator_type' => EqualType::class,
59
            'operator_options' => [],
60
        ];
61
    }
62
63
    public function getRenderSettings()
64
    {
65
        return [DefaultType::class, [
66
            'field_type' => $this->getFieldType(),
67
            'field_options' => $this->getFieldOptions(),
68
            'operator_type' => $this->getOption('operator_type'),
69
            'operator_options' => $this->getOption('operator_options'),
70
            'label' => $this->getLabel(),
71
        ]];
72
    }
73
74
    /**
75
     * @param string $alias
76
     * @param string $field
77
     * @param array  $data
78
     *
79
     * @return void
80
     */
81
    protected function handleMultiple(ProxyQueryInterface $queryBuilder, $alias, $field, $data)
0 ignored issues
show
Unused Code introduced by Dylan Oliver
The parameter $alias is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
82
    {
83
        if (0 === \count($data['value'])) {
84
            return;
85
        }
86
87
        $ids = [];
88
        foreach ($data['value'] as $value) {
89
            $ids[] = self::fixIdentifier($value->getId());
90
        }
91
92
        if (isset($data['type']) && EqualType::TYPE_IS_NOT_EQUAL === $data['type']) {
93
            $queryBuilder->field($field)->notIn($ids);
94
        } else {
95
            $queryBuilder->field($field)->in($ids);
96
        }
97
98
        $this->active = true;
99
    }
100
101
    /**
102
     * @param string $alias
103
     * @param string $field
104
     * @param array  $data
105
     *
106
     * @return void
107
     */
108
    protected function handleScalar(ProxyQueryInterface $queryBuilder, $alias, $field, $data)
0 ignored issues
show
Unused Code introduced by Dylan Oliver
The parameter $alias is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
109
    {
110
        if (empty($data['value'])) {
111
            return;
112
        }
113
114
        $id = self::fixIdentifier($data['value']->getId());
115
116
        if (isset($data['type']) && EqualType::TYPE_IS_NOT_EQUAL === $data['type']) {
117
            $queryBuilder->field($field)->notEqual($id);
118
        } else {
119
            $queryBuilder->field($field)->equals($id);
120
        }
121
122
        $this->active = true;
123
    }
124
125
    /**
126
     * Return \MongoId|ObjectId if $id is MongoId|ObjectId in string representation, otherwise custom string.
127
     *
128
     * @param mixed $id
129
     *
130
     * @return \MongoId|string|ObjectId
131
     */
132
    protected static function fixIdentifier($id)
133
    {
134
        // NEXT_MAJOR: Use only ObjectId when dropping support for doctrine/mongodb-odm 1.x
135
        if (class_exists(ObjectId::class)) {
136
            try {
137
                return new ObjectId($id);
138
            } catch (InvalidArgumentException $ex) {
139
                return $id;
140
            }
141
        }
142
143
        try {
144
            return new \MongoId($id);
145
        } catch (\MongoException $ex) {
146
            return $id;
147
        }
148
    }
149
150
    /**
151
     * Get identifier field name based on mapping type.
152
     *
153
     * @param string $field
154
     *
155
     * @return string
156
     */
157
    protected function getIdentifierField($field)
158
    {
159
        $field_mapping = $this->getFieldMapping();
160
161
        if (isset($field_mapping['storeAs'])) {
162
            switch ($field_mapping['storeAs']) {
163
                case ClassMetadata::REFERENCE_STORE_AS_REF:
164
                    return $field.'.id';
165
                case ClassMetadata::REFERENCE_STORE_AS_ID:
166
                    return $field;
167
                case ClassMetadata::REFERENCE_STORE_AS_DB_REF_WITH_DB:
168
                case ClassMetadata::REFERENCE_STORE_AS_DB_REF:
169
                    return $field.'.$id';
170
            }
171
        }
172
173
        return $field.'._id';
174
    }
175
}
176