Passed
Pull Request — master (#6357)
by Angel Fernando Quiroz
07:55
created

findIncompleteCertificates()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 36
Code Lines 29

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 29
nc 1
nop 1
dl 0
loc 36
rs 9.456
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
/* For licensing terms, see /license.txt */
6
7
namespace Chamilo\CoreBundle\Repository;
8
9
use Chamilo\CoreBundle\Entity\GradebookCategory;
10
use Chamilo\CoreBundle\Entity\GradebookCertificate;
11
use Chamilo\CoreBundle\Entity\PersonalFile;
12
use Chamilo\CoreBundle\Entity\SessionRelCourseRelUser;
13
use Chamilo\CoreBundle\Entity\SessionRelUser;
14
use Chamilo\CoreBundle\Entity\User;
15
use DateTime;
16
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
17
use Doctrine\ORM\AbstractQuery;
18
use Doctrine\ORM\NonUniqueResultException;
19
use Doctrine\Persistence\ManagerRegistry;
20
use Symfony\Component\HttpFoundation\File\UploadedFile;
21
22
class GradebookCertificateRepository extends ServiceEntityRepository
23
{
24
    public function __construct(ManagerRegistry $registry)
25
    {
26
        parent::__construct($registry, GradebookCertificate::class);
27
    }
28
29
    public function getCertificateByUserId(?int $catId, int $userId, bool $asArray = false)
30
    {
31
        $qb = $this->createQueryBuilder('gc')
32
            ->where('gc.user = :userId')
33
            ->setParameter('userId', $userId)
34
            ->setMaxResults(1)
35
        ;
36
37
        if (0 === $catId) {
38
            $catId = null;
39
        }
40
41
        if (null === $catId) {
42
            $qb->andWhere('gc.category IS NULL');
43
        } else {
44
            $qb->andWhere('gc.category = :catId')
45
                ->setParameter('catId', $catId)
46
            ;
47
        }
48
49
        $qb->orderBy('gc.id', 'ASC');
50
51
        $query = $qb->getQuery();
52
53
        if ($asArray) {
54
            try {
55
                return $query->getOneOrNullResult(AbstractQuery::HYDRATE_ARRAY);
56
            } catch (NonUniqueResultException $e) {
57
                return null;
58
            }
59
        } else {
60
            try {
61
                return $query->getOneOrNullResult();
62
            } catch (NonUniqueResultException $e) {
63
                return null;
64
            }
65
        }
66
    }
67
68
    public function registerUserInfoAboutCertificate(int $catId, int $userId, float $scoreCertificate, string $fileName = ''): void
69
    {
70
        $existingCertificate = $this->getCertificateByUserId(0 === $catId ? null : $catId, $userId);
71
72
        if (!$existingCertificate) {
73
            $certificate = new GradebookCertificate();
74
75
            $category = 0 === $catId ? null : $this->_em->getRepository(GradebookCategory::class)->find($catId);
76
            $user = $this->_em->getRepository(User::class)->find($userId);
77
78
            if (!empty($fileName)) {
79
                $fileName = '/'.$fileName;
80
            }
81
82
            if ($category) {
83
                $certificate->setCategory($category);
84
            }
85
            $certificate->setUser($user);
86
            $certificate->setPathCertificate($fileName);
87
            $certificate->setScoreCertificate($scoreCertificate);
88
            $certificate->setCreatedAt(new DateTime());
89
90
            $this->_em->persist($certificate);
91
            $this->_em->flush();
92
        }
93
    }
94
95
    public function generateCertificatePersonalFile(int $userId, string $fileName, string $certificateContent): ?PersonalFile
96
    {
97
        $em = $this->getEntityManager();
98
        $userEntity = $em->getRepository(User::class)->find($userId);
99
100
        $existingFile = $em->getRepository(PersonalFile::class)->findOneBy(['title' => $fileName]);
101
102
        if (!$existingFile) {
103
            $tempFilePath = tempnam(sys_get_temp_dir(), 'cert');
104
            file_put_contents($tempFilePath, $certificateContent);
105
106
            $mimeType = mime_content_type($tempFilePath);
107
            $uploadedFile = new UploadedFile($tempFilePath, $fileName, $mimeType, null, true);
108
109
            $personalFile = new PersonalFile();
110
            $personalFile->setTitle($fileName);
111
            $personalFile->setCreator($userEntity);
112
            $personalFile->setParentResourceNode($userEntity->getResourceNode()->getId());
113
            $personalFile->setResourceName($fileName);
114
            $personalFile->setUploadFile($uploadedFile);
115
            $personalFile->addUserLink($userEntity);
116
117
            $em->persist($personalFile);
118
            $em->flush();
119
120
            unlink($tempFilePath);
121
122
            return $personalFile;
123
        }
124
125
        return $existingFile;
126
    }
127
128
    public function deleteCertificateAndRelatedFiles(int $userId, int $catId): bool
129
    {
130
        $em = $this->getEntityManager();
131
        $certificate = $this->getCertificateByUserId($catId, $userId);
132
133
        if (!$certificate) {
134
            return false;
135
        }
136
137
        $title = basename(ltrim($certificate->getPathCertificate(), '/'));
138
        $personalFile = $em->getRepository(PersonalFile::class)->findOneBy(['title' => $title]);
139
140
        if (!$personalFile) {
141
            return false;
142
        }
143
144
        $em->remove($personalFile);
145
        $em->flush();
146
147
        $em->remove($certificate);
148
        $em->flush();
149
150
        return true;
151
    }
152
153
    public function findCertificatesWithContext(
154
        int $urlId,
155
        int $offset = 0,
156
        int $limit  = 50
157
    ): array {
158
        return $this->createQueryBuilder('gc')
159
            ->join('gc.category',   'cat')
160
            ->join('cat.course',    'course')
161
            ->join('course.urls',   'curl')
162
            ->join('curl.url',      'url')
163
            ->leftJoin('course.sessions', 'src')
164
            ->leftJoin('src.session',     'session')
165
            ->where('url.id = :urlId')
166
            ->setParameter('urlId', $urlId)
167
            ->orderBy('gc.createdAt', 'DESC')
168
            ->setFirstResult($offset)
169
            ->setMaxResults($limit)
170
            ->getQuery()
171
            ->getResult();
172
    }
173
174
    public function findIncompleteCertificates(int $urlId): array
175
    {
176
        $today = new \DateTimeImmutable();
177
        $em = $this->getEntityManager();
178
        $qb = $em->createQueryBuilder();
179
180
        $qb->select('sru', 'u', 's', 'src', 'c')
181
        ->from(SessionRelUser::class, 'sru')
182
            ->join('sru.user',    'u')
183
            ->join('sru.session', 's')
184
            ->join('s.courses',   'src')
185
            ->join('src.course',  'c')
186
            ->join('c.urls',      'curl')
187
            ->join('curl.url',    'url')
188
            ->where('url.id = :urlId')
189
            ->andWhere('s.accessStartDate <= :today')
190
            ->andWhere('s.accessEndDate   IS NULL OR s.accessEndDate > :today')
191
            ->andWhere(
192
                $qb->expr()->not(
193
                    $qb->expr()->exists(
194
                        $em->createQueryBuilder()
195
                            ->select('gc2.id')
196
                            ->from(GradebookCertificate::class, 'gc2')
197
                            ->join('gc2.category', 'cat2')
198
                            ->join('cat2.course',  'cc')
199
                            ->where('gc2.user = u')
200
                            ->andWhere('cc = c')
201
                            ->getDQL()
202
                    )
203
                )
204
            )
205
            ->setParameter('urlId', $urlId)
206
            ->setParameter('today', $today)
207
            ->orderBy('s.accessStartDate', 'DESC');
208
209
        return $qb->getQuery()->getResult();
210
    }
211
212
    public function findRestartableSessions(
213
        int $urlId,
214
        int $offset = 0,
215
        int $limit  = 10
216
    ): array {
217
        $today = new \DateTimeImmutable();
218
219
        $qb = $this->_em->createQueryBuilder();
220
221
        $qb->select('srcu')
222
            ->from(SessionRelCourseRelUser::class, 'srcu')
223
            ->join('srcu.session', 's')
224
            ->join('srcu.course',  'c')
225
            ->join('c.urls',       'curl')
226
            ->join('curl.url',     'url')
227
            ->where('url.id = :urlId')
228
            ->andWhere('s.accessEndDate IS NOT NULL')
229
            ->andWhere('s.accessEndDate < :today')
230
            ->andWhere(
231
                $qb->expr()->not(
232
                    $qb->expr()->exists(
233
                        $this->_em->createQueryBuilder()
234
                            ->select('gc2.id')
235
                            ->from(GradebookCertificate::class, 'gc2')
236
                            ->join('gc2.category', 'cat2')
237
                            ->join('cat2.course',  'cc')
238
                            ->where('gc2.user = srcu.user')
239
                            ->andWhere('cc = c')
240
                            ->getDQL()
241
                    )
242
                )
243
            )
244
            ->orderBy('s.accessEndDate', 'DESC')
245
            ->setFirstResult($offset)
246
            ->setMaxResults($limit)
247
            ->setParameter('urlId', $urlId)
248
            ->setParameter('today', $today);
249
250
        return $qb->getQuery()->getResult();
251
    }
252
}
253