Passed
Push — master ( f19064...ccb5fd )
by Julito
09:49
created

CDocumentRepository::getParent()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 14
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 7
nc 2
nop 1
dl 0
loc 14
rs 10
c 0
b 0
f 0
1
<?php
2
/* For licensing terms, see /license.txt */
3
4
namespace Chamilo\CourseBundle\Repository;
5
6
use Chamilo\CoreBundle\Entity\Resource\ResourceLink;
7
use Chamilo\CoreBundle\Entity\Resource\ResourceNode;
8
use Chamilo\CoreBundle\Entity\Resource\ResourceRight;
9
use Chamilo\CoreBundle\Repository\ResourceRepository;
10
use Chamilo\CoreBundle\Security\Authorization\Voter\ResourceNodeVoter;
11
use Chamilo\CourseBundle\Entity\CDocument;
12
use Doctrine\ORM\EntityManager;
13
use Doctrine\ORM\EntityRepository;
14
use Gaufrette\Exception\FileNotFound;
15
use Sonata\MediaBundle\Provider\MediaProviderInterface;
16
use Sonata\MediaBundle\Provider\Pool;
17
18
/**
19
 * Class CDocumentRepository.
20
 */
21
class CDocumentRepository extends ResourceRepository
22
{
23
    /**
24
     * @var EntityRepository
25
     */
26
    private $repository;
27
28
    /**
29
     * @var Pool
30
     */
31
    private $mediaPool;
32
33
    /**
34
     * CDocumentRepository constructor.
35
     *
36
     * @param EntityManager $entityManager
37
     * @param Pool          $mediaPool
38
     */
39
    public function __construct(EntityManager $entityManager, Pool $mediaPool)
40
    {
41
        $this->repository = $entityManager->getRepository(CDocument::class);
42
        $this->mediaPool = $mediaPool;
43
        $this->entityManager = $entityManager;
44
    }
45
46
    /**
47
     * @param int $id
48
     *
49
     * @return CDocument|null
50
     */
51
    public function find(int $id): ?CDocument
52
    {
53
        return $this->repository->find($id);
54
    }
55
56
    /**
57
     * @param array      $criteria
58
     * @param array|null $orderBy
59
     *
60
     * @return CDocument|null
61
     */
62
    public function findOneBy(array $criteria, array $orderBy = null): ?CDocument
63
    {
64
        return $this->repository->findOneBy($criteria, $orderBy);
65
    }
66
67
    /**
68
     * @param int $id
69
     *
70
     * @return string
71
     */
72
    public function getDocumentPath($id): string
73
    {
74
        try {
75
            $document = $this->find($id);
76
            $resourceNode = $document->getResourceNode();
77
            $resourceFile = $resourceNode->getResourceFile();
78
            $media = $resourceFile->getMedia();
79
            $provider = $this->mediaPool->getProvider($media->getProviderName());
80
81
            $format = MediaProviderInterface::FORMAT_REFERENCE;
82
            $filename = sprintf(
83
                '%s/%s',
84
                $provider->getFilesystem()->getAdapter()->getDirectory(),
85
                $provider->generatePrivateUrl($media, $format)
86
            );
87
88
            return $filename;
89
        } catch (\Throwable $exception) {
90
            throw new FileNotFound($id);
91
        }
92
    }
93
94
    /**
95
     * @param CDocument $document
96
     *
97
     * @return CDocument|null
98
     */
99
    public function getParent(CDocument $document)
100
    {
101
        $resourceParent = $document->getResourceNode()->getParent();
102
103
        if (!empty($resourceParent)) {
104
            $resourceParentId = $resourceParent->getId();
105
            $criteria = [
106
                'resourceNode' => $resourceParentId,
107
            ];
108
109
            return $this->findOneBy($criteria);
110
        }
111
112
        return null;
113
    }
114
115
    /**
116
     * @param int    $courseId
117
     * @param string $path
118
     *
119
     * @return mixed
120
     * @throws \Doctrine\ORM\NonUniqueResultException
121
     */
122
    public function getFolderSize($courseId, $path)
123
    {
124
        $path = str_replace('_', '\_', $path);
125
        $addedSlash = $path === '/' ? '' : '/';
126
127
        $repo = $this->repository;
128
        $qb = $repo->createQueryBuilder('d');
129
        $query = $qb
130
            ->select('SUM(d.size)')
131
            ->innerJoin('d.resourceNode', 'r')
132
            ->innerJoin('r.resourceLinks', 'l')
133
            ->where('d.path LIKE :path')
134
            ->andWhere('d.path NOT LIKE :deleted')
135
            ->andWhere('d.path NOT LIKE :extra_path ')
136
            ->andWhere('l.visibility <> :visibility')
137
            ->andWhere('d.course = :course')
138
            ->setParameters([
139
                'path' => $path.$addedSlash.'%',
140
                'extra_path' => $path.$addedSlash.'%/%',
141
                'course' => $courseId,
142
                'deleted' => '%_DELETED_%',
143
                'visibility' => ResourceLink::VISIBILITY_DELETED,
144
            ])
145
            ->getQuery();
146
147
        return $query->getSingleScalarResult();
148
    }
149
150
    /**
151
     * @param int $courseId
152
     * @param int $groupId
153
     * @param int $sessionId
154
     *
155
     * @return mixed
156
     * @throws \Doctrine\ORM\NonUniqueResultException
157
     */
158
    public function getTotalSpace($courseId, $groupId = null, $sessionId = null)
159
    {
160
        $repo = $this->repository;
161
        $groupId = empty($groupId) ? null : $groupId;
162
        $sessionId = empty($sessionId) ? null : $sessionId;
163
164
        $qb = $repo->createQueryBuilder('d');
165
        $query = $qb
166
            ->select('SUM(d.size)')
167
            ->innerJoin('d.resourceNode', 'r')
168
            ->innerJoin('r.resourceLinks', 'l')
169
            ->where('l.course = :course')
170
            ->andWhere('l.group = :group')
171
            ->andWhere('l.session = :session')
172
            ->andWhere('l.visibility <> :visibility')
173
            ->setParameters([
174
                'course' => $courseId,
175
                'group' => $groupId,
176
                'session' => $sessionId,
177
                'visibility' => ResourceLink::VISIBILITY_DELETED,
178
            ])
179
            ->getQuery();
180
181
        return $query->getSingleScalarResult();
182
    }
183
184
    /**
185
     * Changes current document link visibility.
186
     *
187
     * @param CDocument $document
188
     * @param int       $visibility
189
     *
190
     * @return bool
191
     */
192
    public function setVisibility($document, $visibility)
193
    {
194
        if (empty($document)) {
195
            return false;
196
        }
197
198
        $em = $this->entityManager;
199
        $link = $document->getCourseSessionResourceLink();
200
        $link->setVisibility($visibility);
201
202
        if ($visibility === ResourceLink::VISIBILITY_DRAFT) {
203
            $editorMask = ResourceNodeVoter::getEditorMask();
204
            $rights = [];
205
            $resourceRight = new ResourceRight();
206
            $resourceRight
207
                ->setMask($editorMask)
208
                ->setRole(ResourceNodeVoter::ROLE_CURRENT_COURSE_TEACHER)
209
                ->setResourceLink($link)
210
            ;
211
            $rights[] = $resourceRight;
212
213
            if (!empty($rights)) {
214
                $link->setResourceRight($rights);
215
            }
216
        } else {
217
            $link->setResourceRight([]);
218
        }
219
        $em->persist($link);
220
        $em->flush();
221
222
        return true;
223
    }
224
225
    /**
226
     * Change all links visibility to DELETED.
227
     *
228
     * @param CDocument $document
229
     */
230
    public function softDelete($document)
231
    {
232
        $this->setLinkVisibility($document, ResourceLink::VISIBILITY_DELETED);
233
    }
234
235
    /**
236
     * @param int $userId
237
     *
238
     * @return array
239
     */
240
    public function getAllDocumentsByAuthor($userId)
241
    {
242
        $repo = $this->repository;
243
244
        $qb = $repo->createQueryBuilder('d');
245
        $query = $qb
246
            ->innerJoin('d.resourceNode', 'r')
247
            ->innerJoin('r.resourceLinks', 'l')
248
            ->where('l.user = :user')
249
            ->andWhere('l.visibility <> :visibility')
250
            ->setParameters([
251
                'user' => $userId,
252
                'visibility' => ResourceLink::VISIBILITY_DELETED,
253
            ])
254
            ->getQuery();
255
256
        return $query->getResult();
257
    }
258
259
    /**
260
     * @param CDocument $document
261
     * @param int       $visibility
262
     * @param bool      $recursive
263
     */
264
    private function setLinkVisibility($document, $visibility, $recursive = true)
265
    {
266
        $resourceNode = $document->getResourceNode();
267
        $children = $resourceNode->getChildren();
268
269
        if ($recursive) {
270
            if (!empty($children)) {
271
                /** @var ResourceNode $child */
272
                foreach ($children as $child) {
273
                    $criteria = ['resourceNode' => $child];
274
                    $childDocument = $this->repository->findOneBy($criteria);
275
                    if ($childDocument) {
276
                        $this->setLinkVisibility($childDocument, $visibility);
277
                    }
278
                }
279
            }
280
        }
281
282
        $links = $resourceNode->getResourceLinks();
283
284
        if (!empty($links)) {
285
            /** @var ResourceLink $link */
286
            foreach ($links as $link) {
287
                $link->setVisibility($visibility);
288
289
                if ($visibility === ResourceLink::VISIBILITY_DRAFT) {
290
                    $editorMask = ResourceNodeVoter::getEditorMask();
291
                    $rights = [];
292
                    $resourceRight = new ResourceRight();
293
                    $resourceRight
294
                        ->setMask($editorMask)
295
                        ->setRole(ResourceNodeVoter::ROLE_CURRENT_COURSE_TEACHER)
296
                        ->setResourceLink($link)
297
                    ;
298
                    $rights[] = $resourceRight;
299
300
                    if (!empty($rights)) {
301
                        $link->setResourceRight($rights);
302
                    }
303
                } else {
304
                    $link->setResourceRight([]);
305
                }
306
                $this->entityManager->merge($link);
307
            }
308
        }
309
310
        $this->entityManager->flush();
311
    }
312
}
313