Passed
Push — master ( af00ba...368e6c )
by
unknown
10:47
created

CLpRepository::findAllByCourse()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 19
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 3
nc 1
nop 6
dl 0
loc 19
rs 10
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\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 lastProgressForUser(iterable $lps, User $user, ?Session $session): array
144
    {
145
        $lpIds = [];
146
        foreach ($lps as $lp) {
147
            $id = (int) $lp->getIid();
148
            if ($id > 0) { $lpIds[] = $id; }
149
        }
150
        if (!$lpIds) {
151
            return [];
152
        }
153
154
        $em = $this->getEntityManager();
155
        $qb = $em->createQueryBuilder();
156
        $sub = $session
157
            ? 'SELECT MAX(v2.iid) FROM ' . CLpView::class . ' v2
158
                 WHERE v2.user = :user AND v2.session = :session AND v2.lp = v.lp'
159
            : 'SELECT MAX(v2.iid) FROM ' . CLpView::class . ' v2
160
                 WHERE v2.user = :user AND v2.session IS NULL AND v2.lp = v.lp';
161
162
        $qb->select('IDENTITY(v.lp) AS lp_id', 'COALESCE(v.progress, 0) AS progress')
163
            ->from(CLpView::class, 'v')
164
            ->where($qb->expr()->in('v.lp', ':lpIds'))
165
            ->andWhere('v.user = :user')
166
            ->andWhere($session ? 'v.session = :session' : 'v.session IS NULL')
167
            ->andWhere('v.iid = ('.$sub.')')
168
            ->setParameter('lpIds', $lpIds)
169
            ->setParameter('user', $user);
170
171
        if ($session) {
172
            $qb->setParameter('session', $session);
173
        }
174
175
        $rows = $qb->getQuery()->getArrayResult();
176
177
        $map = array_fill_keys($lpIds, 0);
178
        foreach ($rows as $r) {
179
            $map[(int)$r['lp_id']] = (int)$r['progress'];
180
        }
181
182
        return $map;
183
    }
184
185
    public function reorderByIds(int $courseId, ?int $sessionId, array $orderedLpIds, ?int $categoryId = null): void
186
    {
187
        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...
188
189
        $em      = $this->getEntityManager();
190
        $course  = $em->getReference(Course::class, $courseId);
191
        $session = $sessionId ? $em->getReference(Session::class, $sessionId) : null;
192
193
        $qb = $this->createQueryBuilder('lp')
194
            ->addSelect('rn', 'rl')
195
            ->join('lp.resourceNode', 'rn')
196
            ->join('rn.resourceLinks', 'rl')
197
            ->where('lp.iid IN (:ids)')
198
            ->andWhere('rl.course = :course')->setParameter('course', $course)
199
            ->setParameter('ids', $orderedLpIds);
200
201
        if ($session) {
202
            $qb->andWhere('rl.session = :sid')->setParameter('sid', $session);
203
        } else {
204
            $qb->andWhere('rl.session IS NULL');
205
        }
206
207
        if ($categoryId !== null) {
208
            $qb->andWhere('lp.category = :cat')->setParameter('cat', $categoryId);
209
        } else {
210
            $qb->andWhere('lp.category IS NULL');
211
        }
212
213
        /** @var CLp[] $lps */
214
        $lps = $qb->getQuery()->getResult();
215
        $linksByLpId = [];
216
        $positions   = [];
217
        foreach ($lps as $lp) {
218
            $link = $lp->getResourceNode()->getResourceLinkByContext($course, $session);
219
            if (!$link) continue;
220
            $linksByLpId[(int)$lp->getIid()] = $link;
221
            $positions[] = (int)$link->getDisplayOrder();
222
        }
223
        if (!$linksByLpId) return;
224
225
        sort($positions);
226
        $start = $positions[0];
227
228
        $pos = $start;
229
        foreach ($orderedLpIds as $lpId) {
230
            if (!isset($linksByLpId[$lpId])) continue;
231
            $linksByLpId[$lpId]->setDisplayOrder($pos);
232
            $pos++;
233
        }
234
235
        $em->flush();
236
    }
237
}
238