Passed
Pull Request — master (#6536)
by Yannick
11:20
created

CLpRepository::findScormByCourse()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 13
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 10
c 1
b 0
f 0
nc 1
nop 1
dl 0
loc 13
rs 9.9332
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\Entity\User;
13
use Chamilo\CoreBundle\Repository\ResourceRepository;
14
use Chamilo\CoreBundle\Repository\ResourceWithLinkInterface;
15
use Chamilo\CourseBundle\Entity\CForum;
16
use Chamilo\CourseBundle\Entity\CLp;
17
use Chamilo\CourseBundle\Entity\CLpItem;
18
use Chamilo\CourseBundle\Entity\CLpView;
19
use Doctrine\ORM\QueryBuilder;
20
use Doctrine\Persistence\ManagerRegistry;
21
use Exception;
22
use Symfony\Component\Routing\RouterInterface;
23
24
final class CLpRepository extends ResourceRepository implements ResourceWithLinkInterface
25
{
26
    public function __construct(ManagerRegistry $registry)
27
    {
28
        parent::__construct($registry, CLp::class);
29
    }
30
31
    public function createLp(CLp $lp): void
32
    {
33
        if (null !== $lp->getResourceNode()) {
34
            throw new Exception('Lp should not have a resource node during creation');
35
        }
36
37
        $lpItem = (new CLpItem())
38
            ->setTitle('root')
39
            ->setPath('root')
40
            ->setLp($lp)
41
            ->setItemType('root')
42
        ;
43
        $lp->getItems()->add($lpItem);
44
        $this->create($lp);
45
    }
46
47
    public function findForumByCourse(CLp $lp, Course $course, ?Session $session = null): ?CForum
48
    {
49
        $forums = $lp->getForums();
50
        $result = null;
51
        foreach ($forums as $forum) {
52
            $links = $forum->getResourceNode()->getResourceLinks();
53
            foreach ($links as $link) {
54
                if ($link->getCourse() === $course && $link->getSession() === $session) {
55
                    $result = $forum;
56
57
                    break 2;
58
                }
59
            }
60
        }
61
62
        return $result;
63
    }
64
65
    public function findAllByCourse(
66
        Course $course,
67
        ?Session $session = null,
68
        ?string $title = null,
69
        ?int $active = null,
70
        bool $onlyPublished = true,
71
        ?int $categoryId = null
72
    ): QueryBuilder {
73
        $qb = $this->getResourcesByCourse($course, $session, null, null, true, true);
74
75
        /*if ($onlyPublished) {
76
            $this->addDateFilterQueryBuilder(new DateTime(), $qb);
77
        }*/
78
        // $this->addCategoryQueryBuilder($categoryId, $qb);
79
        // $this->addActiveQueryBuilder($active, $qb);
80
        // $this->addNotDeletedQueryBuilder($qb);
81
        $this->addTitleQueryBuilder($title, $qb);
82
83
        return $qb;
84
    }
85
86
    public function getLink(ResourceInterface $resource, RouterInterface $router, array $extraParams = []): string
87
    {
88
        $params = [
89
            'lp_id' => $resource->getResourceIdentifier(),
90
            'name' => 'lp/lp_controller.php',
91
            'action' => 'view',
92
        ];
93
        if (!empty($extraParams)) {
94
            $params = array_merge($params, $extraParams);
95
        }
96
97
        return $router->generate('legacy_main', $params);
98
    }
99
100
    public function findAutoLaunchableLPByCourseAndSession(Course $course, ?Session $session = null): ?int
101
    {
102
        $qb = $this->getResourcesByCourse($course, $session)
103
            ->select('resource.iid')
104
            ->andWhere('resource.autolaunch = 1')
105
        ;
106
107
        $qb->setMaxResults(1);
108
109
        $result = $qb->getQuery()->getOneOrNullResult();
110
111
        return $result ? $result['iid'] : null;
112
    }
113
114
    protected function addNotDeletedQueryBuilder(?QueryBuilder $qb = null): QueryBuilder
115
    {
116
        $qb = $this->getOrCreateQueryBuilder($qb);
117
118
        $qb->andWhere('resource.active <> -1');
119
120
        return $qb;
121
    }
122
123
    public function getLpSessionId(int $lpId): ?int
124
    {
125
        $lp = $this->find($lpId);
126
127
        if (!$lp) {
128
            return null;
129
        }
130
131
        $resourceNode = $lp->getResourceNode();
132
        if ($resourceNode) {
133
            $link = $resourceNode->getResourceLinks()->first();
134
135
            if ($link && $link->getSession()) {
136
                return (int) $link->getSession()->getId();
137
            }
138
        }
139
140
        return null;
141
    }
142
143
    public function findScormByCourse(Course $course): array
144
    {
145
        return $this->createQueryBuilder('lp')
146
            ->innerJoin('lp.resourceNode', 'rn')
147
            ->innerJoin('rn.resourceLinks', 'rl')
148
            ->andWhere('rl.course = :course')
149
            ->andWhere('lp.lpType = :scormType')
150
            ->setParameters([
151
                'course'    => $course,
152
                'scormType' => CLp::SCORM_TYPE
153
            ])
154
            ->getQuery()
155
            ->getResult();
156
    }
157
158
    public function lastProgressForUser(iterable $lps, User $user, ?Session $session): array
159
    {
160
        $lpIds = [];
161
        foreach ($lps as $lp) {
162
            $id = (int) $lp->getIid();
163
            if ($id > 0) { $lpIds[] = $id; }
164
        }
165
        if (!$lpIds) {
166
            return [];
167
        }
168
169
        $em = $this->getEntityManager();
170
        $qb = $em->createQueryBuilder();
171
        $sub = $session
172
            ? 'SELECT MAX(v2.iid) FROM ' . CLpView::class . ' v2
173
                 WHERE v2.user = :user AND v2.session = :session AND v2.lp = v.lp'
174
            : 'SELECT MAX(v2.iid) FROM ' . CLpView::class . ' v2
175
                 WHERE v2.user = :user AND v2.session IS NULL AND v2.lp = v.lp';
176
177
        $qb->select('IDENTITY(v.lp) AS lp_id', 'COALESCE(v.progress, 0) AS progress')
178
            ->from(CLpView::class, 'v')
179
            ->where($qb->expr()->in('v.lp', ':lpIds'))
180
            ->andWhere('v.user = :user')
181
            ->andWhere($session ? 'v.session = :session' : 'v.session IS NULL')
182
            ->andWhere('v.iid = ('.$sub.')')
183
            ->setParameter('lpIds', $lpIds)
184
            ->setParameter('user', $user);
185
186
        if ($session) {
187
            $qb->setParameter('session', $session);
188
        }
189
190
        $rows = $qb->getQuery()->getArrayResult();
191
192
        $map = array_fill_keys($lpIds, 0);
193
        foreach ($rows as $r) {
194
            $map[(int)$r['lp_id']] = (int)$r['progress'];
195
        }
196
197
        return $map;
198
    }
199
200
    public function reorderByIds(int $courseId, ?int $sessionId, array $orderedLpIds, ?int $categoryId = null): void
201
    {
202
        if (!$orderedLpIds) return;
0 ignored issues
show
Bug Best Practice introduced by
The expression $orderedLpIds of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
203
204
        $em      = $this->getEntityManager();
205
        $course  = $em->getReference(Course::class, $courseId);
206
        $session = $sessionId ? $em->getReference(Session::class, $sessionId) : null;
207
208
        $qb = $this->createQueryBuilder('lp')
209
            ->addSelect('rn', 'rl')
210
            ->join('lp.resourceNode', 'rn')
211
            ->join('rn.resourceLinks', 'rl')
212
            ->where('lp.iid IN (:ids)')
213
            ->andWhere('rl.course = :course')->setParameter('course', $course)
214
            ->setParameter('ids', $orderedLpIds);
215
216
        if ($session) {
217
            $qb->andWhere('rl.session = :sid')->setParameter('sid', $session);
218
        } else {
219
            $qb->andWhere('rl.session IS NULL');
220
        }
221
222
        if ($categoryId !== null) {
223
            $qb->andWhere('lp.category = :cat')->setParameter('cat', $categoryId);
224
        } else {
225
            $qb->andWhere('lp.category IS NULL');
226
        }
227
228
        /** @var CLp[] $lps */
229
        $lps = $qb->getQuery()->getResult();
230
        $linksByLpId = [];
231
        $positions   = [];
232
        foreach ($lps as $lp) {
233
            $link = $lp->getResourceNode()->getResourceLinkByContext($course, $session);
234
            if (!$link) continue;
235
            $linksByLpId[(int)$lp->getIid()] = $link;
236
            $positions[] = (int)$link->getDisplayOrder();
237
        }
238
        if (!$linksByLpId) return;
239
240
        sort($positions);
241
        $start = $positions[0];
242
243
        $pos = $start;
244
        foreach ($orderedLpIds as $lpId) {
245
            if (!isset($linksByLpId[$lpId])) continue;
246
            $linksByLpId[$lpId]->setDisplayOrder($pos);
247
            $pos++;
248
        }
249
250
        $em->flush();
251
    }
252
}
253