Completed
Push — master ( 2ae089...5f42d6 )
by Luis Ramón
13:38
created

ElementRepository::findAllSubProfilesQueryBuilder()   B

Complexity

Conditions 5
Paths 8

Size

Total Lines 24
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 24
rs 8.5125
c 0
b 0
f 0
cc 5
eloc 15
nc 8
nop 2
1
<?php
2
/*
3
  ÁTICA - Aplicación web para la gestión documental de centros educativos
4
5
  Copyright (C) 2015-2017: Luis Ramón López López
6
7
  This program is free software: you can redistribute it and/or modify
8
  it under the terms of the GNU Affero General Public License as published by
9
  the Free Software Foundation, either version 3 of the License, or
10
  (at your option) any later version.
11
12
  This program is distributed in the hope that it will be useful,
13
  but WITHOUT ANY WARRANTY; without even the implied warranty of
14
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
  GNU Affero General Public License for more details.
16
17
  You should have received a copy of the GNU Affero General Public License
18
  along with this program.  If not, see [http://www.gnu.org/licenses/].
19
*/
20
21
namespace AppBundle\Entity;
22
23
use AppBundle\Entity\Documentation\Folder;
24
use Doctrine\Common\Collections\ArrayCollection;
25
use Doctrine\ORM\QueryBuilder;
26
use Gedmo\Tree\Entity\Repository\NestedTreeRepository;
27
28
class ElementRepository extends NestedTreeRepository
29
{
30
    /**
31
     * @param Organization $organization
32
     * @return null|object
33
     */
34
    public function findCurrentOneByOrganization(Organization $organization)
35
    {
36
        $item = $organization->getElement() ?: $this->findOneBy(['organization' => $organization, 'parent' => null], ['left' => 'DESC']);
37
38
        return $item;
39
    }
40
41
    /**
42
     * @param Organization  $organization
43
     * @param string        $rootName
44
     * @return null|object
45
     */
46
    public function findOneByOrganizationAndRootName(Organization $organization, $rootName)
47
    {
48
        return $this->findOneBy(['organization' => $organization, 'name' => $rootName, 'parent' => null]);
49
    }
50
51
    /**
52
     * @param Organization  $organization
53
     * @param string        $path
54
     * @return null|object
55
     */
56
    public function findOneByOrganizationAndPath(Organization $organization, $path)
57
    {
58
        if (!$path) {
59
            return null;
60
        }
61
62
        $items = explode('/', $path);
63
        $itemName = array_shift($items);
64
        $current = null;
65
66
        while ($itemName) {
67
            $current = $this->findOneBy(['organization' => $organization, 'name' => $itemName, 'parent' => $current]);
68
            $itemName = array_shift($items);
69
        }
70
71
        return $current;
72
    }
73
74
    /**
75
     * @param Organization $organization
76
     * @param string $code
77
     * @return null|object
78
     */
79
    public function findOneByOrganizationAndCurrentCode(Organization $organization, $code)
80
    {
81
        $item = $this->findCurrentOneByOrganization($organization);
82
83
        if (null === $item) {
84
            return null;
85
        }
86
87
        return $this->getChildrenQueryBuilder($item)
88
            ->andWhere('node.code = :code')
89
            ->setParameter('code', $code)
90
            ->getQuery()
91
            ->getOneOrNullResult();
92
    }
93
94
    /**
95
     * @param Element[] $elements
96
     * @param boolean $final
97
     *
98
     * @return QueryBuilder
99
     */
100
    public function findAllSubProfilesQueryBuilder(array $elements, $final = false) {
101
        $collection = new ArrayCollection();
102
103
        foreach ($elements as $profile) {
104
            $children = $this->getChildren($profile, false, null, 'ASC', true);
105
            foreach ($children as $element) {
106
                if (!$collection->contains($element)) {
107
                    $collection->add($element);
108
                }
109
            }
110
        }
111
112
        $qb = $this->createQueryBuilder('e')
113
            ->andWhere('e IN (:profiles)')
114
            ->orderBy('e.left')
115
            ->setParameter('profiles', $collection);
116
117
        if ($final) {
118
            $qb = $qb
119
                ->andWhere('e.left = e.right - 1');
120
        }
121
122
        return $qb;
123
    }
124
125
    /**
126
     * @param Organization $organization
127
     * @return QueryBuilder
128
     */
129
    public function findAllProfilesByOrganizationQueryBuilder(Organization $organization)
130
    {
131
        $profileElements = $this->createQueryBuilder('e')
132
            ->innerJoin('e.profile', 'p')
133
            ->where('e.organization = :organization')
134
            ->setParameter('organization', $organization)
135
            ->getQuery()
136
            ->getResult();
137
138
        return $this->findAllSubProfilesQueryBuilder($profileElements);
139
    }
140
141
    /**
142
     * @param Folder $folder
143
     * @param integer $permission
144
     * @param boolean $final
145
     *
146
     * @return QueryBuilder
147
     */
148
    public function findAllProfilesByFolderPermissionQueryBuilder(Folder $folder, $permission, $final = false)
149
    {
150
        $profileElements = $this->getEntityManager()->createQuery(
151
            'SELECT e FROM AppBundle:Element e WHERE e IN (SELECT DISTINCT IDENTITY(fp.element) FROM AppBundle:Documentation\FolderPermission fp WHERE fp.folder = :folder AND fp.permission = :permission)')
152
            ->setParameter('folder', $folder)
153
            ->setParameter('permission', $permission)
154
            ->getResult();
155
156
        return $this->findAllSubProfilesQueryBuilder($profileElements, $final);
157
    }
158
159
    /**
160
     * @param Folder $folder
161
     * @param int $permission
162
     * @param User $user
163
     * @param boolean $final
164
     *
165
     * @return Element[]
166
     */
167
    public function findAllProfilesByFolderPermissionAndUser(Folder $folder, $permission, User $user, $final = false)
168
    {
169
        return $this->findAllProfilesByFolderPermissionQueryBuilder($folder, $permission, $final)
170
            ->innerJoin('AppBundle:Role', 'r', 'WITH', 'r.element = e')
171
            ->join('r.user', 'u')
172
            ->andWhere('r.user = :user')
173
            ->setParameter('user', $user)
174
            ->getQuery()->getResult();
175
    }
176
177
    /**
178
     * @param Folder $folder
179
     * @param integer $permission
180
     * @param boolean $final
181
     *
182
     * @return Element[]
183
     */
184
    public function findAllProfilesByFolderPermission(Folder $folder, $permission, $final = false)
185
    {
186
        return $this->findAllProfilesByFolderPermissionQueryBuilder($folder, $permission, $final)->getQuery()->getResult();
187
    }
188
189
    /**
190
     * @param Element $element
191
     *
192
     * @return Element[]
193
     */
194
    public function findAllAncestorProfiles(Element $element) {
195
        $elements = [$element];
196
197
        while ($element->getParent() && $element->getProfile() === null) {
198
            $element = $element->getParent();
199
            $elements[] = $element;
200
        }
201
202
        return $elements;
203
    }
204
205
    /**
206
     * @param Element[] $elements
207
     * @return Element[]
208
     */
209
    public function findAllAncestorProfilesInArray(array $elements) {
210
        $results = [];
211
212
        foreach ($elements as $element) {
213
            $results[] = $this->findAllAncestorProfiles($element);
214
        }
215
216
        return array_unique(call_user_func_array('array_merge', $results));
217
    }
218
219
    /**
220
     * @param User $user
221
     * @param Organization $organization
222
     * @return Element[]
223
     */
224
    public function findAllProfilesByUserAndOrganization(User $user, Organization $organization)
225
    {
226
        $profiles = $this->getEntityManager()->createQuery(
227
            'SELECT e FROM AppBundle:Element e WHERE e.organization = :organization AND e.id IN (
228
                SELECT IDENTITY(r.element) FROM AppBundle:Role r WHERE r.user = :user
229
            )')
230
            ->setParameter('organization', $organization)
231
            ->setParameter('user', $user)
232
            ->getResult();
233
234
        return $this->getEntityManager()->getRepository('AppBundle:Element')
235
            ->findAllAncestorProfilesInArray($profiles);
236
    }
237
}
238