Passed
Pull Request — master (#6266)
by
unknown
08:07
created

CQuizRepository::addActiveQueryBuilder()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 18
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 10
nc 3
nop 2
dl 0
loc 18
rs 9.9332
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\CourseBundle\Repository;
8
9
use Chamilo\CoreBundle\Entity\Course;
10
use Chamilo\CoreBundle\Entity\ResourceInterface;
11
use Chamilo\CoreBundle\Entity\Session;
12
use Chamilo\CoreBundle\Repository\ResourceRepository;
13
use Chamilo\CoreBundle\Repository\ResourceWithLinkInterface;
14
use Chamilo\CourseBundle\Entity\CQuiz;
15
use DateTime;
16
use Doctrine\ORM\QueryBuilder;
17
use Doctrine\Persistence\ManagerRegistry;
18
use Symfony\Component\Routing\RouterInterface;
19
20
final class CQuizRepository extends ResourceRepository implements ResourceWithLinkInterface
21
{
22
    public function __construct(ManagerRegistry $registry)
23
    {
24
        parent::__construct($registry, CQuiz::class);
25
    }
26
27
    public function findAllByCourse(
28
        Course $course,
29
        ?Session $session = null,
30
        ?string $title = null,
31
        ?int $active = null,
32
        bool $onlyPublished = true,
33
        ?int $categoryId = null
34
    ): QueryBuilder {
35
        $qb = $this->getResourcesByCourse($course, $session);
36
37
        if ($onlyPublished) {
38
            $this->addDateFilterQueryBuilder(new DateTime(), $qb);
39
        }
40
        $this->addCategoryQueryBuilder($categoryId, $qb);
41
        $this->addActiveQueryBuilder($active, $qb);
42
        $this->addNotDeletedQueryBuilder($qb);
43
        if (!empty($title)) {
44
            $this->addTitleQueryBuilder($title, $qb);
45
        }
46
47
        return $qb;
48
    }
49
50
    public function getLink(ResourceInterface $resource, RouterInterface $router, array $extraParams = []): string
51
    {
52
        $params = [
53
            'name' => 'exercise/overview.php',
54
            'exerciseId' => $resource->getResourceIdentifier(),
55
        ];
56
        if (!empty($extraParams)) {
57
            $params = array_merge($params, $extraParams);
58
        }
59
60
        return $router->generate('legacy_main', $params);
61
    }
62
63
    private function addDateFilterQueryBuilder(DateTime $dateTime, ?QueryBuilder $qb = null): QueryBuilder
64
    {
65
        $qb = $this->getOrCreateQueryBuilder($qb);
66
        $qb
67
            ->andWhere('(
68
                (
69
                    resource.startTime IS NOT NULL AND
70
                    resource.startTime < :date AND
71
                    resource.endTime IS NOT NULL AND
72
                    resource.endTime > :date
73
                )  OR
74
                (resource.startTime IS NOT NULL AND resource.startTime < :date AND resource.endTime IS NULL) OR
75
                (resource.startTime IS NULL AND resource.endTime IS NOT NULL AND resource.endTime > :date) OR
76
                (resource.startTime IS NULL AND resource.endTime IS NULL)
77
                )
78
            ')
79
            ->setParameter('date', $dateTime)
80
        ;
81
82
        return $qb;
83
    }
84
85
    private function addNotDeletedQueryBuilder(?QueryBuilder $qb = null): QueryBuilder
86
    {
87
        $qb = $this->getOrCreateQueryBuilder($qb);
88
89
        $qb->andWhere('resource.active <> -1');
90
91
        return $qb;
92
    }
93
94
    private function addCategoryQueryBuilder(?int $categoryId = null, ?QueryBuilder $qb = null): QueryBuilder
95
    {
96
        $qb = $this->getOrCreateQueryBuilder($qb);
97
98
        if (null !== $categoryId) {
99
            $qb
100
                ->andWhere('resource.quizCategory = :category_id')
101
                ->setParameter('category_id', $categoryId)
102
            ;
103
        }
104
105
        return $qb;
106
    }
107
108
    /**
109
     * Adds resource.active filter.
110
     *
111
     * The active parameter can be one of the following values.
112
     *
113
     * - null = no filter
114
     * - -1 = deleted exercises
115
     * - 0 = inactive exercises
116
     * - 1 = active exercises
117
     * - 2 = all exercises (active and inactive)
118
     */
119
    private function addActiveQueryBuilder(?int $active = null, ?QueryBuilder $qb = null): QueryBuilder
120
    {
121
        $qb = $this->getOrCreateQueryBuilder($qb);
122
123
        if (null !== $active) {
124
            if (2 === $active) {
125
                $qb
126
                    ->andWhere('resource.active = 1 OR resource.active = 0')
127
                ;
128
            } else {
129
                $qb
130
                    ->andWhere('resource.active = :active')
131
                    ->setParameter('active', $active)
132
                ;
133
            }
134
        }
135
136
        return $qb;
137
    }
138
139
    /**
140
     * Finds the auto-launchable quiz for the given course and session.
141
     */
142
    public function findAutoLaunchableQuizByCourseAndSession(Course $course, ?Session $session = null): ?int
143
    {
144
        $qb = $this->getResourcesByCourse($course, $session)
145
            ->select('resource.iid')
146
            ->andWhere('resource.autoLaunch = 1')
147
        ;
148
149
        $qb->setMaxResults(1);
150
151
        $result = $qb->getQuery()->getOneOrNullResult();
152
153
        return $result ? $result['iid'] : null;
154
    }
155
156
    /**
157
     * Finds quizzes that are using a given question, optionally excluding one quiz.
158
     */
159
    public function findQuizzesUsingQuestion(int $questionId, int $excludeQuizId = 0): array
160
    {
161
        $qb = $this->getEntityManager()->createQueryBuilder();
162
163
        $qb->select('quiz', 'rn', 'rl', 'course', 'session')
164
        ->from(CQuiz::class, 'quiz')
165
            ->innerJoin('quiz.questions', 'rel')
166
            ->innerJoin('quiz.resourceNode', 'rn')
167
            ->leftJoin('rn.resourceLinks', 'rl')
168
            ->leftJoin('rl.course', 'course')
169
            ->leftJoin('rl.session', 'session')
170
            ->where('rel.question = :questionId')
171
            ->setParameter('questionId', $questionId)
172
            ->groupBy('quiz.iid');
173
174
        if ($excludeQuizId > 0) {
175
            $qb->andWhere('quiz.iid != :excludeQuizId')
176
                ->setParameter('excludeQuizId', $excludeQuizId);
177
        }
178
179
        return $qb->getQuery()->getResult();
180
    }
181
}
182