Completed
Push — master ( 38e61c...cd9a17 )
by Julito
14:03
created

CDocumentRepository::updateVisibility()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 31
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 21
c 0
b 0
f 0
nop 2
dl 0
loc 31
rs 9.584
nc 4
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 League\Flysystem\FilesystemInterface;
16
use League\Flysystem\MountManager;
17
18
/**
19
 * Class CDocumentRepository.
20
 */
21
class CDocumentRepository extends ResourceRepository
22
{
23
    /**
24
     * @var EntityRepository
25
     */
26
    private $repository;
27
28
    /**
29
     * @var FilesystemInterface
30
     */
31
    private $fs;
32
33
    /**
34
     * CDocumentRepository constructor.
35
     *
36
     * @param EntityManager $entityManager
37
     * @param MountManager  $mountManager
38
     */
39
    public function __construct(EntityManager $entityManager, MountManager $mountManager)
40
    {
41
        $this->repository = $entityManager->getRepository(CDocument::class);
42
        $this->fs = $mountManager->getFilesystem('resources_fs');
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 getDocumentContent($id): string
73
    {
74
        try {
75
            $document = $this->find($id);
76
            $resourceNode = $document->getResourceNode();
77
            $resourceFile = $resourceNode->getResourceFile();
78
            $fileName = $resourceFile->getFile()->getPathname();
79
80
            return $this->fs->read($fileName);
81
        } catch (\Throwable $exception) {
82
            throw new FileNotFound($id);
83
        }
84
    }
85
86
    /**
87
     * @param CDocument $document
88
     * @param string    $content
89
     *
90
     * @return bool
91
     */
92
    public function updateDocumentContent(CDocument $document, $content)
93
    {
94
        try {
95
            $resourceNode = $document->getResourceNode();
96
            $resourceFile = $resourceNode->getResourceFile();
97
            $fileName = $resourceFile->getFile()->getPathname();
98
99
            $this->fs->update($fileName, $content);
100
            $size = $this->fs->getSize($fileName);
101
            $document->setSize($size);
102
            $this->entityManager->persist($document);
103
104
            return true;
105
        } catch (\Throwable $exception) {
0 ignored issues
show
Coding Style Comprehensibility introduced by
Consider adding a comment why this CATCH block is empty.
Loading history...
106
        }
107
    }
108
109
    /**
110
     * @param CDocument $document
111
     *
112
     * @return CDocument|null
113
     */
114
    public function getParent(CDocument $document)
115
    {
116
        $resourceParent = $document->getResourceNode()->getParent();
117
118
        if ($resourceParent !== null) {
119
            $resourceParentId = $resourceParent->getId();
120
            $criteria = [
121
                'resourceNode' => $resourceParentId,
122
            ];
123
124
            return $this->findOneBy($criteria);
125
        }
126
127
        return null;
128
    }
129
130
    /**
131
     * @param int    $courseId
132
     * @param string $path
133
     *
134
     * @throws \Doctrine\ORM\NonUniqueResultException
135
     *
136
     * @return mixed
137
     */
138
    public function getFolderSize($courseId, $path)
139
    {
140
        $path = str_replace('_', '\_', $path);
141
        $addedSlash = $path === '/' ? '' : '/';
142
143
        $repo = $this->repository;
144
        $qb = $repo->createQueryBuilder('d');
145
        $query = $qb
146
            ->select('SUM(d.size)')
147
            ->innerJoin('d.resourceNode', 'r')
148
            ->innerJoin('r.resourceLinks', 'l')
149
            ->where('d.path LIKE :path')
150
            ->andWhere('d.path NOT LIKE :deleted')
151
            ->andWhere('d.path NOT LIKE :extra_path ')
152
            ->andWhere('l.visibility <> :visibility')
153
            ->andWhere('d.course = :course')
154
            ->setParameters([
155
                'path' => $path.$addedSlash.'%',
156
                'extra_path' => $path.$addedSlash.'%/%',
157
                'course' => $courseId,
158
                'deleted' => '%_DELETED_%',
159
                'visibility' => ResourceLink::VISIBILITY_DELETED,
160
            ])
161
            ->getQuery();
162
163
        return $query->getSingleScalarResult();
164
    }
165
166
    /**
167
     * @param int $courseId
168
     * @param int $groupId
169
     * @param int $sessionId
170
     *
171
     * @throws \Doctrine\ORM\NonUniqueResultException
172
     *
173
     * @return mixed
174
     */
175
    public function getTotalSpace($courseId, $groupId = null, $sessionId = null)
176
    {
177
        $repo = $this->repository;
178
        $groupId = empty($groupId) ? null : $groupId;
179
        $sessionId = empty($sessionId) ? null : $sessionId;
180
181
        $qb = $repo->createQueryBuilder('d');
182
        $query = $qb
183
            ->select('SUM(d.size)')
184
            ->innerJoin('d.resourceNode', 'r')
185
            ->innerJoin('r.resourceLinks', 'l')
186
            ->where('l.course = :course')
187
            ->andWhere('l.group = :group')
188
            ->andWhere('l.session = :session')
189
            ->andWhere('l.visibility <> :visibility')
190
            ->setParameters([
191
                'course' => $courseId,
192
                'group' => $groupId,
193
                'session' => $sessionId,
194
                'visibility' => ResourceLink::VISIBILITY_DELETED,
195
            ])
196
            ->getQuery();
197
198
        return $query->getSingleScalarResult();
199
    }
200
201
    /**
202
     * Changes current document link visibility.
203
     *
204
     * @param CDocument $document
205
     * @param int       $visibility
206
     *
207
     * @return bool
208
     */
209
    public function updateVisibility($document, $visibility): bool
210
    {
211
        if (empty($document)) {
212
            return false;
213
        }
214
215
        $em = $this->entityManager;
216
        $link = $document->getCourseSessionResourceLink();
217
        $link->setVisibility($visibility);
218
219
        if ($visibility === ResourceLink::VISIBILITY_DRAFT) {
220
            $editorMask = ResourceNodeVoter::getEditorMask();
221
            $rights = [];
222
            $resourceRight = new ResourceRight();
223
            $resourceRight
224
                ->setMask($editorMask)
225
                ->setRole(ResourceNodeVoter::ROLE_CURRENT_COURSE_TEACHER)
226
                ->setResourceLink($link)
227
            ;
228
            $rights[] = $resourceRight;
229
230
            if (!empty($rights)) {
231
                $link->setResourceRight($rights);
232
            }
233
        } else {
234
            $link->setResourceRight([]);
235
        }
236
        $em->persist($link);
237
        $em->flush();
238
239
        return true;
240
    }
241
242
    /**
243
     * Change all links visibility to DELETED.
244
     *
245
     * @param CDocument $document
246
     */
247
    public function softDelete($document)
248
    {
249
        $this->setLinkVisibility($document, ResourceLink::VISIBILITY_DELETED);
250
    }
251
252
    /**
253
     * @param int $userId
254
     *
255
     * @return array
256
     */
257
    public function getAllDocumentsByAuthor($userId)
258
    {
259
        $repo = $this->repository;
260
261
        $qb = $repo->createQueryBuilder('d');
262
        $query = $qb
263
            ->innerJoin('d.resourceNode', 'r')
264
            ->innerJoin('r.resourceLinks', 'l')
265
            ->where('l.user = :user')
266
            ->andWhere('l.visibility <> :visibility')
267
            ->setParameters([
268
                'user' => $userId,
269
                'visibility' => ResourceLink::VISIBILITY_DELETED,
270
            ])
271
            ->getQuery();
272
273
        return $query->getResult();
274
    }
275
276
    /**
277
     * @param CDocument $document
278
     * @param int       $visibility
279
     * @param bool      $recursive
280
     */
281
    private function setLinkVisibility($document, $visibility, $recursive = true)
282
    {
283
        $resourceNode = $document->getResourceNode();
284
        $children = $resourceNode->getChildren();
285
286
        if ($recursive) {
287
            if (!empty($children)) {
288
                /** @var ResourceNode $child */
289
                foreach ($children as $child) {
290
                    $criteria = ['resourceNode' => $child];
291
                    $childDocument = $this->repository->findOneBy($criteria);
292
                    if ($childDocument) {
293
                        $this->setLinkVisibility($childDocument, $visibility);
294
                    }
295
                }
296
            }
297
        }
298
299
        $links = $resourceNode->getResourceLinks();
300
301
        if (!empty($links)) {
302
            /** @var ResourceLink $link */
303
            foreach ($links as $link) {
304
                $link->setVisibility($visibility);
305
306
                if ($visibility === ResourceLink::VISIBILITY_DRAFT) {
307
                    $editorMask = ResourceNodeVoter::getEditorMask();
308
                    $rights = [];
309
                    $resourceRight = new ResourceRight();
310
                    $resourceRight
311
                        ->setMask($editorMask)
312
                        ->setRole(ResourceNodeVoter::ROLE_CURRENT_COURSE_TEACHER)
313
                        ->setResourceLink($link)
314
                    ;
315
                    $rights[] = $resourceRight;
316
317
                    if (!empty($rights)) {
318
                        $link->setResourceRight($rights);
319
                    }
320
                } else {
321
                    $link->setResourceRight([]);
322
                }
323
                $this->entityManager->merge($link);
324
            }
325
        }
326
327
        $this->entityManager->flush();
328
    }
329
}
330