Passed
Push — 1.11.x ( 9ff550...d676dc )
by Julito
14:20
created

checkRequirementsForUser()   D

Complexity

Conditions 18
Paths 64

Size

Total Lines 95
Code Lines 59

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 18
eloc 59
c 1
b 0
f 0
nc 64
nop 4
dl 0
loc 95
rs 4.8666

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
/* For licensing terms, see /license.txt */
4
5
namespace Chamilo\CoreBundle\Entity\Repository;
6
7
use Chamilo\CoreBundle\Entity\Course;
8
use Chamilo\CoreBundle\Entity\SequenceResource;
9
use Chamilo\CoreBundle\Entity\SessionRelUser;
10
use Doctrine\ORM\EntityRepository;
11
use Fhaculty\Graph\Set\Vertices;
12
use Fhaculty\Graph\Vertex;
13
14
/**
15
 * Class SequenceResourceRepository.
16
 */
17
class SequenceResourceRepository extends EntityRepository
18
{
19
    /**
20
     * Find the SequenceResource based in the resourceId and type.
21
     *
22
     * @param int $resourceId
23
     * @param int $type
24
     *
25
     * @return SequenceResource
26
     */
27
    public function findRequirementForResource($resourceId, $type)
28
    {
29
        return $this->findOneBy(['resourceId' => $resourceId, 'type' => $type]);
30
    }
31
32
    /**
33
     * @todo implement for all types only work for sessions
34
     *
35
     * @param int $resourceId
36
     * @param int $type
37
     *
38
     * @return array
39
     */
40
    public function getRequirementAndDependencies($resourceId, $type)
41
    {
42
        $sequence = $this->findRequirementForResource($resourceId, $type);
43
        $result = ['requirements' => [], 'dependencies' => []];
44
        if ($sequence && $sequence->hasGraph()) {
45
            $graph = $sequence->getSequence()->getUnSerializeGraph();
46
            $vertex = $graph->getVertex($resourceId);
47
            $from = $vertex->getVerticesEdgeFrom();
48
49
            foreach ($from as $subVertex) {
50
                $vertexId = $subVertex->getId();
51
                $sessionInfo = api_get_session_info($vertexId);
52
                $sessionInfo['admin_link'] = '<a href="'.\SessionManager::getAdminPath($vertexId).'">'.$sessionInfo['name'].'</a>';
0 ignored issues
show
Bug introduced by
Are you sure SessionManager::getAdminPath($vertexId) of type false|string can be used in concatenation? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

52
                $sessionInfo['admin_link'] = '<a href="'./** @scrutinizer ignore-type */ \SessionManager::getAdminPath($vertexId).'">'.$sessionInfo['name'].'</a>';
Loading history...
53
                $result['requirements'][] = $sessionInfo;
54
            }
55
56
            $to = $vertex->getVerticesEdgeTo();
57
            foreach ($to as $subVertex) {
58
                $vertexId = $subVertex->getId();
59
                $sessionInfo = api_get_session_info($vertexId);
60
                $sessionInfo['admin_link'] = '<a href="'.\SessionManager::getAdminPath($vertexId).'">'.$sessionInfo['name'].'</a>';
61
                $result['dependencies'][] = $sessionInfo;
62
            }
63
        }
64
65
        return $result;
66
    }
67
68
    /**
69
     * Deletes a node and check in all the dependencies if the node exists in
70
     * order to deleted.
71
     *
72
     * @param int $resourceId
73
     * @param int $type
74
     */
75
    public function deleteResource($resourceId, $type)
76
    {
77
        $sequence = $this->findRequirementForResource($resourceId, $type);
78
        if ($sequence && $sequence->hasGraph()) {
79
            $em = $this->getEntityManager();
80
            $graph = $sequence->getSequence()->getUnSerializeGraph();
81
            $mainVertex = $graph->getVertex($resourceId);
82
            $vertices = $graph->getVertices();
83
84
            /** @var Vertex $vertex */
85
            foreach ($vertices as $vertex) {
86
                $subResourceId = $vertex->getId();
87
                $subSequence = $this->findRequirementForResource($subResourceId, $type);
88
                if ($sequence && $subSequence->hasGraph()) {
89
                    $graph = $subSequence->getSequence()->getUnSerializeGraph();
90
                    $subMainVertex = $graph->getVertex($resourceId);
91
                    $subMainVertex->destroy();
92
                    $subSequence->getSequence()->setGraphAndSerialize($graph);
93
                    $em->persist($subSequence);
94
                }
95
            }
96
97
            $mainVertex->destroy();
98
            $em->remove($sequence);
99
            $em->flush();
100
        }
101
    }
102
103
    /**
104
     * Get the requirements for a resource only.
105
     *
106
     * @param int $resourceId The resource ID
107
     * @param int $type       The type of sequence resource
108
     *
109
     * @return array
110
     */
111
    public function getRequirements($resourceId, $type)
112
    {
113
        $sequencesResource = $this->findBy(['resourceId' => $resourceId, 'type' => $type]);
114
        $em = $this->getEntityManager();
115
        $result = [];
116
        /** @var SequenceResource $sequenceResource */
117
        foreach ($sequencesResource as $sequenceResource) {
118
            if (!$sequenceResource->hasGraph()) {
119
                continue;
120
            }
121
122
            $sequence = $sequenceResource->getSequence();
123
            $graph = $sequence->getUnSerializeGraph();
124
            $vertex = $graph->getVertex($resourceId);
125
            $from = $vertex->getVerticesEdgeFrom();
126
127
            $sequenceInfo = [
128
                'name' => $sequence->getName(),
129
                'requirements' => [],
130
            ];
131
132
            foreach ($from as $subVertex) {
133
                $vertexId = $subVertex->getId();
134
                $resource = null;
135
                switch ($type) {
136
                    case SequenceResource::SESSION_TYPE:
137
                        $repo = $em->getRepository('ChamiloCoreBundle:Session');
138
                        $resource = $repo->find($vertexId);
139
140
                        break;
141
                    case SequenceResource::COURSE_TYPE:
142
                        $repo = $em->getRepository('ChamiloCoreBundle:Course');
143
                        $resource = $repo->find($vertexId);
144
145
                        break;
146
                }
147
148
                if (null === $resource) {
149
                    continue;
150
                }
151
152
                $sequenceInfo['requirements'][$vertexId] = $resource;
153
            }
154
155
            $result[$sequence->getId()] = $sequenceInfo;
156
        }
157
158
        return $result;
159
    }
160
161
    /**
162
     * Get the requirements and dependencies within a sequence for a resource.
163
     *
164
     * @param int $resourceId The resource ID
165
     * @param int $type       The type of sequence resource
166
     *
167
     * @return array
168
     */
169
    public function getRequirementsAndDependenciesWithinSequences($resourceId, $type)
170
    {
171
        $sequencesResource = $this->findBy([
172
            'resourceId' => $resourceId,
173
            'type' => $type,
174
        ]);
175
176
        $result = [];
177
178
        /** @var SequenceResource $sequenceResource */
179
        foreach ($sequencesResource as $sequenceResource) {
180
            if (!$sequenceResource->hasGraph()) {
181
                continue;
182
            }
183
184
            $sequence = $sequenceResource->getSequence();
185
            $graph = $sequence->getUnSerializeGraph();
186
            $vertex = $graph->getVertex($resourceId);
187
            $from = $vertex->getVerticesEdgeFrom();
188
            $to = $vertex->getVerticesEdgeTo();
189
190
            $requirements = $this->findVerticesEdges($from, $type);
191
            $dependencies = $this->findVerticesEdges($to, $type);
192
193
            $result[$sequence->getId()] = [
194
                'name' => $sequence->getName(),
195
                'requirements' => $requirements,
196
                'dependencies' => $dependencies,
197
            ];
198
        }
199
200
        return $result;
201
    }
202
203
    /**
204
     * Check if the ser has completed the requirements for the sequences.
205
     *
206
     * @param array $sequences The sequences
207
     * @param int   $type      The type of sequence resource
208
     * @param int   $userId
209
     * @param int   $sessionId
210
     *
211
     * @return array
212
     */
213
    public function checkRequirementsForUser(array $sequences, $type, $userId, $sessionId = 0)
214
    {
215
        $sequenceList = [];
216
        $em = $this->getEntityManager();
217
        $gradebookCategoryRepo = $em->getRepository('ChamiloCoreBundle:GradebookCategory');
218
219
        $sessionUserList = [];
220
        if (SequenceResource::COURSE_TYPE == $type) {
221
            $checkOnlySameSession = api_get_configuration_value('course_sequence_valid_only_in_same_session');
222
            if ($checkOnlySameSession) {
223
                $sessionUserList = [$sessionId];
224
            } else {
225
                $criteria = ['user' => $userId];
226
                $sessions = $em->getRepository('ChamiloCoreBundle:SessionRelUser')->findBy($criteria);
227
                if ($sessions) {
228
                    /** @var SessionRelUser $sessionRelUser */
229
                    foreach ($sessions as $sessionRelUser) {
230
                        $sessionUserList[] = $sessionRelUser->getSession()->getId();
231
                    }
232
                }
233
            }
234
        }
235
236
        foreach ($sequences as $sequenceId => $sequence) {
237
            $item = [
238
                'name' => $sequence['name'],
239
                'requirements' => [],
240
            ];
241
            $resourceItem = null;
242
243
            foreach ($sequence['requirements'] as $resource) {
244
                switch ($type) {
245
                    case SequenceResource::SESSION_TYPE:
246
                        $id = $resource->getId();
247
                        $resourceItem = [
248
                            'name' => $resource->getName(),
249
                            'status' => true,
250
                        ];
251
252
                        $sessionsCourses = $resource->getCourses();
253
                        foreach ($sessionsCourses as $sessionCourse) {
254
                            $course = $sessionCourse->getCourse();
255
                            $gradebooks = $gradebookCategoryRepo->findBy(
256
                                [
257
                                    'courseCode' => $course->getCode(),
258
                                    'sessionId' => $resource->getId(),
259
                                    'isRequirement' => true,
260
                                ]
261
                            );
262
263
                            foreach ($gradebooks as $gradebook) {
264
                                $category = \Category::createCategoryObjectFromEntity($gradebook);
265
                                if (!empty($userId)) {
266
                                    $resourceItem['status'] = $resourceItem['status'] && \Category::userFinishedCourse(
267
                                        $userId,
268
                                        $category
269
                                    );
270
                                }
271
                            }
272
                        }
273
                        break;
274
                    case SequenceResource::COURSE_TYPE:
275
                        $id = $resource->getId();
276
                        $status = $this->checkCourseRequirements($userId, $resource, 0);
277
278
                        if (false === $status) {
279
                            $sessionsInCourse = \SessionManager::get_session_by_course($id);
280
                            foreach ($sessionsInCourse as $session) {
281
                                if (in_array($session['id'], $sessionUserList)) {
282
                                    $status = $this->checkCourseRequirements($userId, $resource, $session['id']);
283
                                    if (true === $status) {
284
                                        break;
285
                                    }
286
                                }
287
                            }
288
                        }
289
290
                        $resourceItem = [
291
                            'name' => $resource->getTitle(),
292
                            'status' => $status,
293
                        ];
294
295
                        break;
296
                }
297
298
                if (empty($id)) {
299
                    continue;
300
                }
301
302
                $item['requirements'][$id] = $resourceItem;
303
            }
304
            $sequenceList[$sequenceId] = $item;
305
        }
306
307
        return $sequenceList;
308
    }
309
310
    public function checkCourseRequirements($userId, Course $course, $sessionId)
311
    {
312
        $em = $this->getEntityManager();
313
        $sessionId = (int) $sessionId;
314
315
        $gradebookCategoryRepo = $em->getRepository('ChamiloCoreBundle:GradebookCategory');
316
        $gradebooks = $gradebookCategoryRepo->findBy(
317
            [
318
                'courseCode' => $course->getCode(),
319
                'sessionId' => $sessionId,
320
                'isRequirement' => true,
321
            ]
322
        );
323
324
        if (empty($gradebooks)) {
325
            return false;
326
        }
327
328
        $status = true;
329
        foreach ($gradebooks as $gradebook) {
330
            $category = \Category::createCategoryObjectFromEntity($gradebook);
331
            $userFinishedCourse = \Category::userFinishedCourse(
332
                $userId,
333
                $category,
334
                true
335
            );
336
            if (0 === $sessionId) {
337
                if (false === $userFinishedCourse) {
338
                    $status = false;
339
                    break;
340
                }
341
            } else {
342
                if (false === $userFinishedCourse) {
343
                    $status = false;
344
                    break;
345
                }
346
            }
347
        }
348
349
        return $status;
350
    }
351
352
    /**
353
     * Check if at least one sequence are completed.
354
     *
355
     * @param array $sequences The sequences
356
     *
357
     * @return bool
358
     */
359
    public function checkSequenceAreCompleted(array $sequences)
360
    {
361
        foreach ($sequences as $sequence) {
362
            $status = true;
363
364
            foreach ($sequence['requirements'] as $item) {
365
                $status = $status && $item['status'];
366
            }
367
368
            if ($status) {
369
                return true;
370
            }
371
        }
372
373
        return false;
374
    }
375
376
    /**
377
     * Get sessions from vertices.
378
     *
379
     * @param Vertices $verticesEdges The vertices
380
     * @param int      $type
381
     *
382
     * @return array
383
     */
384
    protected function findVerticesEdges(Vertices $verticesEdges, $type)
385
    {
386
        $sessionVertices = [];
387
        $em = $this->getEntityManager();
388
389
        foreach ($verticesEdges as $supVertex) {
390
            $vertexId = $supVertex->getId();
391
            switch ($type) {
392
                case SequenceResource::SESSION_TYPE:
393
                    $resource = $em->getRepository('ChamiloCoreBundle:Session')->find($vertexId);
394
                    break;
395
                case SequenceResource::COURSE_TYPE:
396
                    $resource = $em->getRepository('ChamiloCoreBundle:Course')->find($vertexId);
397
                    break;
398
            }
399
400
            if (empty($resource)) {
401
                continue;
402
            }
403
404
            $sessionVertices[$vertexId] = $resource;
405
        }
406
407
        return $sessionVertices;
408
    }
409
}
410