Completed
Pull Request — 5.6 (#2830)
by Jeroen
14:14
created

AbstractDoctrineORMAdminListConfigurator.php (2 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
namespace Kunstmaan\AdminListBundle\AdminList\Configurator;
4
5
use Doctrine\ORM\EntityManagerInterface;
6
use Doctrine\ORM\Query;
7
use Doctrine\ORM\QueryBuilder;
8
use Kunstmaan\AdminBundle\Helper\Security\Acl\AclHelper;
9
use Kunstmaan\AdminBundle\Helper\Security\Acl\Permission\PermissionDefinition;
10
use Kunstmaan\AdminListBundle\AdminList\Filter;
11
use Kunstmaan\AdminListBundle\AdminList\FilterType\ORM\AbstractORMFilterType;
12
use Kunstmaan\AdminListBundle\AdminList\SortableInterface;
13
use Pagerfanta\Adapter\DoctrineORMAdapter;
14
use Pagerfanta\Pagerfanta;
15
use Traversable;
16
17
/**
18
 * An abstract admin list configurator that can be used with the orm query builder
19
 */
20
abstract class AbstractDoctrineORMAdminListConfigurator extends AbstractAdminListConfigurator
21
{
22
    /**
23
     * @var EntityManagerInterface
24
     */
25
    protected $em;
26
27
    /**
28
     * @var Query
29
     */
30
    private $query;
31
32
    /**
33
     * @var Pagerfanta
34
     */
35
    private $pagerfanta;
36
37
    /**
38
     * @var PermissionDefinition
39
     */
40
    private $permissionDef;
41
42
    /**
43
     * @var AclHelper
44
     */
45
    protected $aclHelper;
46
47
    /**
48
     * AbstractDoctrineORMAdminListConfigurator constructor.
49
     */
50 31
    public function __construct(EntityManagerInterface $em, AclHelper $aclHelper = null)
51
    {
52 31
        $this->em = $em;
53 31
        $this->aclHelper = $aclHelper;
54 31
    }
55
56
    /**
57
     * Return the url to edit the given $item
58
     *
59
     * @param object $item
60
     *
61
     * @return array
62
     */
63 1 View Code Duplication
    public function getEditUrlFor($item)
64
    {
65 1
        $params = ['id' => $item->getId()];
66 1
        $params = array_merge($params, $this->getExtraParameters());
67
68
        return [
69 1
            'path' => $this->getPathByConvention($this::SUFFIX_EDIT),
70 1
            'params' => $params,
71
        ];
72
    }
73
74
    /**
75
     * Get the delete url for the given $item
76
     *
77
     * @param object $item
78
     *
79
     * @return array
80
     */
81 1 View Code Duplication
    public function getDeleteUrlFor($item)
82
    {
83 1
        $params = ['id' => $item->getId()];
84 1
        $params = array_merge($params, $this->getExtraParameters());
85
86
        return [
87 1
            'path' => $this->getPathByConvention($this::SUFFIX_DELETE),
88 1
            'params' => $params,
89
        ];
90
    }
91
92
    /**
93
     * @return Pagerfanta
94
     */
95 1 View Code Duplication
    public function getPagerfanta()
96
    {
97 1
        if (\is_null($this->pagerfanta)) {
98 1
            $adapter = new DoctrineORMAdapter($this->getQuery());
99 1
            $this->pagerfanta = new Pagerfanta($adapter);
100 1
            $this->pagerfanta->setNormalizeOutOfRangePages(true);
101 1
            $this->pagerfanta->setMaxPerPage($this->getLimit());
102 1
            $this->pagerfanta->setCurrentPage($this->getPage());
103
        }
104
105 1
        return $this->pagerfanta;
106
    }
107
108 8
    public function adaptQueryBuilder(QueryBuilder $queryBuilder)
109
    {
110 8
        $queryBuilder->where('1=1');
111 8
    }
112
113
    /**
114
     * @return int
0 ignored issues
show
Should the return type not be integer|null?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
115
     */
116
    public function getCount()
117
    {
118
        return $this->getPagerfanta()->getNbResults();
119
    }
120
121
    /**
122
     * @return array|Traversable
0 ignored issues
show
Should the return type not be \Pagerfanta\iterable|null?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
123
     */
124
    public function getItems()
125
    {
126
        return $this->getPagerfanta()->getCurrentPageResults();
127
    }
128
129
    /**
130
     * Return an iterator for all items that matches the current filtering
131
     *
132
     * @return \Iterator
133
     */
134 1
    public function getIterator()
135
    {
136 1
        return $this->getQuery()->iterate();
137
    }
138
139
    /**
140
     * @return Query|null
141
     */
142 5
    public function getQuery()
143
    {
144 5
        if (\is_null($this->query)) {
145 5
            $queryBuilder = $this->getQueryBuilder();
146 5
            $this->adaptQueryBuilder($queryBuilder);
147
148
            // Apply filters
149 5
            $filters = $this->getFilterBuilder()->getCurrentFilters();
150
            /* @var Filter $filter */
151 5
            foreach ($filters as $filter) {
152
                /* @var AbstractORMFilterType $type */
153 1
                $type = $filter->getType();
154 1
                $type->setQueryBuilder($queryBuilder);
155 1
                $filter->apply();
156
            }
157
158
            // Apply sorting
159 5
            if (!empty($this->orderBy)) {
160 1
                $orderBy = $this->orderBy;
161 1
                if ($this->getEntityManager()->getClassMetadata($this->getRepositoryName())->hasAssociation($this->orderBy)) {
162
                    $queryBuilder->leftJoin('b.' . $orderBy, 'A' . $orderBy);
163
                    $orderBy = 'A' . $orderBy . '.id';
164 1
                } elseif (!strpos($orderBy, '.')) {
165 1
                    $orderBy = 'b.' . $orderBy;
166
                }
167 1
                $queryBuilder->orderBy($orderBy, ($this->orderDirection == 'DESC' ? 'DESC' : 'ASC'));
168
            }
169
170
            // Apply other changes
171 5
            $this->finishQueryBuilder($queryBuilder);
172
173
            // Apply ACL restrictions (if applicable)
174 5
            if (!\is_null($this->permissionDef) && !\is_null($this->aclHelper)) {
175
                $this->query = $this->aclHelper->apply($queryBuilder, $this->permissionDef);
176
            } else {
177 5
                $this->query = $queryBuilder->getQuery();
178
            }
179
        }
180
181 5
        return $this->query;
182
    }
183
184 5
    protected function finishQueryBuilder(QueryBuilder $queryBuilder)
185
    {
186 5
        if ($this instanceof SortableInterface) {
187
            $queryBuilder->addOrderBy('b.' . $this->getSortableField());
188
        }
189 5
    }
190
191
    /**
192
     * @return QueryBuilder
193
     */
194 5
    protected function getQueryBuilder()
195
    {
196 5
        $queryBuilder = $this->em
197 5
            ->getRepository($this->getRepositoryName())
198 5
            ->createQueryBuilder('b');
199
200 5
        return $queryBuilder;
201
    }
202
203
    /**
204
     * Get current permission definition.
205
     *
206
     * @return PermissionDefinition|null
207
     */
208 1
    public function getPermissionDefinition()
209
    {
210 1
        return $this->permissionDef;
211
    }
212
213
    /**
214
     * Set permission definition.
215
     *
216
     * @return AbstractDoctrineORMAdminListConfigurator
217
     */
218 13
    public function setPermissionDefinition(PermissionDefinition $permissionDef)
219
    {
220 13
        $this->permissionDef = $permissionDef;
221
222 13
        return $this;
223
    }
224
225
    /**
226
     * @return AbstractDoctrineORMAdminListConfigurator
227
     */
228 1
    public function setEntityManager(EntityManagerInterface $em)
229
    {
230 1
        $this->em = $em;
231
232 1
        return $this;
233
    }
234
235
    /**
236
     * @return EntityManagerInterface
237
     */
238 2
    public function getEntityManager()
239
    {
240 2
        return $this->em;
241
    }
242
}
243