Completed
Push — master ( bb9871...4572bc )
by Julito
11:01 queued 10s
created

CDocumentRepository::updateDocumentContent()   A

Complexity

Conditions 2
Paths 8

Size

Total Lines 16
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

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