Completed
Push — master ( 209945...41a4bc )
by Matthew
07:41 queued 03:34
created

EntityGridSource::remove()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 17
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 9
nc 2
nop 1
dl 0
loc 17
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
namespace Dtc\GridBundle\Grid\Source;
4
5
use Doctrine\ORM\EntityManager;
6
use Doctrine\ORM\Mapping\ClassMetadata;
7
use Dtc\GridBundle\Grid\Column\GridColumn;
8
9
class EntityGridSource extends AbstractGridSource
10
{
11
    use ColumnExtractionTrait;
12
13
    protected $entityManager;
14
    protected $entityName;
15
16
    public function __construct(EntityManager $entityManager, $entityName)
17
    {
18
        $this->entityManager = $entityManager;
19
        $this->entityName = $entityName;
20
    }
21
22
    protected function getQueryBuilder()
23
    {
24
        $columns = $this->getColumns();
25
        $fieldList = [];
26 View Code Duplication
        foreach ($columns as $column) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
27
            if ($column instanceof GridColumn && $column->isSearchable()) {
28
                $fieldList[$column->getField()] = true;
29
            }
30
        }
31
32
        $qb = $this->entityManager->createQueryBuilder();
33
        $orderBy = array();
34
        foreach ($this->orderBy as $key => $value) {
35
            $orderBy[] = "u.{$key} {$value}";
36
        }
37
38
        $qb->add('select', 'u')
0 ignored issues
show
Bug introduced by
'u' of type string is incompatible with the type Doctrine\ORM\Query\Expr\Base expected by parameter $dqlPart of Doctrine\ORM\QueryBuilder::add(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

38
        $qb->add('select', /** @scrutinizer ignore-type */ 'u')
Loading history...
39
            ->add('from', "{$this->entityName} u")
40
            ->setFirstResult($this->offset)
41
            ->setMaxResults($this->limit);
42
43
        if ($this->orderBy) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->orderBy of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
44
            $orderByStr = implode(',', $orderBy);
45
            $qb->add('orderBy', $orderByStr);
46
        }
47
48
        if ($this->filter) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->filter of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
49
            /** @var ClassMetadata $classMetaData */
50
            $classMetaData = $this->getClassMetadata();
51
            $classFields = $classMetaData->fieldMappings;
52
53
            $validFilters = array_intersect_key($this->filter, $classFields);
54
55
            $query = array();
56
            foreach ($validFilters as $key => $value) {
57
                if (isset($fieldList[$key])) {
58
                    if (is_array($value)) {
59
                        $query[] = "u.{$key} IN :{$key}";
60
                    } else {
61
                        $query[] = "u.{$key} = :{$key}";
62
                    }
63
                }
64
                $qb->setParameter($key, $value);
65
            }
66
            if ($query) {
67
                $qb->add('where', implode(' and ', $query));
68
            } else {
69
                $starFilter = array_intersect_key($this->filter, ['*' => null]);
70
                if ($starFilter) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $starFilter of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
71
                    $value = current($starFilter);
72
                    $starQuery = [];
73
                    foreach (array_keys($classFields) as $key) {
74
                        if (isset($fieldList[$key])) {
75
                            $starQuery[] = "u.{$key} like :{$key}";
76
                            $qb->setParameter($key, $value);
77
                        }
78
                    }
79
80
                    if ($starQuery) {
81
                        $star = implode(' or ', $starQuery);
82
83
                        if ($query) {
84
                            $qb->andWhere($star);
85
                        } else {
86
                            $qb->add('where', $star);
87
                        }
88
                    }
89
                }
90
            }
91
        }
92
93
        return $qb;
94
    }
95
96
    /**
97
     * @return \Doctrine\Common\Persistence\Mapping\ClassMetadata
98
     */
99
    public function getClassMetadata()
100
    {
101
        $metaFactory = $this->entityManager->getMetadataFactory();
102
        $classInfo = $metaFactory->getMetadataFor($this->entityName);
103
104
        return $classInfo;
105
    }
106
107
    public function getCount()
108
    {
109
        $qb = $this->getQueryBuilder();
110
        $qb->add('select', 'count(u)')
0 ignored issues
show
Bug introduced by
'count(u)' of type string is incompatible with the type Doctrine\ORM\Query\Expr\Base expected by parameter $dqlPart of Doctrine\ORM\QueryBuilder::add(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

110
        $qb->add('select', /** @scrutinizer ignore-type */ 'count(u)')
Loading history...
111
            ->setFirstResult(null)
112
            ->setMaxResults(null);
113
114
        return $qb->getQuery()
115
            ->getSingleScalarResult();
116
    }
117
118
    public function getRecords()
119
    {
120
        return $this->getQueryBuilder()->getQuery()
121
            ->getResult();
122
    }
123
124
    public function find($id)
125
    {
126
        if (!$this->hasIdColumn()) {
127
            throw new \Exception('No id column found for '.$this->entityName);
128
        }
129
        $qb = $this->entityManager->createQueryBuilder();
130
        $idColumn = $this->getIdColumn();
131
        $qb->from($this->entityName, 'a');
132
        $qb->select('a.'.implode(',a.', $this->getClassMetadata()->getFieldNames()));
133
        $qb->where('a.'.$idColumn.' = :id')->setParameter(':id', $id);
134
        $result = $qb->getQuery()->execute();
135
        if (isset($result[0])) {
136
            return $result[0];
137
        }
138
    }
139
140
    public function remove($id)
141
    {
142
        if (!$this->hasIdColumn()) {
143
            throw new \Exception('No id column found for '.$this->entityName);
144
        }
145
146
        $repository = $this->entityManager->getRepository($this->entityName);
147
        $entity = $repository->find($id);
148
149
        if ($entity) {
150
            $this->entityManager->remove($entity);
151
            $this->entityManager->flush();
152
153
            return true;
154
        }
155
156
        return false;
157
    }
158
}
159