Completed
Push — master ( 06c1ce...67d37c )
by Jeroen
06:20
created

MediaBundle/Repository/FolderRepository.php (1 issue)

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\MediaBundle\Repository;
4
5
use Doctrine\ORM\EntityNotFoundException;
6
use Doctrine\ORM\Query;
7
use Doctrine\ORM\QueryBuilder;
8
use Gedmo\Tree\Entity\Repository\NestedTreeRepository;
9
use Kunstmaan\MediaBundle\Entity\Folder;
10
use Kunstmaan\MediaBundle\Entity\Media;
11
12
/**
13
 * FolderRepository
14
 *
15
 * @method FolderRepository persistAsFirstChild(object $node)
16
 * @method FolderRepository persistAsFirstChildOf(object $node, object $parent)
17
 * @method FolderRepository persistAsLastChild(object $node)
18
 * @method FolderRepository persistAsLastChildOf(object $node, object $parent)
19
 * @method FolderRepository persistAsNextSibling(object $node)
20
 * @method FolderRepository persistAsNextSiblingOf(object $node, object $sibling)
21
 * @method FolderRepository persistAsPrevSibling(object $node)
22
 * @method FolderRepository persistAsPrevSiblingOf(object $node, object $sibling)
23
 */
24
class FolderRepository extends NestedTreeRepository
25
{
26
    /**
27
     * @param Folder $folder The folder
28
     *
29
     * @throws \Exception
30
     */
31
    public function save(Folder $folder)
32
    {
33
        $em = $this->getEntityManager();
34
        $parent = $folder->getParent();
35
36
        $em->beginTransaction();
37
38
        try {
39
            if (!\is_null($parent)) {
40
                $this->persistInOrderedTree($folder, $parent);
41
            } else {
42
                $em->persist($folder);
43
            }
44
            $em->commit();
45
            $em->flush();
46
        } catch (\Exception $e) {
47
            $em->rollback();
48
49
            throw $e;
50
        }
51
    }
52
53
    /**
54
     * @param Folder $folder
55
     */
56 View Code Duplication
    public function delete(Folder $folder)
57
    {
58
        $em = $this->getEntityManager();
59
60
        $this->deleteMedia($folder);
61
        $this->deleteChildren($folder);
62
        $folder->setDeleted(true);
63
        $em->persist($folder);
64
        $em->flush();
65
    }
66
67
    /**
68
     * @param Folder $folder
69
     * @param bool   $alsoDeleteFolders
70
     */
71 View Code Duplication
    public function emptyFolder(Folder $folder, $alsoDeleteFolders = false)
0 ignored issues
show
This method seems to be duplicated in 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...
72
    {
73
        $em = $this->getEntityManager();
74
        $this->deleteMedia($folder);
75
        if ($alsoDeleteFolders) {
76
            $this->deleteChildren($folder);
77
        }
78
        $em->flush();
79
    }
80
81
    /**
82
     * @param Folder $folder
83
     */
84
    private function deleteMedia(Folder $folder)
85
    {
86
        $em = $this->getEntityManager();
87
88
        /** @var Media $media */
89
        foreach ($folder->getMedia() as $media) {
90
            $media->setDeleted(true);
91
            $em->persist($media);
92
        }
93
    }
94
95
    /**
96
     * @param Folder $folder
97
     */
98 View Code Duplication
    private function deleteChildren(Folder $folder)
99
    {
100
        $em = $this->getEntityManager();
101
102
        /** @var Folder $child */
103
        foreach ($folder->getChildren() as $child) {
104
            $this->deleteMedia($child);
105
            $this->deleteChildren($child);
106
            $child->setDeleted(true);
107
            $em->persist($child);
108
        }
109
    }
110
111
    /**
112
     * @param int $limit
113
     *
114
     * @return array
115
     */
116
    public function getAllFolders($limit = null)
117
    {
118
        $qb = $this->createQueryBuilder('folder')
119
            ->select('folder')
120
            ->where('folder.parent is null AND folder.deleted != true')
121
            ->orderBy('folder.name');
122
123
        if (false === \is_null($limit)) {
124
            $qb->setMaxResults($limit);
125
        }
126
127
        return $qb->getQuery()->getResult();
128
    }
129
130
    /**
131
     * @param int $folderId
132
     *
133
     * @return object
134
     *
135
     * @throws EntityNotFoundException
136
     */
137
    public function getFolder($folderId)
138
    {
139
        $folder = $this->find($folderId);
140
        if (!$folder) {
141
            throw new EntityNotFoundException();
142
        }
143
144
        return $folder;
145
    }
146
147
    public function getFirstTopFolder()
148
    {
149
        $folder = $this->findOneBy(array('parent' => null));
150
        if (!$folder) {
151
            throw new EntityNotFoundException();
152
        }
153
154
        return $folder;
155
    }
156
157
    public function getParentIds(Folder $folder)
158
    {
159
        /** @var QueryBuilder $qb */
160
        $qb = $this->getPathQueryBuilder($folder)
161
            ->select('node.id');
162
163
        $result = $qb->getQuery()->getScalarResult();
164
        $ids = array_map('current', $result);
165
166
        return $ids;
167
    }
168
169
    /**
170
     * {@inheritdoc}
171
     */
172
    public function getPathQueryBuilder($node)
173
    {
174
        /** @var QueryBuilder $qb */
175
        $qb = parent::getPathQueryBuilder($node);
176
        $qb->andWhere('node.deleted != true');
177
178
        return $qb;
179
    }
180
181
    /**
182
     * {@inheritdoc}
183
     */
184
    public function getRootNodesQueryBuilder($sortByField = null, $direction = 'asc')
185
    {
186
        /** @var QueryBuilder $qb */
187
        $qb = parent::getRootNodesQueryBuilder($sortByField, $direction);
188
        $qb->andWhere('node.deleted != true');
189
190
        return $qb;
191
    }
192
193
    /**
194
     * {@inheritdoc}
195
     */
196
    public function childrenQueryBuilder(
197
        $node = null,
198
        $direct = false,
199
        $sortByField = null,
200
        $direction = 'ASC',
201
        $includeNode = false
202
    ) {
203
        /** @var QueryBuilder $qb */
204
        $qb = parent::childrenQueryBuilder($node, $direct, $sortByField, $direction, $includeNode);
205
        $qb->andWhere('node.deleted != true');
206
207
        return $qb;
208
    }
209
210
    /**
211
     * {@inheritdoc}
212
     */
213
    public function getLeafsQueryBuilder($root = null, $sortByField = null, $direction = 'ASC')
214
    {
215
        /** @var QueryBuilder $qb */
216
        $qb = parent::getLeafsQueryBuilder($root, $sortByField, $direction);
217
        $qb->andWhere('node.deleted != true');
218
219
        return $qb;
220
    }
221
222
    /**
223
     * {@inheritdoc}
224
     */
225
    public function getNextSiblingsQueryBuilder($node, $includeSelf = false)
226
    {
227
        /** @var QueryBuilder $qb */
228
        $qb = parent::getNextSiblingsQueryBuilder($node, $includeSelf);
229
        $qb->andWhere('node.deleted != true');
230
231
        return $qb;
232
    }
233
234
    /**
235
     * {@inheritdoc}
236
     */
237
    public function getPrevSiblingsQueryBuilder($node, $includeSelf = false)
238
    {
239
        /** @var QueryBuilder $qb */
240
        $qb = parent::getPrevSiblingsQueryBuilder($node, $includeSelf);
241
        $qb->andWhere('node.deleted != true');
242
243
        return $qb;
244
    }
245
246
    /**
247
     * {@inheritdoc}
248
     */
249
    public function getNodesHierarchyQueryBuilder(
250
        $node = null,
251
        $direct = false,
252
        array $options = array(),
253
        $includeNode = false
254
    ) {
255
        /** @var QueryBuilder $qb */
256
        $qb = parent::getNodesHierarchyQueryBuilder($node, $direct, $options, $includeNode);
257
        $qb->andWhere('node.deleted != true');
258
259
        return $qb;
260
    }
261
262
    /**
263
     * {@inheritdoc}
264
     */
265
    public function getNodesHierarchy($node = null, $direct = false, array $options = array(), $includeNode = false)
266
    {
267
        $query = $this->getNodesHierarchyQuery($node, $direct, $options, $includeNode);
268
        $query->setHint(
269
            Query::HINT_CUSTOM_OUTPUT_WALKER,
270
            'Gedmo\\Translatable\\Query\\TreeWalker\\TranslationWalker'
271
        );
272
273
        return $query->getArrayResult();
274
    }
275
276
    /**
277
     * Rebuild the nested tree
278
     */
279
    public function rebuildTree()
280
    {
281
        $em = $this->getEntityManager();
282
283
        // Reset tree...
284
        $sql = 'UPDATE kuma_folders SET lvl=NULL,lft=NULL,rgt=NULL';
285
        $stmt = $em->getConnection()->prepare($sql);
286
        $stmt->execute();
287
288
        $folders = $this->findBy(array(), array('parent' => 'ASC', 'name' => 'asc'));
289
290
        $rootFolder = $folders[0];
291
        $first = true;
292
        foreach ($folders as $folder) {
293
            // Force parent load
294
            $parent = $folder->getParent();
295
            if (\is_null($parent)) {
296
                $folder->setLevel(0);
297
                if ($first) {
298
                    $this->persistAsFirstChild($folder);
299
                    $first = false;
300
                } else {
301
                    $this->persistAsNextSiblingOf($folder, $rootFolder);
302
                }
303
            } else {
304
                $folder->setLevel($parent->getLevel() + 1);
305
                $this->persistAsLastChildOf($folder, $parent);
306
            }
307
        }
308
        $em->flush();
309
    }
310
311
    /**
312
     * Used as querybuilder for Folder entity selectors
313
     *
314
     * @param Folder $ignoreSubtree Folder (with children) that has to be filtered out (optional)
315
     *
316
     * @return QueryBuilder
317
     */
318
    public function selectFolderQueryBuilder(Folder $ignoreSubtree = null)
319
    {
320
        /** @var QueryBuilder $qb */
321
        $qb = $this->createQueryBuilder('f');
322
        $qb->where('f.deleted != true')
323
            ->orderBy('f.lft');
324
325
        // Fetch all folders except the current one and its children
326
        if (!\is_null($ignoreSubtree) && $ignoreSubtree->getId() !== null) {
327
            $orX = $qb->expr()->orX();
328
            $orX->add('f.rgt > :right')
329
                ->add('f.lft < :left');
330
331
            $qb->andWhere($orX)
332
                ->setParameter('left', $ignoreSubtree->getLeft())
333
                ->setParameter('right', $ignoreSubtree->getRight());
334
        }
335
336
        return $qb;
337
    }
338
339
    /**
340
     * @param Folder $folder
341
     * @param        $parent
342
     */
343
    private function persistInOrderedTree(Folder $folder, $parent)
344
    {
345
        // Find where to insert the new item
346
        $children = $parent->getChildren(true);
347
        if ($children->isEmpty()) {
348
            // No children yet - insert as first child
349
            $this->persistAsFirstChildOf($folder, $parent);
350
        } else {
351
            $previousChild = null;
352
            foreach ($children as $child) {
353
                // Alphabetical sorting - could be nice if we implemented a sorting strategy
354
                if (strcasecmp($folder->getName(), $child->getName()) < 0) {
355
                    break;
356
                }
357
                $previousChild = $child;
358
            }
359
            if (\is_null($previousChild)) {
360
                $this->persistAsPrevSiblingOf($folder, $children[0]);
361
            } else {
362
                $this->persistAsNextSiblingOf($folder, $previousChild);
363
            }
364
        }
365
    }
366
}
367