Passed
Push — 1.11.x ( a83aa6...c231b6 )
by Julito
14:28
created

SequenceResourceRepository::deleteResource()   A

Complexity

Conditions 6
Paths 4

Size

Total Lines 25
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 6
eloc 18
nc 4
nop 2
dl 0
loc 25
rs 9.0444
c 1
b 0
f 0
1
<?php
2
/* For licensing terms, see /license.txt */
3
4
namespace Chamilo\CoreBundle\Entity\Repository;
5
6
use Chamilo\CoreBundle\Entity\Course;
7
use Chamilo\CoreBundle\Entity\SequenceResource;
8
use Doctrine\ORM\EntityRepository;
9
use Fhaculty\Graph\Set\Vertices;
10
use Fhaculty\Graph\Vertex;
11
12
/**
13
 * Class SequenceResourceRepository
14
 */
15
class SequenceResourceRepository extends EntityRepository
16
{
17
    /**
18
     * Find the SequenceResource based in the resourceId and type.
19
     *
20
     * @param int $resourceId
21
     * @param int $type
22
     *
23
     * @return SequenceResource
24
     */
25
    public function findRequirementForResource($resourceId, $type)
26
    {
27
        return $this->findOneBy(['resourceId' => $resourceId, 'type' => $type]);
28
    }
29
30
    /**
31
     * @todo implement for all types only work for sessions
32
     *
33
     * @param int $resourceId
34
     * @param int $type
35
     *
36
     * @return array
37
     */
38
    public function getRequirementAndDependencies($resourceId, $type)
39
    {
40
        $sequence = $this->findRequirementForResource($resourceId, $type);
41
        $result = ['requirements' => [], 'dependencies' => []];
42
        if ($sequence && $sequence->hasGraph()) {
43
            $graph = $sequence->getSequence()->getUnSerializeGraph();
44
            $vertex = $graph->getVertex($resourceId);
45
            $from = $vertex->getVerticesEdgeFrom();
46
47
            foreach ($from as $subVertex) {
48
                $vertexId = $subVertex->getId();
49
                $sessionInfo = api_get_session_info($vertexId);
50
                $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

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