Passed
Push — master ( 370d09...eec542 )
by Angel Fernando Quiroz
07:54 queued 14s
created

addPersonalCalendarConditions()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 13
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 7
c 1
b 0
f 0
nc 1
nop 2
dl 0
loc 13
rs 10
1
<?php
2
3
/* For licensing terms, see /license.txt */
4
5
declare(strict_types=1);
6
7
namespace Chamilo\CoreBundle\DataProvider\Extension;
8
9
use ApiPlatform\Doctrine\Orm\Extension\QueryCollectionExtensionInterface;
10
use ApiPlatform\Doctrine\Orm\Util\QueryNameGeneratorInterface;
11
use ApiPlatform\Metadata\Operation;
12
use Chamilo\CoreBundle\Entity\AccessUrl;
13
use Chamilo\CoreBundle\Entity\User;
14
use Chamilo\CoreBundle\Entity\Usergroup;
15
use Chamilo\CoreBundle\Repository\Node\CourseRepository;
16
use Chamilo\CoreBundle\Repository\SessionRepository;
17
use Chamilo\CoreBundle\ServiceHelper\AccessUrlHelper;
18
use Chamilo\CoreBundle\ServiceHelper\CidReqHelper;
19
use Chamilo\CoreBundle\ServiceHelper\UserHelper;
20
use Chamilo\CoreBundle\Settings\SettingsManager;
21
use Chamilo\CourseBundle\Entity\CCalendarEvent;
22
use Doctrine\ORM\QueryBuilder;
23
use Symfony\Bundle\SecurityBundle\Security;
24
use UserGroupModel;
25
26
final class CCalendarEventExtension implements QueryCollectionExtensionInterface
27
{
28
    use CourseLinkExtensionTrait;
29
30
    public function __construct(
31
        private readonly Security $security,
32
        private readonly CidReqHelper $cidReqHelper,
33
        private readonly UserHelper $userHelper,
34
        private readonly AccessUrlHelper $accessUrlHelper,
35
        private readonly SettingsManager $settingsManager,
36
        private readonly CourseRepository $courseRepository,
37
        private readonly SessionRepository $sessionRepository,
38
    ) {}
39
40
    public function applyToCollection(
41
        QueryBuilder $queryBuilder,
42
        QueryNameGeneratorInterface $queryNameGenerator,
43
        string $resourceClass,
44
        ?Operation $operation = null,
45
        array $context = []
46
    ): void {
47
        $this->addWhere($queryBuilder, $resourceClass, $context);
48
    }
49
50
    private function addWhere(QueryBuilder $qb, string $resourceClass, array $context): void
51
    {
52
        if (CCalendarEvent::class !== $resourceClass) {
53
            return;
54
        }
55
56
        $isGlobalType = isset($context['filters']['type']) && 'global' === $context['filters']['type'];
57
        if ($isGlobalType) {
58
            return;
59
        }
60
61
        $courseId = $this->cidReqHelper->getCourseId();
62
        $sessionId = $this->cidReqHelper->getSessionId();
63
        $groupId = $this->cidReqHelper->getGroupId();
64
        $user = $this->userHelper->getCurrent();
65
        $accessUrl = $this->accessUrlHelper->getCurrent();
66
67
        $inCourseBase = !empty($courseId);
68
        $inSession = !empty($sessionId);
69
        $inCourseSession = $inCourseBase && $inSession;
70
71
        $inPersonalList = !$inCourseBase && !$inCourseSession;
72
73
        $alias = $qb->getRootAliases()[0];
74
75
        $qb
76
            ->innerJoin("$alias.resourceNode", 'node')
77
            ->leftJoin('node.resourceLinks', 'resource_links')
78
        ;
79
80
        if ($inPersonalList && $user) {
81
            $this->addPersonalCalendarConditions($qb, $user);
82
            $this->addCourseConditions($qb, $user, $accessUrl);
83
            $this->addSessionConditions($qb, $user, $accessUrl);
84
        }
85
    }
86
87
    private function addPersonalCalendarConditions(QueryBuilder $qb, User $user): void
88
    {
89
        $qb
90
            ->andWhere(
91
                $qb->expr()->orX(
92
                    $qb->expr()->eq('resource_links.user', ':user'),
93
                    $qb->expr()->eq('node.creator', ':user')
94
                )
95
            )
96
            ->setParameter('user', $user->getId())
97
        ;
98
99
        $this->addSubscriptionsConditions($qb, $user);
100
    }
101
102
    private function addSubscriptionsConditions(QueryBuilder $qb, User $user): void
103
    {
104
        $groupList = (new UserGroupModel())->getUserGroupListByUser($user->getId(), Usergroup::NORMAL_CLASS);
105
        $groupIdList = $groupList ? array_column($groupList, 'id') : [];
106
107
        $alias = $qb->getRootAliases()[0];
108
109
        $expr = $qb->expr()->orX(
110
            $qb->expr()->eq("$alias.subscriptionVisibility", ':visibility_all'),
111
        );
112
113
        if ($groupIdList) {
114
            $expr->add(
115
                $qb->expr()->orX(
116
                    $qb->expr()->eq("$alias.subscriptionVisibility", ':visibility_class'),
117
                    $qb->expr()->in("$alias.subscriptionItemId", ':item_id_list')
118
                )
119
            );
120
121
            $qb->setParameter('visibility_class', CCalendarEvent::SUBSCRIPTION_VISIBILITY_CLASS);
122
            $qb->setParameter('item_id_list', $groupIdList);
123
        }
124
125
        $qb
126
            ->orWhere($expr)
127
            ->setParameter(':visibility_all', CCalendarEvent::SUBSCRIPTION_VISIBILITY_ALL)
128
        ;
129
    }
130
131
    private function addCourseConditions(QueryBuilder $qb, User $user, AccessUrl $accessUrl): void
132
    {
133
        $courseSubscriptions = $this->courseRepository->getCoursesByUser($user, $accessUrl);
134
135
        $courseIdList = [];
136
137
        foreach ($courseSubscriptions as $courseSubscription) {
138
            $courseIdList[] = $courseSubscription->getCourse()->getId();
139
        }
140
141
        if ($courseIdList) {
142
            $qb
143
                ->orWhere(
144
                    $qb->expr()->andX(
145
                        $qb->expr()->in('resource_links.course', ':course_id_list'),
146
                        $qb->expr()->isNull('resource_links.session')
147
                    )
148
                )
149
                ->setParameter('course_id_list', $courseIdList)
150
            ;
151
        }
152
    }
153
154
    private function addSessionConditions(QueryBuilder $qb, User $user, AccessUrl $accessUrl): void
155
    {
156
        $sessionIdList = [];
157
        $courseIdList = [];
158
159
        if ($user->isHRM()
160
            && 'true' === $this->settingsManager->getSetting('session.drh_can_access_all_session_content')
161
        ) {
162
            $sessions = $this->sessionRepository
163
                ->getUserFollowedSessionsInAccessUrl($user, $accessUrl)
164
                ->getQuery()
165
                ->getResult()
166
            ;
167
168
            foreach ($sessions as $session) {
169
                foreach ($session->getCourses() as $sessionRelCourse) {
170
                    $courseIdList[] = $sessionRelCourse->getCourse()->getId();
171
                }
172
173
                $sessionIdList[] = $session->getId();
174
            }
175
        } else {
176
            $sessions = $this->sessionRepository->getSessionsByUser($user, $accessUrl);
177
178
            foreach ($sessions as $session) {
179
                foreach ($session->getSessionRelCourseByUser($user) as $sessionRelCourse) {
180
                    $courseIdList[] = $sessionRelCourse->getCourse()->getId();
181
                }
182
183
                $sessionIdList[] = $session->getId();
184
            }
185
        }
186
187
        if ($sessionIdList && $courseIdList) {
188
            $qb
189
                ->orWhere(
190
                    $qb->expr()->andX(
191
                        $qb->expr()->in('resource_links.session', ':session_id_list'),
192
                        $qb->expr()->in('resource_links.course', ':course_id_list')
193
                    )
194
                )
195
                ->setParameter('session_id_list', array_unique($sessionIdList))
196
                ->setParameter('course_id_list', $courseIdList)
197
            ;
198
        }
199
    }
200
}
201