Proyectos de Subversion LeadersLinked - Services

Rev

Rev 633 | Rev 635 | Ir a la última revisión | | Comparar con el anterior | Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
119 efrain 1
<?php
2
declare(strict_types=1);
3
 
4
namespace LeadersLinked\Controller;
5
 
6
use Laminas\Mvc\Controller\AbstractActionController;
7
use Laminas\View\Model\JsonModel;
8
use LeadersLinked\Library\Functions;
283 www 9
use LeadersLinked\Mapper\MicrolearningCapsuleMapper;
119 efrain 10
use LeadersLinked\Mapper\QueryMapper;
11
use LeadersLinked\Mapper\UserMapper;
12
use Laminas\Db\Sql\Select;
283 www 13
use LeadersLinked\Mapper\MicrolearningCapsuleCommentMapper;
119 efrain 14
use LeadersLinked\Form\Service\CapsuleCommentForm;
283 www 15
use LeadersLinked\Model\MicrolearningCapsuleComment;
16
use LeadersLinked\Model\MicrolearningAnswer;
17
use LeadersLinked\Mapper\MicrolearningUserProgressMapper;
18
use LeadersLinked\Mapper\MicrolearningSlideMapper;
19
use LeadersLinked\Mapper\MicrolearningUserLogMapper;
20
use LeadersLinked\Model\MicrolearningUserLog;
21
use LeadersLinked\Mapper\MicrolearningTopicMapper;
119 efrain 22
use LeadersLinked\Mapper\CompanyMapper;
283 www 23
use LeadersLinked\Model\MicrolearningUserProgress;
24
use LeadersLinked\Mapper\MicrolearningExtendUserMapper;
25
use LeadersLinked\Mapper\MicrolearningExtendUserCompanyMapper;
26
use LeadersLinked\Mapper\MicrolearningExtendUserFunctionMapper;
27
use LeadersLinked\Mapper\MicrolearningExtendUserGroupMapper;
28
use LeadersLinked\Mapper\MicrolearningExtendUserInstitutionMapper;
29
use LeadersLinked\Mapper\MicrolearningExtendUserPartnerMapper;
30
use LeadersLinked\Mapper\MicrolearningExtendUserProgramMapper;
31
use LeadersLinked\Mapper\MicrolearningExtendUserStudentTypeMapper;
32
use LeadersLinked\Mapper\MicrolearningExtendUserSectorMapper;
33
use LeadersLinked\Mapper\MicrolearningQuizMapper;
34
use LeadersLinked\Mapper\MicrolearningQuestionMapper;
35
use LeadersLinked\Mapper\MicrolearningAnswerMapper;
36
use LeadersLinked\Model\MicrolearningSlide;
37
use LeadersLinked\Library\Storage;
302 www 38
use LeadersLinked\Mapper\MicrolearningTopicCapsuleMapper;
633 stevensc 39
use LeadersLinked\Mapper\MicrolearningTopicUserMapper;
40
use LeadersLinked\Model\MicrolearningTopicUser;
119 efrain 41
 
42
class MicrolearningUserAccessGrantedIds
43
{
44
    public $companies;
45
    public $topics;
46
    public $capsules;
47
 
48
 
49
    public function __construct()
50
    {
51
        $this->companies    = [];
52
        $this->topics       = [];
53
        $this->capsules     = [];
54
    }
55
}
56
 
57
class MicrolearningController extends AbstractActionController
58
{
59
 
60
    /**
61
     *
62
     * @var \Laminas\Db\Adapter\AdapterInterface
63
     */
64
    private $adapter;
65
 
66
    /**
67
     *
68
     * @var \LeadersLinked\Cache\CacheInterface
69
     */
70
    private $cache;
71
 
72
 
73
    /**
74
     *
75
     * @var \Laminas\Log\LoggerInterface
76
     */
77
    private $logger;
78
 
79
    /**
80
     *
81
     * @var array
82
     */
83
    private $config;
84
 
85
 
86
    /**
87
     *
88
     * @var \Laminas\Mvc\I18n\Translator
89
     */
90
    private $translator;
91
 
92
 
93
    /**
94
     *
95
     * @param \Laminas\Db\Adapter\AdapterInterface $adapter
96
     * @param \LeadersLinked\Cache\CacheInterface $cache
97
     * @param \Laminas\Log\LoggerInterface LoggerInterface $logger
98
     * @param array $config
99
     * @param \Laminas\Mvc\I18n\Translator $translator
100
     */
101
    public function __construct($adapter, $cache, $logger, $config, $translator)
102
    {
103
        $this->adapter      = $adapter;
104
        $this->cache        = $cache;
105
        $this->logger       = $logger;
106
        $this->config       = $config;
107
        $this->translator   = $translator;
108
    }
109
 
110
    public function indexAction()
111
    {
112
        $request = $this->getRequest();
113
 
114
        if($request->isGet()) {
115
            return new JsonModel([
116
                'success' => true,
117
                'data' =>  [
118
                    'link_companies' => $this->url()->fromRoute('microlearning/companies',[], ['force_canonical' => true]),
119
                    'link_timeline' => $this->url()->fromRoute('microlearning/timeline',[], ['force_canonical' => true]),
120
                    'link_last_capsule_in_progress' => $this->url()->fromRoute('microlearning/last-capsule-in-progress',[], ['force_canonical' => true]),
121
                    'link_profile' => $this->url()->fromRoute('microlearning/profile',[], ['force_canonical' => true]),
122
                    'link_topics' => $this->url()->fromRoute('microlearning/topics',[], ['force_canonical' => true]),
123
                    'link_capsules_pending' => $this->url()->fromRoute('microlearning/capsules-pending',[], ['force_canonical' => true]),
124
                    'link_capsules_completed' => $this->url()->fromRoute('microlearning/capsules-completed',[], ['force_canonical' => true]),
125
                    'link_capsules_in_progress' => $this->url()->fromRoute('microlearning/capsules-in-progress',[], ['force_canonical' => true]),
126
                ]
127
            ]);
128
        }
129
 
130
        return new JsonModel([
131
            'success' => false,
132
            'data' => 'ERROR_METHOD_NOT_ALLOWED'
133
        ]);
134
    }
590 stevensc 135
 
119 efrain 136
    public function companiesAction()
137
    {
138
 
139
        $request = $this->getRequest();
140
 
141
        if($request->isGet()) {
142
            $currentNetworkPlugin = $this->plugin('currentNetworkPlugin');
143
            $currentNetwork = $currentNetworkPlugin->getNetwork();
144
 
145
 
146
            $accessGrantedIds = $this->getAccessGranted();
147
            $companyMapper = CompanyMapper::getInstance($this->adapter);
148
            $records = $companyMapper->fetchAllByIdsAndNetworkId($accessGrantedIds->companies, $currentNetwork->id);
149
 
333 www 150
            $storage = Storage::getInstance($this->config, $this->adapter);
119 efrain 151
 
152
            $companies = [];
153
            foreach($records as $record)
154
            {
155
                array_push($companies, [
164 efrain 156
                    'uuid' => $record->uuid,
119 efrain 157
                    'name' => $record->name,
283 www 158
                    'image' => $storage->getCompanyImage($record),
119 efrain 159
                    'link_progress' => $this->url()->fromRoute('microlearning/progress',['id' => $record->uuid], ['force_canonical' => true]),
160
                ]);
161
            }
162
 
163
            return new JsonModel([
164
                'success' => true,
165
                'data' =>  $companies
166
            ]);
167
 
168
 
169
        }
170
        return new JsonModel([
171
            'success' => false,
172
            'data' => 'ERROR_METHOD_NOT_ALLOWED'
173
        ]);
174
    }
590 stevensc 175
 
119 efrain 176
    public function capsuleCommentsAction()
177
    {
178
 
179
        $request = $this->getRequest();
180
 
181
        if($request->isGet()) {
182
            $serviceDatetimeFormat = $this->config['leaderslinked.services.datetime'];
183
 
184
            $currentUserPlugin = $this->plugin('currentUserPlugin');
185
            $currentUser = $currentUserPlugin->getUser();
186
 
187
            $capsule_id = $this->params()->fromRoute('capsule_id');
188
 
283 www 189
            $capsuleMapper = MicrolearningCapsuleMapper::getInstance($this->adapter);
119 efrain 190
            $capsule = $capsuleMapper->fetchOneByUuid($capsule_id);
191
 
192
            if(!$capsule) {
193
                return new JsonModel([
194
                    'success' => false,
195
                    'data' => 'ERROR_CAPSULE_NOT_FOUND'
196
 
197
                ]);
198
            }
199
 
200
            $userMapper = UserMapper::getInstance($this->adapter);
201
            $users = [];
202
 
333 www 203
            $storage = Storage::getInstance($this->config, $this->adapter);
283 www 204
 
205
            $capsuleCommentMapper = MicrolearningCapsuleCommentMapper::getInstance($this->adapter);
119 efrain 206
            $records = $capsuleCommentMapper->fetchAllByCapsuleId($capsule->id);
207
 
208
            $comments = [];
209
            foreach($records as $record)
210
            {
211
 
212
                if(isset($users[$record->user_id])) {
213
 
214
                    $user = $users[$record->user_id];
215
 
216
                } else {
217
 
218
                    $user = $userMapper->fetchOne($record->user_id);
219
                    if(!$user) {
220
                        continue;
221
                    }
222
 
223
                    $users[$record->user_id] = $user;
224
 
225
 
226
                }
227
 
228
 
229
                $dt = \DateTime::createFromFormat('Y-m-d H:i:s', $record->added_on);
230
 
231
                array_push($comments, [
232
                    'date' => $dt->format($serviceDatetimeFormat),
283 www 233
                    'image' => $storage->getUserImage($user),
119 efrain 234
                    'fullname' => trim(trim($user->first_name) . ' ' . trim($user->last_name)),
235
                    'rating' => strval($record->rating),
236
                    'comment' => $record->comment,
237
                    'link_delete' => $record->user_id == $currentUser->id ? $this->url()->fromRoute('microlearning/capsules-comments/delete', ['capsule_id' => $capsule->uuid, 'comment_id' => $record->uuid], ['force_canonical' => true]) : '',
238
                ]);
239
            }
240
 
302 www 241
            $dataCountAndRatingAverage = $capsuleCommentMapper->fetchCountAndRatingAverage($capsule->company_id, $capsule->id);
119 efrain 242
 
243
            return new JsonModel([
244
                'success' => true,
245
                'data' => [
246
                    'comments' => $comments,
247
                    'capsule' => [
248
                        'total_comments' => strval($dataCountAndRatingAverage['total_comments']),
249
                        'total_rating' => strval($dataCountAndRatingAverage['total_rating'])
250
                    ]
251
                ]
252
 
253
            ]);
254
 
255
        }
256
 
257
        return new JsonModel([
258
            'success' => false,
259
            'data' => 'ERROR_METHOD_NOT_ALLOWED'
260
        ]);
261
    }
262
 
263
 
264
 
265
    public function capsuleDeleteMyCommentAction()
266
    {
267
 
268
        $request = $this->getRequest();
269
 
270
        if($request->isPost()) {
271
 
272
            $currentUserPlugin = $this->plugin('currentUserPlugin');
273
            $currentUser = $currentUserPlugin->getUser();
274
 
275
            $capsule_id = $this->params()->fromRoute('capsule_id');
276
            $comment_id = $this->params()->fromRoute('comment_id');
277
 
283 www 278
            $capsuleMapper = MicrolearningCapsuleMapper::getInstance($this->adapter);
119 efrain 279
            $capsule = $capsuleMapper->fetchOneByUuid($capsule_id);
280
 
281
            if(!$capsule) {
282
                return new JsonModel([
283
                    'success' => false,
284
                    'data' => 'ERROR_CAPSULE_NOT_FOUND'
285
 
626 stevensc 286
                ]);
119 efrain 287
            }
288
 
283 www 289
            $capsuleCommentMapper = MicrolearningCapsuleCommentMapper::getInstance($this->adapter);
119 efrain 290
            $capsuleComment = $capsuleCommentMapper->fetchOneByUuid($comment_id);
291
 
292
            if(!$capsuleComment) {
293
                return new JsonModel([
294
                    'success' => false,
295
                    'data' => 'ERROR_CAPSULE_COMMENT_NOT_FOUND',
296
                ]);
297
            }
298
 
299
            if($capsuleComment->capsule_id != $capsule->id || $capsuleComment->user_id != $currentUser->id) {
300
                return new JsonModel([
301
                    'success' => false,
302
                    'data' => 'ERROR_YOU_DO_NOT_HAVE_ACCESS_TO_THIS_CAPSULE_COMMENT',
303
                ]);
304
            }
305
 
306
 
307
            $result = $capsuleCommentMapper->delete($capsuleComment->id);
308
            if($result) {
302 www 309
                $dataCountAndRatingAverage = $capsuleCommentMapper->fetchCountAndRatingAverage($capsule->company_id, $capsule->id);
626 stevensc 310
 
119 efrain 311
                return new JsonModel([
312
                    'success' => true,
313
                    'data' => [
314
                        'message' => 'LABEL_CAPSULE_COMMENT_HAVE_BEEN_SUCCESSFULLY_DELETE',
315
                        'capsule' => [
316
                            'total_comments' => strval($dataCountAndRatingAverage['total_comments']),
317
                            'total_rating' => strval($dataCountAndRatingAverage['total_rating'])
318
                        ]
319
                    ],
320
 
321
                ]);
322
            } else {
323
                return new JsonModel([
324
                    'success' => false,
325
                    'data' => $capsuleCommentMapper->getError()
326
 
327
                ]);
328
            }
329
        }
330
 
331
        return new JsonModel([
332
            'success' => false,
333
            'data' => 'ERROR_METHOD_NOT_ALLOWED'
334
        ]);
335
    }
336
 
337
    public function capsuleAddMyCommentAction()
338
    {
339
 
340
        $request = $this->getRequest();
341
 
342
        if($request->isPost()) {
343
 
344
            $currentUserPlugin = $this->plugin('currentUserPlugin');
345
            $currentUser = $currentUserPlugin->getUser();
346
 
347
            $capsule_id = $this->params()->fromRoute('capsule_id');
348
 
349
 
283 www 350
            $capsuleMapper = MicrolearningCapsuleMapper::getInstance($this->adapter);
119 efrain 351
            $capsule = $capsuleMapper->fetchOneByUuid($capsule_id);
352
 
353
            if(!$capsule) {
354
                return new JsonModel([
355
                    'success' => false,
356
                    'data' => 'ERROR_CAPSULE_NOT_FOUND'
357
 
358
                ]);
359
 
360
            }
361
 
362
            $form = new  CapsuleCommentForm();
363
            $dataPost = $request->getPost()->toArray();
364
            $dataPost['added_on'] = $capsuleMapper->getDatebaseNow();
365
 
366
            $form->setData($dataPost);
367
 
368
            if($form->isValid()) {
369
                $dataPost = (array) $form->getData();
370
 
371
 
283 www 372
                $capsuleComment = new MicrolearningCapsuleComment();
119 efrain 373
                $capsuleComment->company_id = $capsule->company_id;
374
                $capsuleComment->capsule_id = $capsule->id;
375
                $capsuleComment->user_id = $currentUser->id;
376
                $capsuleComment->comment = $dataPost['comment'];
377
                $capsuleComment->rating = strval($dataPost['rating']);
378
                $capsuleComment->added_on =  $dataPost['added_on'];
379
 
380
 
283 www 381
                $capsuleCommentMapper = MicrolearningCapsuleCommentMapper::getInstance($this->adapter);
119 efrain 382
                $result = $capsuleCommentMapper->insert($capsuleComment);
383
                if($result) {
384
 
385
                    $capsuleComment = $capsuleCommentMapper->fetchOne($capsuleComment->id);
386
 
302 www 387
                    $dataCountAndRatingAverage = $capsuleCommentMapper->fetchCountAndRatingAverage($capsule->company_id,  $capsule->id);
119 efrain 388
 
389
 
390
 
391
                    return new JsonModel([
392
                        'success' => true,
393
                        'data' => [
394
                            'message' =>'LABEL_CAPSULE_COMMENT_HAVE_BEEN_SUCCESSFULLY_ADDED',
395
 
396
                            'comment' => [
397
                                'comment' => $capsuleComment->comment,
398
                                'rating' => $capsuleComment->rating,
399
                                'link_delete' => $this->url()->fromRoute('microlearning/capsules-comments/delete', ['capsule_id' => $capsule->uuid, 'comment_id' => $capsuleComment->uuid], ['force_canonical' => true])
400
                            ],
401
                            'capsule' => [
402
                                'total_comments' => strval($dataCountAndRatingAverage['total_comments']),
403
                                'total_rating' => strval($dataCountAndRatingAverage['total_rating'])
404
                            ]
405
                        ]
406
 
407
                    ]);
408
                } else {
409
                    return new JsonModel([
410
                        'success' => false,
411
                        'data' => $capsuleCommentMapper->getError()
412
 
413
                    ]);
414
                }
415
 
416
 
417
            } else {
418
                $messages = [];
419
                $form_messages = (array) $form->getMessages();
420
                foreach($form_messages  as $fieldname => $field_messages)
421
                {
422
 
423
                    $messages[$fieldname] = array_values($field_messages);
424
                }
425
 
426
                return new JsonModel([
427
                    'success'   => false,
428
                    'data'   => $messages
429
                ]);
430
            }
431
 
432
 
433
 
434
 
435
        }
436
 
437
        return new JsonModel([
438
            'success' => false,
439
            'data' => 'ERROR_METHOD_NOT_ALLOWED'
440
        ]);
441
    }
442
 
443
    public function lastCapsuleInProgressAction()
444
    {
445
        $request = $this->getRequest();
446
 
447
        if($request->isGet())
448
        {
449
            $currentUserPlugin = $this->plugin('currentUserPlugin');
450
            $currentUser = $currentUserPlugin->getUser();
451
 
452
            $accessGrantedIds = $this->getAccessGranted();
453
 
454
 
283 www 455
            $userProgressMapper = MicrolearningUserProgressMapper::getInstance($this->adapter);
119 efrain 456
            $userProgress = $userProgressMapper->fetchOneLastCapsuleInProgressByUserIdAndCapsuleIds($currentUser->id, $accessGrantedIds->capsules);
283 www 457
            $topicMapper = MicrolearningTopicMapper::getInstance($this->adapter);
119 efrain 458
 
459
            if($userProgress) {
333 www 460
                $storage = Storage::getInstance($this->config, $this->adapter);
283 www 461
                $path = $storage->getPathMicrolearningCapsule();
462
 
463
                $capsuleMapper = MicrolearningCapsuleMapper::getInstance($this->adapter);
119 efrain 464
                $capsule = $capsuleMapper->fetchOne($userProgress->capsule_id);
465
 
301 www 466
                $topic = $topicMapper->fetchOne($userProgress->topic_id);
467
 
283 www 468
                $capsuleCommentMapper = MicrolearningCapsuleCommentMapper::getInstance($this->adapter);
302 www 469
                $dataCountAndRatingAverage = $capsuleCommentMapper->fetchCountAndRatingAverage($capsule->company_id,  $capsule->id);
576 stevensc 470
                $image = $storage->getGenericImage($path, $topic->uuid, $capsule->image);
471
 
119 efrain 472
                $response = [
473
                    'success' => true,
474
                    'data' => [
164 efrain 475
                        'uuid'              => $capsule->uuid,
119 efrain 476
                        'name'              => $capsule->name ? $capsule->name : '',
477
                        'description'       => $capsule->description ? $capsule->description : '',
575 stevensc 478
                        'image'             => ($capsule->image && $topic) ? $storage->getGenericImage($path,  $topic->uuid, $capsule->image )  : '',
119 efrain 479
                        'total_comments'    => strval($dataCountAndRatingAverage['total_comments']),
480
                        'total_rating'      => strval($dataCountAndRatingAverage['total_rating']),
481
                        'completed'         => $userProgress->completed,
145 efrain 482
                        'progress'          => $userProgress->progress,
119 efrain 483
                        'added_on'          => $userProgress->added_on,
484
                        'updated_on'        => $userProgress->updated_on
485
                    ]
486
                ];
487
 
488
 
489
            } else {
490
                $response = [
491
                    'success' => true,
575 stevensc 492
                    'data' => []
119 efrain 493
                ];
494
            }
495
 
496
 
497
        } else {
498
 
499
            $response = [
500
                'success' => false,
501
                'data' => 'ERROR_METHOD_NOT_ALLOWED'
502
            ];
503
 
504
 
505
        }
506
 
507
        return new JsonModel($response);
508
    }
509
 
510
    public function capsulesPendingAction()
511
    {
512
        $request = $this->getRequest();
513
        if($request->isGet()) {
514
            $currentUserPlugin = $this->plugin('currentUserPlugin');
515
            $currentUser = $currentUserPlugin->getUser();
516
 
517
            $name = Functions::sanitizeFilterString($this->params()->fromQuery('name'));
245 efrain 518
            $order_field = Functions::sanitizeFilterString($this->params()->fromQuery('order_field'));
519
            $order_direction = Functions::sanitizeFilterString($this->params()->fromQuery('order_direction'));
119 efrain 520
 
245 efrain 521
            if(!in_array($order_field,['name', 'added_on'] )) {
522
                $order_field = 'name';
523
            }
119 efrain 524
 
245 efrain 525
            if(!in_array( $order_direction,['asc', 'desc'])) {
634 stevensc 526
                $order_direction = 'asc';
245 efrain 527
            }
528
 
283 www 529
            $userProgressMapper = MicrolearningUserProgressMapper::getInstance($this->adapter);
530
            $capsuleMapper = MicrolearningCapsuleMapper::getInstance($this->adapter);
558 stevensc 531
            $topicCapsuleMapper = MicrolearningTopicCapsuleMapper::getInstance($this->adapter); // Añadido
283 www 532
            $topicMapper = MicrolearningTopicMapper::getInstance($this->adapter);
558 stevensc 533
            $capsuleCommentMapper = MicrolearningCapsuleCommentMapper::getInstance($this->adapter); // Reordenado
119 efrain 534
 
535
            $accessGranted = $this->getAccessGranted();
558 stevensc 536
 
634 stevensc 537
            $capsulesData = [];
119 efrain 538
 
333 www 539
            $storage = Storage::getInstance($this->config, $this->adapter);
283 www 540
            $path = $storage->getPathMicrolearningCapsule();
541
 
634 stevensc 542
            foreach($accessGranted->topics as $topic_id)
119 efrain 543
            {
634 stevensc 544
                $topic = $topicMapper->fetchOne($topic_id);
545
                if(!$topic) {
119 efrain 546
                    continue;
547
                }
634 stevensc 548
 
549
                $capsules = $topicCapsuleMapper->fetchAllActiveByTopicId($topic_id) ?? [];
119 efrain 550
 
634 stevensc 551
                foreach($capsules as $capsule) {
552
                    $capsule = $capsuleMapper->fetchOne($capsule->capsule_id);
553
                    if(!$capsule) {
119 efrain 554
                        continue;
555
                    }
634 stevensc 556
 
557
                    $userProgress = $userProgressMapper->fetchOneByUseridAndCapsuleId($currentUser->id, $capsule->id);
558
                    if($userProgress) {
559
                        continue;
558 stevensc 560
                    }
634 stevensc 561
 
562
                    if($name) {
563
                        if(empty($name) || stripos($capsule->name, $name) === false) {
564
                            continue;
565
                        }
566
                    }
567
 
568
                    $dataCountAndRatingAverage = $capsuleCommentMapper->fetchCountAndRatingAverage($capsule->company_id,  $capsule->id);
569
                    $link_slides = $topic->uuid ? $this->url()->fromRoute('microlearning/slides', ['topic_id' => $topic->uuid,  'capsule_id' => $capsule->uuid], ['force_canonical' => true]) : '';
570
 
571
                    array_push($capsulesData, [
572
                        'uuid'              => $capsule->uuid,
573
                        'name'              => $capsule->name ? $capsule->name : '',
574
                        'description'       => $capsule->description ? $capsule->description : '',
575
                        'image'             => $capsule->image ? $storage->getGenericImage($path, $capsule->uuid, $capsule->image)  : '',
576
                        'link_comments'     => $this->url()->fromRoute('microlearning/capsules-comments', ['capsule_id' => $capsule->uuid], ['force_canonical' => true]),
577
                        'link_comment_add'  => $this->url()->fromRoute('microlearning/capsules-comments/add', ['capsule_id' => $capsule->uuid],['force_canonical' => true]),
578
                        'link_slides'       => $link_slides,
579
                        'total_comments'    => strval($dataCountAndRatingAverage['total_comments']),
580
                        'total_rating'      => strval($dataCountAndRatingAverage['total_rating']),
581
                        'progress'          => 0,
582
                        'added_on'          => $capsule->added_on,
583
                        'updated_on'        => $capsule->updated_on,
584
                    ]);
558 stevensc 585
                }
119 efrain 586
            }
587
 
558 stevensc 588
            // 8. Ordenar
245 efrain 589
            if($order_field == 'name') {
590
                if($order_direction == 'asc') {
558 stevensc 591
                    usort($capsulesData, function($a, $b) {
245 efrain 592
                        return strcasecmp($a['name'], $b['name']);
593
                    });
594
                } else {
558 stevensc 595
                    usort($capsulesData, function($a, $b) {
245 efrain 596
                        $result = strcasecmp($a['name'], $b['name']);
558 stevensc 597
                        if($result < 0) { return 1; } else if($result > 0) { return -1; } else { return 0; } // Simplificado
245 efrain 598
                    });
119 efrain 599
                }
600
 
245 efrain 601
            }
602
 
603
            if($order_field == 'added_on') {
604
                if($order_direction == 'asc') {
558 stevensc 605
                    usort($capsulesData, function($a, $b) {
245 efrain 606
                        return strcasecmp($a['added_on'], $b['added_on']);
607
                    });
608
                } else {
558 stevensc 609
                    usort($capsulesData, function($a, $b) {
245 efrain 610
                        $result = strcasecmp($a['added_on'], $b['added_on']);
558 stevensc 611
                        if($result < 0) { return 1; } else if($result > 0) { return -1; } else { return 0; } // Simplificado
245 efrain 612
                    });
613
                }
119 efrain 614
 
558 stevensc 615
            }
119 efrain 616
 
558 stevensc 617
            // 9. Retornar
119 efrain 618
            return new JsonModel([
619
                'success' => true,
558 stevensc 620
                'data' => $capsulesData
634 stevensc 621
            ]);
119 efrain 622
        }
623
 
624
        return new JsonModel([
625
            'success' => false,
626
            'data' => 'ERROR_METHOD_NOT_ALLOWED'
627
        ]);
628
 
629
    }
630
 
631
    public function capsulesCompletedAction()
632
    {
633
        $request = $this->getRequest();
634
        if($request->isGet()) {
635
            $currentUserPlugin = $this->plugin('currentUserPlugin');
636
            $currentUser = $currentUserPlugin->getUser();
637
 
638
            $name = Functions::sanitizeFilterString($this->params()->fromQuery('name'));
245 efrain 639
            $order_field = Functions::sanitizeFilterString($this->params()->fromQuery('order_field'));
640
            $order_direction = Functions::sanitizeFilterString($this->params()->fromQuery('order_direction'));
119 efrain 641
 
246 efrain 642
            if(!in_array($order_field,['name', 'added_on','last_access_on'] )) {
245 efrain 643
                $order_field = 'name';
644
            }
119 efrain 645
 
245 efrain 646
            if(!in_array( $order_direction,['asc', 'desc'])) {
647
                $order_field = 'asc';
648
            }
649
 
283 www 650
            $userProgressMapper = MicrolearningUserProgressMapper::getInstance($this->adapter);
651
            $capsuleMapper = MicrolearningCapsuleMapper::getInstance($this->adapter);
558 stevensc 652
            $topicCapsuleMapper = MicrolearningTopicCapsuleMapper::getInstance($this->adapter);
653
            $topicMapper = MicrolearningTopicMapper::getInstance($this->adapter);
283 www 654
            $capsuleCommentMapper = MicrolearningCapsuleCommentMapper::getInstance($this->adapter);
119 efrain 655
 
656
            $accessGranted = $this->getAccessGranted();
657
 
558 stevensc 658
            $capsulesData = [];
119 efrain 659
 
333 www 660
            $storage = Storage::getInstance($this->config, $this->adapter);
283 www 661
            $path = $storage->getPathMicrolearningCapsule();
662
 
119 efrain 663
            foreach($accessGranted->capsules as $capsule_id)
664
            {
558 stevensc 665
                // 1. Verificar progreso
119 efrain 666
                $userProgress = $userProgressMapper->fetchOneByUseridAndCapsuleId($currentUser->id, $capsule_id);
667
                if(!$userProgress) {
668
                    continue;
669
                }
670
 
671
                if(!$userProgress->completed) {
672
                    continue;
673
                }
674
 
558 stevensc 675
                // 2. Obtener detalles de la cápsula
119 efrain 676
                $capsule = $capsuleMapper->fetchOne($capsule_id);
558 stevensc 677
                if(!$capsule) {
678
                    continue;
679
                }
119 efrain 680
 
558 stevensc 681
                // 3. Filtrar por nombre
119 efrain 682
                if($name) {
683
                    if(empty($name) || stripos($capsule->name, $name) === false) {
684
                        continue;
685
                    }
686
                }
687
 
558 stevensc 688
                // 4. Obtener Tópico asociado válido
689
                $topic = null;
690
                $topic_uuid_for_links = null;
691
                $relation = $topicCapsuleMapper->fetchOneByCapsuleId($capsule->id);
692
                if ($relation && in_array($relation->topic_id, $accessGranted->topics)) {
693
                    $topic = $topicMapper->fetchOne($relation->topic_id);
694
                    if ($topic) {
695
                        $topic_uuid_for_links = $topic->uuid;
696
                    }
697
                }
698
 
699
                // 5. Obtener datos de comentarios
302 www 700
                $dataCountAndRatingAverage = $capsuleCommentMapper->fetchCountAndRatingAverage($capsule->company_id, $capsule->id);
119 efrain 701
 
558 stevensc 702
                // 6. Construir enlace slides
703
                $link_slides = $topic_uuid_for_links ? $this->url()->fromRoute('microlearning/slides', ['topic_id' => $topic_uuid_for_links,  'capsule_id' => $capsule->uuid], ['force_canonical' => true]) : '';
119 efrain 704
 
558 stevensc 705
                // 7. Añadir al array de resultados
706
                array_push($capsulesData, [
119 efrain 707
                    'uuid'              => $capsule->uuid,
708
                    'name'              => $capsule->name ? $capsule->name : '',
709
                    'description'       => $capsule->description ? $capsule->description : '',
283 www 710
                    'image'             => $capsule->image ? $storage->getGenericImage($path, $capsule->uuid, $capsule->image)  : '',
119 efrain 711
                    'position'          => $capsule->order,
712
                    'link_comments'     => $this->url()->fromRoute('microlearning/capsules-comments', ['capsule_id' => $capsule->uuid], ['force_canonical' => true]),
713
                    'link_comment_add'  => $this->url()->fromRoute('microlearning/capsules-comments/add', ['capsule_id' => $capsule->uuid],['force_canonical' => true]),
558 stevensc 714
                    'link_slides'       => $link_slides,
119 efrain 715
                    'total_comments'    => strval($dataCountAndRatingAverage['total_comments']),
716
                    'total_rating'      => strval($dataCountAndRatingAverage['total_rating']),
145 efrain 717
                    'progress'          => $userProgress->progress,
119 efrain 718
                    'added_on'          => $capsule->added_on,
246 efrain 719
                    'last_access_on'    => $userProgress->updated_on,
119 efrain 720
                    'updated_on'        => $capsule->updated_on,
721
                ]);
722
            }
723
 
558 stevensc 724
            // 8. Ordenar (lógica de ordenación permanece igual, usando $capsulesData)
245 efrain 725
            if($order_field == 'name') {
726
                if($order_direction == 'asc') {
558 stevensc 727
                    usort($capsulesData, function($a, $b) {
245 efrain 728
                        return strcasecmp($a['name'], $b['name']);
729
                    });
730
                } else {
558 stevensc 731
                    usort($capsulesData, function($a, $b) {
245 efrain 732
                        $result = strcasecmp($a['name'], $b['name']);
558 stevensc 733
                        if($result < 0) { return 1; } else if($result > 0) { return -1; } else { return 0; }
245 efrain 734
                    });
119 efrain 735
                }
245 efrain 736
            }
737
 
738
            if($order_field == 'added_on') {
739
                if($order_direction == 'asc') {
558 stevensc 740
                    usort($capsulesData, function($a, $b) {
245 efrain 741
                        return strcasecmp($a['added_on'], $b['added_on']);
742
                    });
743
                } else {
558 stevensc 744
                    usort($capsulesData, function($a, $b) {
245 efrain 745
                        $result = strcasecmp($a['added_on'], $b['added_on']);
558 stevensc 746
                        if($result < 0) { return 1; } else if($result > 0) { return -1; } else { return 0; }
245 efrain 747
                    });
748
                }
749
            }
246 efrain 750
 
751
            if($order_field == 'last_access_on') {
752
                if($order_direction == 'asc') {
558 stevensc 753
                    usort($capsulesData, function($a, $b) {
246 efrain 754
                        return strcasecmp($a['last_access_on'], $b['last_access_on']);
755
                    });
756
                } else {
558 stevensc 757
                    usort($capsulesData, function($a, $b) {
246 efrain 758
                        $result = strcasecmp($a['last_access_on'], $b['last_access_on']);
558 stevensc 759
                        if($result < 0) { return 1; } else if($result > 0) { return -1; } else { return 0; }
246 efrain 760
                    });
761
                }
762
            }
763
 
764
 
765
 
766
 
119 efrain 767
 
768
            return new JsonModel([
769
                'success' => true,
558 stevensc 770
                'data' => $capsulesData
119 efrain 771
            ]);
772
 
773
        }
774
 
775
        return new JsonModel([
776
            'success' => false,
777
            'data' => 'ERROR_METHOD_NOT_ALLOWED'
778
        ]);
779
    }
780
 
781
    public function capsulesInProgressAction()
782
    {
783
        $request = $this->getRequest();
784
        if($request->isGet()) {
785
            $currentUserPlugin = $this->plugin('currentUserPlugin');
786
            $currentUser = $currentUserPlugin->getUser();
787
 
788
            $name = Functions::sanitizeFilterString($this->params()->fromQuery('name'));
245 efrain 789
            $order_field = Functions::sanitizeFilterString($this->params()->fromQuery('order_field'));
790
            $order_direction = Functions::sanitizeFilterString($this->params()->fromQuery('order_direction'));
119 efrain 791
 
246 efrain 792
            if(!in_array($order_field,['name', 'added_on', 'last_access_on'] )) {
245 efrain 793
                $order_field = 'name';
794
            }
119 efrain 795
 
245 efrain 796
            if(!in_array( $order_direction,['asc', 'desc'])) {
558 stevensc 797
                $order_direction = 'asc';
245 efrain 798
            }
799
 
283 www 800
            $userProgressMapper = MicrolearningUserProgressMapper::getInstance($this->adapter);
801
            $capsuleMapper = MicrolearningCapsuleMapper::getInstance($this->adapter);
558 stevensc 802
            $topicCapsuleMapper = MicrolearningTopicCapsuleMapper::getInstance($this->adapter);
803
            $topicMapper = MicrolearningTopicMapper::getInstance($this->adapter);
283 www 804
            $capsuleCommentMapper = MicrolearningCapsuleCommentMapper::getInstance($this->adapter);
119 efrain 805
 
806
            $accessGranted = $this->getAccessGranted();
807
 
558 stevensc 808
            $capsulesData = [];
119 efrain 809
 
333 www 810
            $storage = Storage::getInstance($this->config, $this->adapter);
283 www 811
            $path = $storage->getPathMicrolearningCapsule();
812
 
119 efrain 813
            foreach($accessGranted->capsules as $capsule_id)
814
            {
558 stevensc 815
                // 1. Verificar progreso
119 efrain 816
                $userProgress = $userProgressMapper->fetchOneByUseridAndCapsuleId($currentUser->id, $capsule_id);
558 stevensc 817
                if(!$userProgress || $userProgress->completed) { // Si no hay progreso o ya está completada
119 efrain 818
                    continue;
819
                }
558 stevensc 820
 
821
                // 2. Obtener detalles de la cápsula
822
                $capsule = $capsuleMapper->fetchOne($capsule_id);
823
                if(!$capsule) {
119 efrain 824
                    continue;
825
                }
826
 
558 stevensc 827
                // 3. Filtrar por nombre
119 efrain 828
                if($name) {
829
                    if(empty($name) || stripos($capsule->name, $name) === false) {
830
                        continue;
831
                    }
832
                }
833
 
558 stevensc 834
                // 4. Obtener Tópico asociado válido
835
                $topic = null;
836
                $topic_uuid_for_links = null;
837
                $relation = $topicCapsuleMapper->fetchOneByCapsuleId($capsule->id);
838
                if ($relation && in_array($relation->topic_id, $accessGranted->topics)) {
839
                    $topic = $topicMapper->fetchOne($relation->topic_id);
840
                    if ($topic) {
841
                        $topic_uuid_for_links = $topic->uuid;
842
                    }
843
                }
119 efrain 844
 
558 stevensc 845
                // 5. Obtener datos de comentarios
302 www 846
                $dataCountAndRatingAverage = $capsuleCommentMapper->fetchCountAndRatingAverage($capsule->company_id,  $capsule->id);
119 efrain 847
 
558 stevensc 848
                // 6. Construir enlace slides
849
                $link_slides = $topic_uuid_for_links ? $this->url()->fromRoute('microlearning/slides', ['topic_id' => $topic_uuid_for_links,  'capsule_id' => $capsule->uuid], ['force_canonical' => true]) : '';
119 efrain 850
 
558 stevensc 851
                // 7. Añadir al array de resultados
852
                array_push($capsulesData, [
119 efrain 853
                    'uuid'              => $capsule->uuid,
854
                    'name'              => $capsule->name ? $capsule->name : '',
855
                    'description'       => $capsule->description ? $capsule->description : '',
283 www 856
                    'image'             => $capsule->image ? $storage->getGenericImage($path, $capsule->uuid, $capsule->image)  : '',
119 efrain 857
                    'position'          => $capsule->order,
858
                    'link_comments'     => $this->url()->fromRoute('microlearning/capsules-comments', ['capsule_id' => $capsule->uuid], ['force_canonical' => true]),
859
                    'link_comment_add'  => $this->url()->fromRoute('microlearning/capsules-comments/add', ['capsule_id' => $capsule->uuid],['force_canonical' => true]),
558 stevensc 860
                    'link_slides'       => $link_slides,
119 efrain 861
                    'total_comments'    => strval($dataCountAndRatingAverage['total_comments']),
862
                    'total_rating'      => strval($dataCountAndRatingAverage['total_rating']),
585 stevensc 863
                    'progress'          => $userProgress->progress,
864
                    'last_access_on'    => $userProgress->updated_on,
865
                    'added_on'          => $capsule->added_on,
866
                    'updated_on'        => $capsule->updated_on,
119 efrain 867
                ]);
868
            }
869
 
558 stevensc 870
            // 8. Ordenar (lógica de ordenación permanece igual, usando $capsulesData)
245 efrain 871
            if($order_field == 'name') {
872
                if($order_direction == 'asc') {
558 stevensc 873
                    usort($capsulesData, function($a, $b) {
245 efrain 874
                        return strcasecmp($a['name'], $b['name']);
875
                    });
876
                } else {
558 stevensc 877
                    usort($capsulesData, function($a, $b) {
245 efrain 878
                        $result = strcasecmp($a['name'], $b['name']);
558 stevensc 879
                        if($result < 0) { return 1; } else if($result > 0) { return -1; } else { return 0; }
245 efrain 880
                    });
119 efrain 881
                }
245 efrain 882
            }
883
 
884
            if($order_field == 'added_on') {
885
                if($order_direction == 'asc') {
558 stevensc 886
                    usort($capsulesData, function($a, $b) {
245 efrain 887
                        return strcasecmp($a['added_on'], $b['added_on']);
888
                    });
889
                } else {
558 stevensc 890
                    usort($capsulesData, function($a, $b) {
245 efrain 891
                        $result = strcasecmp($a['added_on'], $b['added_on']);
558 stevensc 892
                        if($result < 0) { return 1; } else if($result > 0) { return -1; } else { return 0; }
245 efrain 893
                    });
894
                }
895
            }
246 efrain 896
 
897
            if($order_field == 'last_access_on') {
898
                if($order_direction == 'asc') {
558 stevensc 899
                    usort($capsulesData, function($a, $b) {
246 efrain 900
                        return strcasecmp($a['last_access_on'], $b['last_access_on']);
901
                    });
902
                } else {
558 stevensc 903
                    usort($capsulesData, function($a, $b) {
246 efrain 904
                        $result = strcasecmp($a['last_access_on'], $b['last_access_on']);
558 stevensc 905
                        if($result < 0) { return 1; } else if($result > 0) { return -1; } else { return 0; }
246 efrain 906
                    });
907
                }
908
            }
245 efrain 909
 
246 efrain 910
 
119 efrain 911
            return new JsonModel([
912
                'success' => true,
558 stevensc 913
                'data' => $capsulesData
119 efrain 914
            ]);
915
        }
916
 
917
        return new JsonModel([
918
            'success' => false,
919
            'data' => 'ERROR_METHOD_NOT_ALLOWED'
920
        ]);
921
    }
922
 
923
 
924
    public function timelineAction()
925
    {
926
 
927
        $request = $this->getRequest();
928
        if($request->isGet()) {
929
            $currentUserPlugin = $this->plugin('currentUserPlugin');
930
            $currentUser = $currentUserPlugin->getUser();
931
 
932
 
933
            $page = intval($this->params()->fromQuery('page'), 10);
934
 
935
            $activities = [
283 www 936
                MicrolearningUserLog::ACTIVITY_SIGNIN            => 'LABEL_MICROLEARNING_ACTIVITY_SIGNIN',
937
                MicrolearningUserLog::ACTIVITY_SIGNOUT           => 'LABEL_MICROLEARNING_ACTIVITY_SIGNOUT',
938
                MicrolearningUserLog::ACTIVITY_START_TOPIC       => 'LABEL_MICROLEARNING_ACTIVITY_START_TOPIC',
939
                MicrolearningUserLog::ACTIVITY_START_CAPSULE     => 'LABEL_MICROLEARNING_ACTIVITY_START_CAPSULE',
940
                MicrolearningUserLog::ACTIVITY_VIEW_SLIDE        => 'LABEL_MICROLEARNING_ACTIVITY_VIEW_SLIDE',
941
                MicrolearningUserLog::ACTIVITY_TAKE_A_TEST       => 'LABEL_MICROLEARNING_ACTIVITY_TAKE_A_TEST',
942
                MicrolearningUserLog::ACTIVITY_RETAKE_A_TEST     => 'LABEL_MICROLEARNING_ACTIVITY_RETAKE_A_TEST',
943
                MicrolearningUserLog::ACTIVITY_APPROVED_TEST     => 'LABEL_MICROLEARNING_ACTIVITY_APPROVED_TEST',
944
                MicrolearningUserLog::ACTIVITY_COMPLETED_CAPSULE => 'LABEL_MICROLEARNING_ACTIVITY_COMPLETED_CAPSULE',
945
                MicrolearningUserLog::ACTIVITY_COMPLETED_TOPIC   => 'LABEL_MICROLEARNING_ACTIVITY_COMPLETED_TOPIC',
119 efrain 946
            ];
947
 
948
 
949
 
283 www 950
            $microlearningUserLogMapper = MicrolearningUserLogMapper::getInstance($this->adapter);
951
            $paginator = $microlearningUserLogMapper->getAllMessagesPaginatorByUserId($currentUser->id, $page);
119 efrain 952
 
953
            $items = [];
954
            foreach($paginator as $record)
955
            {
956
                $dt = \DateTime::createFromFormat('Y-m-d H:i:s', $record->added_on);
957
 
958
                array_push($items, [
959
                    'activity' => $activities[$record->activity],
960
                    'added_on' => $dt->format('d/m/Y H:i a')
961
                ]);
962
            }
963
 
964
 
965
            return new JsonModel([
966
                'success' => true,
967
                'data' => [
968
                    'total' => [
969
                        'count' => $paginator->getTotalItemCount(),
970
                        'pages' => $paginator->getPages()->pageCount,
971
                    ],
972
                    'current' => [
973
                        'items'    => $items,
974
                        'page'     => $paginator->getCurrentPageNumber(),
975
                        'count'    => $paginator->getCurrentItemCount(),
976
                    ]
977
                ]
978
            ]);
979
 
980
 
981
        } else {
982
            return new JsonModel([
983
                'success' => false,
984
                'data' => 'ERROR_METHOD_NOT_ALLOWED'
985
            ]);
986
        }
987
    }
988
 
989
    /**
990
     * Valores para la generación de los gráficos de progreso
991
     * Para las repuesta afirmativa
992
     * [
993
     *  'success' => true,
994
     *      'data' => [
995
     *          'topicTotal' => cantidad total de tópicos,
996
     *          'topicStarted' => cantidad de tópicos iniciados,
997
     *          'topicIncompleted' => cantidad de tópicos incompletos,
998
     *          'topicCompleted' => cantidad de tópicos completos,
999
     *          'percentCompleted' => % de diapositivas completados ,
1000
     *          'percentIncompleted' => % de diapositivas incompletos ,
1001
     *          'percentWithoutReturning' => % de cápsulas sin retorno después de completada,
1002
     *          'percentWithReturning' => % de cápsulas con retorno después de completada,
558 stevensc 1003
     *      ],
119 efrain 1004
     * ]
1005
     *
1006
     *
1007
     *  En caso contrario
1008
     *  [
1009
     *      'success' => false,
1010
     *      'data' => mensaje de error
1011
     *  ]
1012
     *
1013
     *
1014
     * @return \Laminas\View\Model\JsonModel
1015
     */
1016
    public function progressAction()
1017
    {
1018
 
1019
        $request = $this->getRequest();
1020
        if($request->isGet()) {
1021
            $currentUserPlugin = $this->plugin('currentUserPlugin');
1022
            $currentUser = $currentUserPlugin->getUser();
1023
 
1024
 
1025
            $accessGrantedIds = $this->getAccessGranted();
1026
            $id = $this->params()->fromRoute('id');
1027
 
1028
            $companyMapper = CompanyMapper::getInstance($this->adapter);
1029
            $company = $companyMapper->fetchOneByUuid($id);
1030
 
1031
            if(!$company) {
1032
                $response = [
1033
                    'success' => false,
1034
                    'data' => 'ERROR_COMPANY_NOT_FOUND',
1035
                ];
1036
 
1037
 
1038
                return new JsonModel($response);
1039
            }
1040
 
1041
            if(!in_array($company->id, $accessGrantedIds->companies)) {
1042
                $response = [
1043
                    'success' => false,
1044
                    'data' => 'ERROR_YOU_DO_NOT_HAVE_ACCESS_TO_THIS_COMPANY',
1045
                ];
1046
 
1047
 
1048
                return new JsonModel($response);
1049
            }
1050
 
1051
            $capsuleTotal              = 0;
1052
            $capsuleCompleted          = 0;
1053
            $capsuleWithReturning      = 0;
1054
            $capsuleWithoutReturning   = 0;
1055
            $capsuleStarted            = 0;
1056
            $capsuleToStart            = 0;
1057
            $percentCompleted          = 0;
1058
            $percentIncompleted        = 100;
1059
 
283 www 1060
            $topicMapper = MicrolearningTopicMapper::getInstance($this->adapter);
119 efrain 1061
            $topics = $topicMapper->fetchAllActiveByCompanyIdAndIds($company->id, $accessGrantedIds->topics);
1062
 
283 www 1063
            $progressMapper = MicrolearningUserProgressMapper::getInstance($this->adapter);
119 efrain 1064
 
302 www 1065
            $topicCapsuleMapper = MicrolearningTopicCapsuleMapper::getInstance($this->adapter);
119 efrain 1066
 
1067
            foreach($topics as $topic)
1068
            {
302 www 1069
                $resultCount = $topicCapsuleMapper->fetchCountByCompanyIdAndTopicId($company->id, $topic->id);
119 efrain 1070
                $capsuleTotal =  $capsuleTotal + $resultCount;
1071
 
1072
                $resultCount = $progressMapper->fetchCountCapsulesCompletedByIdAndTopicId($currentUser->id, $topic->id);
1073
                $capsuleCompleted = $capsuleCompleted + $resultCount;
1074
 
1075
                $resultCount = $progressMapper->fetchCountCapsulesCompletedWithReturningByIdAndTopicId($currentUser->id, $topic->id);
1076
                $capsuleWithReturning = $capsuleWithReturning + $resultCount;
1077
 
1078
                $resultCount = $progressMapper->fetchCountCapsulesCompletedWithoutReturningByIdAndTopicId($currentUser->id, $topic->id);
1079
                $capsuleWithoutReturning = $capsuleWithoutReturning + $resultCount;
1080
 
1081
                $resultCount = $progressMapper->fetchCountCapsulesCompletedByIdAndTopicId($currentUser->id, $topic->id);
1082
                $capsuleStarted = $capsuleStarted + $resultCount;
1083
            }
1084
 
1085
            $capsuleToStart = $capsuleTotal -  $capsuleStarted;
1086
 
1087
            if($capsuleTotal > 0) {
1088
                $percentCompleted = ($capsuleCompleted * 100) /  $capsuleTotal;
1089
                $percentIncompleted = 100 - $percentCompleted;
1090
            }
1091
 
1092
            return new JsonModel([
1093
                'success' => true,
1094
                'data' => [
1095
                    'capsuleTotal' => $capsuleTotal,
1096
                    'capsuleCompleted' => $capsuleCompleted,
1097
                    'capsuleStarted' => $capsuleStarted,
1098
                    'capsuleToStart' => $capsuleToStart,
1099
                    'percentCompleted' => number_format($percentCompleted, 2, '.', ','),
1100
                    'percentIncompleted' => number_format($percentIncompleted, 2, '.', ','),
1101
                    'capsuleWithReturning' => $capsuleWithReturning,
1102
                    'capsuleWithoutReturning' => $capsuleWithoutReturning,
1103
                ],
1104
            ]);
1105
 
1106
 
1107
        } else {
1108
            return new JsonModel([
1109
                'success' => false,
1110
                'data' => 'ERROR_METHOD_NOT_ALLOWED'
1111
            ]);
1112
        }
1113
    }
1114
 
1115
 
1116
    public function topicsAction()
1117
    {
1118
        $request = $this->getRequest();
626 stevensc 1119
 
119 efrain 1120
        if($request->isGet()) {
1121
            $currentUserPlugin = $this->plugin('currentUserPlugin');
1122
            $currentUser = $currentUserPlugin->getUser();
1123
 
1124
            $data = [];
1125
            $accessGrantedIds = $this->getAccessGranted();
1126
 
283 www 1127
            $userProgressMapper = MicrolearningUserProgressMapper::getInstance($this->adapter);
1128
            $topicMapper = MicrolearningTopicMapper::getInstance($this->adapter);
119 efrain 1129
 
333 www 1130
            $storage = Storage::getInstance($this->config, $this->adapter);
283 www 1131
            $path = $storage->getPathMicrolearningTopic();
119 efrain 1132
 
1133
            foreach($accessGrantedIds->topics as $id)
1134
            {
1135
                $topic = $topicMapper->fetchOne($id);
1136
                if(!$topic) {
1137
                    continue;
1138
                }
1139
 
1140
                $userProgress = $userProgressMapper->fetchOneByUserIdAndTopicId($currentUser->id, $id);
1141
                if($userProgress) {
1142
                    $progress = $userProgress->progress;
1143
                    $completed = $userProgress->completed;
1144
                } else {
1145
                    $progress = 0;
1146
                    $completed = 0;
1147
                }
1148
 
1149
 
1150
 
1151
                array_push($data, [
164 efrain 1152
                    'uuid'          => $topic->uuid,
119 efrain 1153
                    'name'          => $topic->name ? $topic->name : '',
1154
                    'description'   => $topic->description ? $topic->description : '',
283 www 1155
                    'image'         => $topic->image ? $storage->getGenericImage($path, $topic->uuid, $topic->image) : '',
119 efrain 1156
                    'progress'      => $progress,
1157
                    'completed'     => $completed,
1158
                    'order'         => $topic->order,
1159
                    'added_on'      => $topic->added_on,
564 stevensc 1160
                    'updated_on'    => $topic->updated_on
119 efrain 1161
                ]);
1162
            }
1163
 
1164
            usort($data, function($a, $b) {
1165
 
1166
                $result =  $a['order'] <=> $b['order'];
1167
                if(0 == $result) {
1168
                    $result = strcasecmp($a['added_on'], $b['added_on']);
1169
                    if(0 == $result) {
1170
                        $result = strcasecmp($a['name'], $b['name']);
1171
                    }
1172
                }
1173
 
1174
                if($result < 0) {
1175
                    return 1;
1176
                } else if($result > 0) {
1177
                    return -1;
1178
                } else  {
1179
                    return  0;
1180
                }
1181
            });
1182
 
1183
 
1184
 
1185
                return new JsonModel([
1186
                    'success' => true,
1187
                    'data' => $data
1188
                ]);
1189
 
1190
        } else {
1191
            return new JsonModel([
1192
                'success' => false,
1193
                'data' => 'ERROR_METHOD_NOT_ALLOWED'
1194
            ]);
1195
        }
1196
    }
1197
 
161 efrain 1198
    public function getTopicAction()
1199
    {
563 stevensc 1200
        // Handle GET request
161 efrain 1201
        $request = $this->getRequest();
1202
        if($request->isGet()) {
563 stevensc 1203
            // Get current user
161 efrain 1204
            $currentUserPlugin = $this->plugin('currentUserPlugin');
1205
            $currentUser = $currentUserPlugin->getUser();
563 stevensc 1206
 
1207
            // Get topic ID from route
161 efrain 1208
            $id = $this->params()->fromRoute('id');
283 www 1209
            $topicMapper = MicrolearningTopicMapper::getInstance($this->adapter);
161 efrain 1210
            $topic = $topicMapper->fetchOneByUuid($id);
563 stevensc 1211
 
1212
            // Return error if topic not found
161 efrain 1213
            if(!$topic) {
1214
                return new JsonModel([
1215
                    'success' => false,
1216
                    'data' => 'ERROR_TOPIC_NOT_FOUND'
1217
                ]);
1218
            }
563 stevensc 1219
 
1220
            // Check if current user has access to the topic
161 efrain 1221
            $accessGrantedIds = $this->getAccessGranted();
1222
            if(!in_array($topic->id, $accessGrantedIds->topics)) {
1223
                return new JsonModel([
1224
                    'success' => false,
1225
                    'data' => 'ERROR_YOU_DO_NOT_HAVE_ACCESS_TO_THIS_TOPIC'
1226
                ]);
1227
            }
563 stevensc 1228
 
1229
            // Get user progress for this topic
283 www 1230
            $userProgressMapper = MicrolearningUserProgressMapper::getInstance($this->adapter);
563 stevensc 1231
            $userProgress = $userProgressMapper->fetchOneByUserIdAndTopicId($currentUser->id, $topic->id);
161 efrain 1232
 
580 stevensc 1233
            $progress = $userProgress->progress ?? 0;
1234
            $completed = $userProgress->completed ?? 0;
563 stevensc 1235
 
1236
            // Initialize storage service to get image paths
333 www 1237
            $storage = Storage::getInstance($this->config, $this->adapter);
563 stevensc 1238
            $pathTopic = $storage->getPathMicrolearningTopic();
1239
 
1240
            // Fetch associated capsules using the private helper method
1241
            $capsulesData = $this->_getCapsulesByTopic($topic, $storage);
1242
 
1243
            // Prepare data for JSON response
161 efrain 1244
            $data = [
165 efrain 1245
                'uuid'          => $topic->uuid,
161 efrain 1246
                'name'          => $topic->name ? $topic->name : '',
1247
                'description'   => $topic->description ? $topic->description : '',
563 stevensc 1248
                'image'         => $topic->image ? $storage->getGenericImage($pathTopic, $topic->uuid, $topic->image) : '',
161 efrain 1249
                'progress'      => $progress,
1250
                'completed'     => $completed,
1251
                'order'         => $topic->order,
1252
                'added_on'      => $topic->added_on,
1253
                'updated_on'    => $topic->updated_on,
563 stevensc 1254
                'total_capsules' => count($capsulesData),
1255
                'capsules'      => $capsulesData,
161 efrain 1256
            ];
563 stevensc 1257
 
161 efrain 1258
            return new JsonModel([
1259
                'success' => true,
1260
                'data' => $data
1261
            ]);
563 stevensc 1262
 
161 efrain 1263
        } else {
563 stevensc 1264
            // Return error if not a GET request
161 efrain 1265
            return new JsonModel([
1266
                'success' => false,
1267
                'data' => 'ERROR_METHOD_NOT_ALLOWED'
1268
            ]);
1269
        }
1270
    }
563 stevensc 1271
 
1272
    /**
580 stevensc 1273
     * @param MicrolearningTopic $topic The topic object.
1274
     * @param Storage $storage The storage object.
1275
     * @return array The capsules data.
563 stevensc 1276
     */
1277
    private function _getCapsulesByTopic($topic, $storage)
1278
    {
578 stevensc 1279
        $data = [];
584 stevensc 1280
        $accessGrantedIds = $this->getAccessGranted();
563 stevensc 1281
 
578 stevensc 1282
        if (!$topic) {
1283
            return $data;
1284
        }
1285
 
584 stevensc 1286
        if (!in_array($topic->id, $accessGrantedIds->topics)) {
578 stevensc 1287
            return $data;
584 stevensc 1288
        }
578 stevensc 1289
 
1290
        $currentUserPlugin = $this->plugin('currentUserPlugin');
1291
        $currentUser = $currentUserPlugin->getUser();
1292
 
1293
        $topicCapsuleMapper = MicrolearningTopicCapsuleMapper::getInstance($this->adapter);
574 stevensc 1294
        $topicCapsuleRelations = $topicCapsuleMapper->fetchAllActiveByTopicId($topic->id);
1295
 
581 stevensc 1296
        $userProgressMapper = MicrolearningUserProgressMapper::getInstance($this->adapter);
1297
        $capsuleCommentMapper = MicrolearningCapsuleCommentMapper::getInstance($this->adapter);
578 stevensc 1298
 
581 stevensc 1299
        $path = $storage->getPathMicrolearningCapsule();
1300
 
578 stevensc 1301
        foreach ($topicCapsuleRelations as $relation) {
584 stevensc 1302
            if(!in_array($relation->capsule_id, $accessGrantedIds->capsules)) {
1303
                continue;
1304
            }
578 stevensc 1305
 
581 stevensc 1306
            $capsuleMapper = MicrolearningCapsuleMapper::getInstance($this->adapter);
1307
            $capsule = $capsuleMapper->fetchOne($relation->capsule_id);
563 stevensc 1308
 
581 stevensc 1309
            if(!$capsule) {
1310
                continue;
1311
            }
1312
 
578 stevensc 1313
            $userProgress = $userProgressMapper->fetchOneByUseridAndCapsuleId($currentUser->id, $capsule->id);
1314
            $progress = $userProgress->progress ?? 0;
1315
            $completed = $userProgress->completed ?? 0;
1316
            $dataCountAndRatingAverage = $capsuleCommentMapper->fetchCountAndRatingAverage($capsule->company_id, $capsule->id);
1317
            $image = $capsule->image ? $storage->getGenericImage($path, $capsule->uuid, $capsule->image) : '';
1318
            $total_comments = strval($dataCountAndRatingAverage['total_comments']);
1319
            $total_rating = strval($dataCountAndRatingAverage['total_rating']);
1320
 
581 stevensc 1321
            array_push($data, [
578 stevensc 1322
                'uuid'              => $capsule->uuid,
1323
                'name'              => $capsule->name ? $capsule->name : '',
1324
                'description'       => $capsule->description ? $capsule->description : '',
1325
                'image'             => $image,
1326
                'total_comments'    => $total_comments,
1327
                'total_rating'      => $total_rating,
1328
                'progress'          => $progress,
1329
                'completed'         => $completed,
1330
                'added_on'          => $capsule->added_on,
1331
                'updated_on'        => $capsule->updated_on,
581 stevensc 1332
            ]);
563 stevensc 1333
        }
578 stevensc 1334
 
581 stevensc 1335
        return $data;
563 stevensc 1336
    }
586 stevensc 1337
 
1338
    /**
1339
     * @param MicrolearningCapsule $capsule The capsule object.
1340
     * @param Storage $storage The storage object.
1341
     * @return array The slides data.
1342
     */
1343
    private function _getSlidesByCapsule($capsule, $storage)
1344
    {
1345
        $data = [];
1346
        $accessGrantedIds = $this->getAccessGranted();
1347
 
1348
        if (!$capsule) {
1349
            return $data;
1350
        }
1351
 
1352
        if (!in_array($capsule->id, $accessGrantedIds->capsules)) {
1353
            return $data;
1354
        }
1355
 
1356
        $currentUserPlugin = $this->plugin('currentUserPlugin');
1357
        $currentUser = $currentUserPlugin->getUser();
1358
 
1359
        $slideMapper = MicrolearningSlideMapper::getInstance($this->adapter);
1360
        $userProgressMapper = MicrolearningUserProgressMapper::getInstance($this->adapter);
1361
        $quizMapper = MicrolearningQuizMapper::getInstance($this->adapter);
1362
 
1363
        $path = $storage->getPathMicrolearningSlide();
587 stevensc 1364
        $slides = $slideMapper->fetchAllByCompanyIdAndCapsuleId($capsule->company_id, $capsule->id);
586 stevensc 1365
 
1366
        foreach ($slides as $slide) {
1367
            $userProgress = $userProgressMapper->fetchOneByUserIdAndSlideId($currentUser->id, $slide->id);
1368
            $completed = $userProgress ? $userProgress->completed : 0;
1369
 
1370
            $quiz_uuid = '';
1371
            $quiz_data = [];
1372
            $link_take_a_test = '';
1373
 
1374
            if ($slide->quiz_id) {
1375
                $quiz = $quizMapper->fetchOne($slide->quiz_id);
1376
                if ($quiz) {
1377
                    $quiz_uuid = $quiz->uuid;
1378
                    $quiz_data = $this->getQuiz($slide->quiz_id);
1379
                    $link_take_a_test = $this->url()->fromRoute('microlearning/take-a-test', ['slide_id' => $slide->uuid], ['force_canonical' => true]);
1380
                }
1381
            }
1382
 
1383
            array_push($data, [
1384
                'quiz'                  => $quiz_uuid,
1385
                'quiz_data'             => $quiz_data,
1386
                'uuid'                  => $slide->uuid,
1387
                'name'                  => $slide->name ? $slide->name : '',
1388
                'description'           => $slide->description ? $slide->description : '',
1389
                'type'                  => $slide->type,
1390
                'background'            => $slide->background ? $storage->getGenericImage($path, $slide->uuid, $slide->background) : '',
1391
                'file'                  => $slide->file ? $storage->getGenericFile($path, $slide->uuid, $slide->file) : '',
1392
                'order'                 => $slide->order,
1393
                'completed'             => $completed,
1394
                'link_take_a_test'      => $link_take_a_test,
1395
                'added_on'              => $slide->added_on,
1396
                'updated_on'            => $slide->updated_on,
1397
            ]);
1398
        }
1399
 
1400
        // Sort slides by order, then by added_on, then by name
1401
        usort($data, function($a, $b) {
1402
            $result = $a['order'] <=> $b['order'];
1403
            if (0 == $result) {
1404
                $result = strcasecmp($a['added_on'], $b['added_on']);
1405
                if (0 == $result) {
1406
                    $result = strcasecmp($a['name'], $b['name']);
1407
                }
1408
            }
1409
 
1410
            if ($result < 0) {
1411
                return 1;
1412
            } else if ($result > 0) {
1413
                return -1;
1414
            } else {
1415
                return 0;
1416
            }
1417
        });
1418
 
1419
        return $data;
1420
    }
1421
 
119 efrain 1422
    public function capsulesAction()
1423
    {
1424
        $request = $this->getRequest();
1425
        if($request->isGet()) {
580 stevensc 1426
            $currentUserPlugin = $this->plugin('currentUserPlugin');
1427
            $currentUser = $currentUserPlugin->getUser();
584 stevensc 1428
 
1429
            $topic_id_param = $this->params()->fromRoute('topic_id');
283 www 1430
            $topicMapper = MicrolearningTopicMapper::getInstance($this->adapter);
580 stevensc 1431
            $topic = $topicMapper->fetchOneByUuid($topic_id_param);
584 stevensc 1432
 
119 efrain 1433
            if(!$topic) {
1434
                return new JsonModel([
1435
                    'success' => false,
1436
                    'data' => 'ERROR_TOPIC_NOT_FOUND'
1437
                ]);
1438
            }
584 stevensc 1439
 
580 stevensc 1440
            $accessGrantedIds = $this->getAccessGranted();
584 stevensc 1441
 
119 efrain 1442
            if(!in_array($topic->id, $accessGrantedIds->topics)) {
1443
                return new JsonModel([
1444
                    'success' => false,
1445
                    'data' => 'ERROR_YOU_DO_NOT_HAVE_ACCESS_TO_THIS_TOPIC'
1446
                ]);
1447
            }
584 stevensc 1448
 
333 www 1449
            $storage = Storage::getInstance($this->config, $this->adapter);
584 stevensc 1450
            // Use the _getCapsulesByTopic method to fetch capsules
1451
            $data = $this->_getCapsulesByTopic($topic, $storage);
580 stevensc 1452
 
584 stevensc 1453
            // The _getCapsulesByTopic method already returns capsules with the required data structure.
1454
            // We just need to sort them.
1455
 
580 stevensc 1456
            usort($data, function($a, $b) {
584 stevensc 1457
 
580 stevensc 1458
                $result =  $a['order'] <=> $b['order'];
1459
                if(0 == $result) {
1460
                    $result = strcasecmp($a['added_on'], $b['added_on']);
1461
                    if(0 == $result) {
1462
                        $result = strcasecmp($a['name'], $b['name']);
1463
                    }
1464
                }
584 stevensc 1465
 
580 stevensc 1466
                if($result < 0) {
1467
                    return 1;
1468
                } else if($result > 0) {
1469
                    return -1;
1470
                } else  {
1471
                    return  0;
1472
                }
1473
            });
584 stevensc 1474
 
1475
            return new JsonModel([
1476
                'success' => true,
1477
                'data' => $data
1478
            ]);
1479
 
119 efrain 1480
        } else {
1481
            return new JsonModel([
1482
                'success' => false,
1483
                'data' => 'ERROR_METHOD_NOT_ALLOWED'
1484
            ]);
1485
        }
1486
    }
1487
 
235 efrain 1488
    public function takeTestAction()
1489
    {
1490
        $request = $this->getRequest();
1491
        if($request->isPost()) {
1492
            $currentUserPlugin = $this->plugin('currentUserPlugin');
1493
            $currentUser = $currentUserPlugin->getUser();
1494
 
1495
            $slide_id = $this->params()->fromRoute('slide_id');
283 www 1496
            $slideMapper = MicrolearningSlideMapper::getInstance($this->adapter);
235 efrain 1497
            $slide = $slideMapper->fetchOneByUuid($slide_id);
1498
 
1499
            if(!$slide) {
1500
                return new JsonModel([
1501
                    'success' => false,
1502
                    'data' => 'ERROR_SLIDE_NOT_FOUND'
1503
                ]);
1504
            }
1505
 
283 www 1506
            if($slide->type != MicrolearningSlide::TYPE_QUIZ) {
235 efrain 1507
                return new JsonModel([
1508
                    'success' => false,
1509
                    'data' => 'ERROR_SLIDE_IS_NOT_QUIZ'
1510
                ]);
1511
            }
1512
 
1513
 
1514
 
283 www 1515
            $capsuleMapper = MicrolearningCapsuleMapper::getInstance($this->adapter);
235 efrain 1516
            $capsule = $capsuleMapper->fetchOne($slide->capsule_id);
1517
 
1518
            if(!$capsule) {
1519
                return new JsonModel([
1520
                    'success' => false,
1521
                    'data' => 'ERROR_CAPSULE_NOT_FOUND'
1522
                ]);
1523
            }
1524
 
1525
            $accessGrantedIds = $this->getAccessGranted();
1526
 
1527
            if(!in_array($capsule->id, $accessGrantedIds->capsules)) {
1528
                return new JsonModel([
1529
                    'success' => false,
1530
                    'data' => 'ERROR_YOU_DO_NOT_HAVE_ACCESS_TO_THIS_CAPSULE'
1531
                ]);
1532
            }
1533
 
283 www 1534
            $userLogMapper = MicrolearningUserLogMapper::getInstance($this->adapter);
235 efrain 1535
            $userLog = $userLogMapper->fetchOneTakeATestByUserIdAndSlideId($currentUser->id, $slide->id);
1536
 
1537
            if($userLog) {
283 www 1538
                $activity = MicrolearningUserLog::ACTIVITY_RETAKE_A_TEST;
235 efrain 1539
            } else {
283 www 1540
                $activity = MicrolearningUserLog::ACTIVITY_TAKE_A_TEST;
235 efrain 1541
            }
1542
 
1543
            $added_on = $userLogMapper->getDatebaseNow();
1544
 
283 www 1545
            $userLog = new MicrolearningUserLog();
235 efrain 1546
            $userLog->activity      = $activity;
1547
            $userLog->user_id       = $currentUser->id;
1548
            $userLog->company_id    = $slide->company_id;
1549
            $userLog->topic_id      = $slide->topic_id;
1550
            $userLog->capsule_id    = $slide->capsule_id;
1551
            $userLog->slide_id      = $slide->id;
1552
            $userLog->added_on      = $added_on;
1553
 
1554
            if($userLogMapper->insert($userLog)) {
1555
                return new JsonModel([
1556
                    'success' => true,
1557
                ]);
1558
            } else {
1559
                return new JsonModel([
1560
                    'success' => false,
1561
                    'data' => $userLogMapper->getError()
1562
                ]);
1563
            }
1564
 
1565
 
1566
 
1567
 
1568
 
1569
 
1570
 
1571
        } else {
1572
            return new JsonModel([
1573
                'success' => false,
1574
                'data' => 'ERROR_METHOD_NOT_ALLOWED'
1575
            ]);
1576
        }
1577
    }
1578
 
161 efrain 1579
    public function getCapsuleAction()
1580
    {
1581
        $request = $this->getRequest();
587 stevensc 1582
 
161 efrain 1583
        if($request->isGet()) {
1584
            $currentUserPlugin = $this->plugin('currentUserPlugin');
1585
            $currentUser = $currentUserPlugin->getUser();
1586
 
558 stevensc 1587
            $capsule_uuid = $this->params()->fromRoute('id');
283 www 1588
            $capsuleMapper = MicrolearningCapsuleMapper::getInstance($this->adapter);
558 stevensc 1589
            $capsule = $capsuleMapper->fetchOneByUuid($capsule_uuid);
161 efrain 1590
 
1591
            if(!$capsule) {
1592
                return new JsonModel([
1593
                    'success' => false,
1594
                    'data' => 'ERROR_CAPSULE_NOT_FOUND'
1595
                ]);
1596
            }
1597
 
1598
            $accessGrantedIds = $this->getAccessGranted();
1599
 
1600
            if(!in_array($capsule->id, $accessGrantedIds->capsules)) {
1601
                return new JsonModel([
1602
                    'success' => false,
1603
                    'data' => 'ERROR_YOU_DO_NOT_HAVE_ACCESS_TO_THIS_CAPSULE'
1604
                ]);
1605
            }
1606
 
283 www 1607
            $userProgressMapper = MicrolearningUserProgressMapper::getInstance($this->adapter);
1608
            $capsuleCommentMapper = MicrolearningCapsuleCommentMapper::getInstance($this->adapter);
161 efrain 1609
 
1610
            $userProgress = $userProgressMapper->fetchOneByUseridAndCapsuleId($currentUser->id, $capsule->id);
587 stevensc 1611
            $progress = $userProgress->progress ?? 0;
1612
            $completed = $userProgress->completed ?? 0;
244 efrain 1613
 
586 stevensc 1614
            $dataCountAndRatingAverage = $capsuleCommentMapper->fetchCountAndRatingAverage($capsule->company_id, $capsule->id);
244 efrain 1615
 
587 stevensc 1616
            // Get comments data
1617
            $userMapper = UserMapper::getInstance($this->adapter);
333 www 1618
            $storage = Storage::getInstance($this->config, $this->adapter);
587 stevensc 1619
            $serviceDatetimeFormat = $this->config['leaderslinked.services.datetime'];
1620
 
1621
            $comments = [];
1622
            $records = $capsuleCommentMapper->fetchAllByCapsuleId($capsule->id);
1623
            foreach($records as $record) {
1624
                $user = $userMapper->fetchOne($record->user_id);
1625
                if(!$user) {
1626
                    continue;
1627
                }
1628
 
1629
                $dt = \DateTime::createFromFormat('Y-m-d H:i:s', $record->added_on);
1630
 
1631
                array_push($comments, [
597 stevensc 1632
                    'uuid' => $record->uuid,
587 stevensc 1633
                    'date' => $dt->format($serviceDatetimeFormat),
1634
                    'image' => $storage->getUserImage($user),
1635
                    'fullname' => trim(trim($user->first_name) . ' ' . trim($user->last_name)),
1636
                    'rating' => strval($record->rating),
1637
                    'comment' => $record->comment,
597 stevensc 1638
                    'link_delete' => $record->user_id == $currentUser->id ? $this->url()->fromRoute('microlearning/capsules-comments/delete', ['capsule_id' => $capsule->uuid, 'comment_id' => $record->uuid], ['force_canonical' => true]) : ''
587 stevensc 1639
                ]);
1640
            }
1641
 
1642
            $storage = Storage::getInstance($this->config, $this->adapter);
283 www 1643
            $path = $storage->getPathMicrolearningCapsule();
244 efrain 1644
 
586 stevensc 1645
            $slides = $this->_getSlidesByCapsule($capsule, $storage);
1646
 
161 efrain 1647
            $data = [
586 stevensc 1648
                'uuid'              => $capsule->uuid,
1649
                'name'              => $capsule->name ? $capsule->name : '',
1650
                'description'       => $capsule->description ? $capsule->description : '',
1651
                'image'             => $capsule->image ? $storage->getGenericImage($path, $capsule->uuid, $capsule->image) : '',
1652
                'link_comment_add'  => $this->url()->fromRoute('microlearning/capsules-comments/add', ['capsule_id' => $capsule->uuid], ['force_canonical' => true]),
1653
                'total_comments'    => strval($dataCountAndRatingAverage['total_comments']),
1654
                'total_rating'      => strval($dataCountAndRatingAverage['total_rating']),
587 stevensc 1655
                'comments'          => $comments,
586 stevensc 1656
                'progress'          => $progress,
1657
                'completed'         => $completed,
1658
                'total_slides'      => count($slides),
1659
                'slides'            => $slides,
1660
                'order'             => $capsule->order,
1661
                'added_on'          => $capsule->added_on,
1662
                'updated_on'        => $capsule->updated_on,
161 efrain 1663
            ];
586 stevensc 1664
 
161 efrain 1665
            return new JsonModel([
1666
                'success' => true,
1667
                'data' => $data
1668
            ]);
1669
        }
586 stevensc 1670
 
1671
        return new JsonModel([
1672
            'success' => false,
1673
            'data' => 'ERROR_METHOD_NOT_ALLOWED'
1674
        ]);
161 efrain 1675
    }
1676
 
119 efrain 1677
    public function slidesAction()
1678
    {
1679
        $request = $this->getRequest();
1680
        if($request->isGet()) {
1681
            $currentUserPlugin = $this->plugin('currentUserPlugin');
1682
            $currentUser = $currentUserPlugin->getUser();
1683
 
1684
 
1685
 
1686
            $topic_id = $this->params()->fromRoute('topic_id');
283 www 1687
            $topicMapper = MicrolearningTopicMapper::getInstance($this->adapter);
119 efrain 1688
            $topic = $topicMapper->fetchOneByUuid($topic_id);
1689
 
1690
            if(!$topic) {
1691
                return new JsonModel([
1692
                    'success' => false,
1693
                    'data' => 'ERROR_TOPIC_NOT_FOUND'
1694
                ]);
1695
            }
1696
 
1697
            $accessGrantedIds = $this->getAccessGranted();
1698
 
1699
            if(!in_array($topic->id, $accessGrantedIds->topics)) {
1700
                return new JsonModel([
1701
                    'success' => false,
1702
                    'data' => 'ERROR_YOU_DO_NOT_HAVE_ACCESS_TO_THIS_TOPIC'
1703
                ]);
1704
            }
1705
 
1706
            $capsule_id = $this->params()->fromRoute('capsule_id');
283 www 1707
            $capsuleMapper = MicrolearningCapsuleMapper::getInstance($this->adapter);
119 efrain 1708
            $capsule = $capsuleMapper->fetchOneByUuid($capsule_id);
1709
 
1710
            if(!$capsule) {
1711
                return new JsonModel([
1712
                    'success' => false,
1713
                    'data' => 'ERROR_CAPSULE_NOT_FOUND'
1714
                ]);
1715
            }
1716
 
1717
 
1718
 
1719
            if(!in_array($capsule->id, $accessGrantedIds->capsules)) {
1720
                return new JsonModel([
1721
                    'success' => false,
1722
                    'data' => 'ERROR_YOU_DO_NOT_HAVE_ACCESS_TO_THIS_CAPSULE'
1723
                ]);
1724
            }
1725
 
1726
 
1727
 
1728
            $data = [];
1729
 
283 www 1730
            $quizMapper = MicrolearningQuizMapper::getInstance($this->adapter);
119 efrain 1731
 
283 www 1732
            $slideMapper = MicrolearningSlideMapper::getInstance($this->adapter);
1733
            $userProgressMapper = MicrolearningUserProgressMapper::getInstance($this->adapter);
119 efrain 1734
 
333 www 1735
            $storage = Storage::getInstance($this->config, $this->adapter);
283 www 1736
            $path = $storage->getPathMicrolearningSlide();
119 efrain 1737
 
1738
            $slides = $slideMapper->fetchAllByCompanyIdAndTopicIdAndCapsuleId($capsule->company_id, $capsule->topic_id, $capsule->id);
1739
            foreach($slides as $slide)
1740
            {
1741
 
1742
 
1743
                $userProgress = $userProgressMapper->fetchOneByUserIdAndSlideId($currentUser->id, $slide->id);
1744
                if($userProgress) {
224 efrain 1745
                    $completed =  $userProgress->completed ;
119 efrain 1746
                } else {
1747
                    $completed = 0;
1748
                }
1749
 
235 efrain 1750
 
230 efrain 1751
 
235 efrain 1752
                $link_take_a_test = '';
230 efrain 1753
                if($slide->quiz_id) {
235 efrain 1754
 
283 www 1755
                    $quizMapper = MicrolearningQuizMapper::getInstance($this->adapter);
230 efrain 1756
                    $quiz = $quizMapper->fetchOne($slide->quiz_id);
1757
                    if($quiz) {
1758
                        $quiz_uuid = $quiz->uuid;
235 efrain 1759
                        $quiz_data = $this->getQuiz($slide->quiz_id);
1760
                        $link_take_a_test = $this->url()->fromRoute('microlearning/take-a-test', ['slide_id' => $slide->uuid], ['force_canonical' => true]);
230 efrain 1761
                    }
235 efrain 1762
 
1763
                }
119 efrain 1764
 
1765
 
1766
                array_push($data, [
235 efrain 1767
                    'quiz'                  => $quiz_uuid,
1768
                    'quiz_data'             => $quiz_data,
1769
                    'uuid'                  => $slide->uuid,
1770
                    'name'                  => $slide->name ? $slide->name : '',
1771
                    'description'           => $slide->description ? $slide->description : '',
1772
                    'type'                  => $slide->type,
283 www 1773
                    'background'            => $slide->background ? $storage->getGenericImage($path, $slide->uuid, $slide->background) : '',
1774
                    'file'                  => $slide->file ? $storage->getGenericFile($path, $slide->uuid, $slide->file) : '',
235 efrain 1775
                    'order'                 => $slide->order,
1776
                    'completed'             => $completed,
236 efrain 1777
                    'link_take_a_test'      => $link_take_a_test,
235 efrain 1778
                    'added_on'              => $slide->added_on,
1779
                    'updated_on'            => $slide->updated_on,
119 efrain 1780
                ]);
1781
 
1782
 
1783
 
1784
            }
1785
 
1786
            usort($data, function($a, $b) {
1787
 
1788
                $result =  $a['order'] <=> $b['order'];
1789
                if(0 == $result) {
1790
                    $result = strcasecmp($a['added_on'], $b['added_on']);
1791
                    if(0 == $result) {
1792
                        $result = strcasecmp($a['name'], $b['name']);
1793
                    }
1794
                }
1795
 
1796
                if($result < 0) {
1797
                    return 1;
1798
                } else if($result > 0) {
1799
                    return -1;
1800
                } else  {
1801
                    return  0;
1802
                }
1803
            });
1804
 
1805
 
1806
 
1807
                return new JsonModel([
1808
                    'success' => true,
1809
                    'data' => $data
1810
                ]);
1811
 
1812
        } else {
1813
            return new JsonModel([
1814
                'success' => false,
1815
                'data' => 'ERROR_METHOD_NOT_ALLOWED'
1816
            ]);
1817
        }
1818
    }
1819
 
229 efrain 1820
    private function getQuiz($id)
1821
    {
1822
        $serviceDatetimeFormat = $this->config['leaderslinked.services.datetime'];
1823
 
1824
        $data = [];
1825
 
283 www 1826
        $quizMapper = MicrolearningQuizMapper::getInstance($this->adapter);
229 efrain 1827
        $quiz = $quizMapper->fetchOne($id);
1828
 
1829
        if(!$quiz) {
1830
            return [];
1831
        }
1832
 
1833
        $companyMapper = CompanyMapper::getInstance($this->adapter);
1834
        $company = $companyMapper->fetchOne($quiz->company_id);
1835
 
283 www 1836
        $questionMapper = MicrolearningQuestionMapper::getInstance($this->adapter);
1837
        $answerMapper = MicrolearningAnswerMapper::getInstance($this->adapter);
229 efrain 1838
 
1839
        $record_questions = [];
1840
        $questions = $questionMapper->fetchAllByQuizId($quiz->id);
1841
        foreach($questions as $question)
1842
        {
1843
            $record_answers = [];
1844
 
1845
            $answers = $answerMapper->fetchAllByQuizIdAndQuestionId($question->quiz_id, $question->id);
1846
            foreach($answers as $answer)
1847
            {
1848
                $dtAddedOn = \DateTime::createFromFormat('Y-m-d H:i:s', $answer->added_on);
1849
                $dtUpdatedOn = \DateTime::createFromFormat('Y-m-d H:i:s', $answer->updated_on);
1850
 
1851
                array_push($record_answers, [
1852
                    'uuid' => $answer->uuid,
1853
                    'text' => trim($answer->text),
1854
                    'correct' => $answer->correct ? $answer->correct  : 0 ,
1855
                    'points' => strval(intval($answer->points, 10)),
1856
                    'added_on'  => $dtAddedOn->format($serviceDatetimeFormat),
1857
                    'updated_on'    => $dtUpdatedOn->format($serviceDatetimeFormat),
1858
                ]);
1859
            }
1860
 
1861
            $dtAddedOn = \DateTime::createFromFormat('Y-m-d H:i:s', $question->added_on);
1862
            $dtUpdatedOn = \DateTime::createFromFormat('Y-m-d H:i:s', $question->updated_on);
1863
 
1864
            array_push($record_questions, [
1865
                'uuid'          => $question->uuid,
1866
                'text'          => trim($question->text),
1867
                'type'          => $question->type,
1868
                'maxlength'     => strval($question->maxlength),
1869
                'points'        => strval($question->points),
1870
                'answers'       => $record_answers,
1871
                'added_on'      => $dtAddedOn->format($serviceDatetimeFormat),
1872
                'updated_on'    => $dtUpdatedOn->format($serviceDatetimeFormat),
1873
            ]);
1874
        }
1875
 
1876
        $dtAddedOn = \DateTime::createFromFormat('Y-m-d H:i:s', $quiz->added_on);
1877
        $dtUpdatedOn = \DateTime::createFromFormat('Y-m-d H:i:s', $quiz->updated_on);
1878
 
1879
        array_push($data, [
1880
            'uuid' => $quiz->uuid,
1881
            'name' => $quiz->name,
1882
            'text' => trim($quiz->text ? $quiz->text : ''),
1883
            'failed' => trim($quiz->failed ? $quiz->failed : ''),
1884
            'points' => strval($quiz->points),
1885
            'minimum_points_required' => strval($quiz->minimum_points_required),
1886
            'max_time' => $quiz->max_time ? $quiz->max_time : 5,
1887
            'company_uuid' => $company->uuid,
1888
            'company_name' => $company->name,
1889
            'company_image' => $this->url()->fromRoute('services/storage',['type' => 'company', 'code' => $company->uuid, 'filename' => $company->image], ['force_canonical' => true]),
1890
            'questions'     => $record_questions,
1891
            'added_on'      => $dtAddedOn->format($serviceDatetimeFormat),
1892
            'updated_on'    => $dtUpdatedOn->format($serviceDatetimeFormat),
1893
        ]);
1894
 
1895
        return $data;
1896
 
1897
    }
161 efrain 1898
 
229 efrain 1899
 
161 efrain 1900
    public function getSlideAction()
1901
    {
1902
        $request = $this->getRequest();
1903
        if($request->isGet()) {
1904
            $currentUserPlugin = $this->plugin('currentUserPlugin');
1905
            $currentUser = $currentUserPlugin->getUser();
1906
 
1907
            $id = $this->params()->fromRoute('id');
283 www 1908
            $slideMapper = MicrolearningSlideMapper::getInstance($this->adapter);
161 efrain 1909
            $slide = $slideMapper->fetchOneByUuid($id);
1910
 
1911
            if(!$slide) {
1912
                return new JsonModel([
1913
                    'success' => false,
1914
                    'data' => 'ERROR_SLIDE_NOT_FOUND'
1915
                ]);
1916
            }
1917
 
1918
            $accessGrantedIds = $this->getAccessGranted();
1919
 
1920
 
1921
 
1922
            if(!in_array($slide->capsule_id, $accessGrantedIds->capsules)) {
1923
                return new JsonModel([
1924
                    'success' => false,
1925
                    'data' => 'ERROR_YOU_DO_NOT_HAVE_ACCESS_TO_THIS_CAPSULE'
1926
                ]);
1927
            }
1928
 
283 www 1929
            $slideMapper = MicrolearningSlideMapper::getInstance($this->adapter);
1930
            $userProgressMapper = MicrolearningUserProgressMapper::getInstance($this->adapter);
161 efrain 1931
 
1932
            $userProgress = $userProgressMapper->fetchOneByUserIdAndSlideId($currentUser->id, $slide->id);
1933
            if($userProgress) {
1934
                $completed = $userProgress->completed;
1935
            } else {
1936
                $completed = 0;
1937
            }
235 efrain 1938
 
1939
            $quiz_uuid = '';
1940
            $quiz_data = [];
1941
            $link_take_a_test = '';
1942
            if($slide->quiz_id) {
1943
 
283 www 1944
                $quizMapper = MicrolearningQuizMapper::getInstance($this->adapter);
235 efrain 1945
                $quiz = $quizMapper->fetchOne($slide->quiz_id);
1946
                if($quiz) {
1947
                    $quiz_uuid = $quiz->uuid;
1948
                    $quiz_data = $this->getQuiz($slide->quiz_id);
1949
                    $link_take_a_test = $this->url()->fromRoute('microlearning/take-a-test', ['slide_id' => $slide->uuid], ['force_canonical' => true]);
1950
                }
161 efrain 1951
 
235 efrain 1952
            }
161 efrain 1953
 
333 www 1954
            $storage = Storage::getInstance($this->config, $this->adapter);
283 www 1955
            $path = $storage->getPathMicrolearningSlide();
618 stevensc 1956
 
1957
            $image = $storage->getGenericImage($path, $slide->uuid, $slide->background);
1958
            $file = $storage->getGenericFile($path, $slide->uuid, $slide->file);
161 efrain 1959
 
1960
            $data =[
235 efrain 1961
                'quiz'              => $quiz_uuid,
1962
                'quiz_data'         => $quiz_data,
1963
                'uuid'              => $slide->uuid,
1964
                'name'              => $slide->name ? $slide->name : '',
1965
                'description'       => $slide->description ? $slide->description : '',
1966
                'type'              => $slide->type,
618 stevensc 1967
                'background'        => $image,
1968
                'file'              => $file,
235 efrain 1969
                'order'             => $slide->order,
1970
                'completed'         => $completed,
1971
                'link_take_a_test'  => $link_take_a_test,
1972
                'added_on'          => $slide->added_on,
1973
                'updated_on'        => $slide->updated_on,
161 efrain 1974
            ];
1975
 
1976
            return new JsonModel([
1977
                'success' => true,
1978
                'data' => $data
1979
            ]);
1980
 
1981
        } else {
1982
            return new JsonModel([
1983
                'success' => false,
1984
                'data' => 'ERROR_METHOD_NOT_ALLOWED'
1985
            ]);
1986
        }
1987
    }
1988
 
119 efrain 1989
    public function profileAction()
1990
    {
1991
        $request = $this->getRequest();
1992
        if($request->isGet()) {
1993
            $currentUserPlugin = $this->plugin('currentUserPlugin');
1994
            $currentUser = $currentUserPlugin->getUser();
1995
 
1996
 
1997
            $accessGrantedIds = $this->getAccessGranted();
1998
 
1999
            $companyMapper = CompanyMapper::getInstance($this->adapter);
283 www 2000
            $companyExtendUserMapper = MicrolearningExtendUserMapper::getInstance($this->adapter);
2001
            $companyExtendUserCompanyMapper = MicrolearningExtendUserCompanyMapper::getInstance($this->adapter);
2002
            $companyExtendUserFunctionMapper = MicrolearningExtendUserFunctionMapper::getInstance($this->adapter);
2003
            $companyExtendUserGroupMapper = MicrolearningExtendUserGroupMapper::getInstance($this->adapter);
2004
            $companyExtendUserInstitutionMapper = MicrolearningExtendUserInstitutionMapper::getInstance($this->adapter);
2005
            $companyExtendUserPartnerMapper = MicrolearningExtendUserPartnerMapper::getInstance($this->adapter);
2006
            $companyExtendUserProgramMapper = MicrolearningExtendUserProgramMapper::getInstance($this->adapter);
2007
            $companyExtendUserStudentTypeMapper = MicrolearningExtendUserStudentTypeMapper::getInstance($this->adapter);
2008
            $companyExtendUserSectorMapper = MicrolearningExtendUserSectorMapper::getInstance($this->adapter);
119 efrain 2009
 
333 www 2010
            $storage = Storage::getInstance($this->config, $this->adapter);
283 www 2011
 
119 efrain 2012
 
2013
            $data = [];
2014
            foreach($accessGrantedIds->companies as $company_id)
2015
            {
2016
                $company = $companyMapper->fetchOne($company_id);
2017
                if(!$company) {
2018
                    continue;
2019
                }
2020
 
2021
                $record = [
2022
                    'name' => $company->name,
283 www 2023
                    'image' => $storage->getCompanyImage($company),
119 efrain 2024
                    'details' => [],
2025
                ];
2026
 
2027
                $companyExtendUser = $companyExtendUserMapper->fetchOneByCompanyIdAndUserId($company->id, $currentUser->id);
2028
                if(!$companyExtendUser) {
2029
                    continue;
2030
                }
2031
 
2032
                if($companyExtendUser->extend_company_id) {
2033
 
2034
                    $extendedCompany = $companyExtendUserCompanyMapper->fetchOne($companyExtendUser->company_id);
2035
                    if($extendedCompany) {
2036
                        array_push($record['details'],[
2037
                            'uuid' => $extendedCompany->uuid,
2038
                            'label' => 'LABEL_COMPANY',
2039
                            'value' => $extendedCompany->name
2040
                        ]);
2041
                    }
2042
                }
2043
 
2044
                if($companyExtendUser->extend_function_id) {
2045
                    $extendedFunction = $companyExtendUserFunctionMapper->fetchOne($companyExtendUser->extend_function_id);
2046
                    if($extendedFunction) {
2047
                        array_push($record['details'],[
2048
                            'uuid' => $extendedFunction->uuid,
2049
                            'label' => 'LABEL_FUNCTION',
2050
                            'value' => $extendedFunction->name
2051
                        ]);
2052
                    }
2053
                }
2054
 
2055
                if($companyExtendUser->extend_group_id) {
2056
                    $extendedGroup = $companyExtendUserGroupMapper->fetchOne($companyExtendUser->extend_group_id);
2057
                    if($extendedGroup) {
2058
                        array_push($record['details'],[
2059
                            'uuid' => $extendedGroup->uuid,
2060
                            'label' => 'LABEL_GROUP',
2061
                            'value' => $extendedGroup->name
2062
                        ]);
2063
                    }
2064
                }
2065
 
2066
                if($companyExtendUser->extend_institution_id) {
2067
                    $extendedInstitution= $companyExtendUserInstitutionMapper->fetchOne($companyExtendUser->extend_institution_id);
2068
                    if($extendedInstitution) {
2069
                        array_push($record['details'],[
2070
                            'uuid' => $extendedInstitution->uuid,
2071
                            'label' => 'LABEL_INSTITUTION',
2072
                            'value' => $extendedInstitution->name
2073
                        ]);
2074
                    }
2075
                }
2076
 
2077
                if($companyExtendUser->extend_program_id) {
2078
                    $extendedProgram = $companyExtendUserProgramMapper->fetchOne($companyExtendUser->extend_program_id);
2079
                    if($extendedProgram) {
2080
                        array_push($record['details'],[
2081
                            'uuid' => $extendedProgram->uuid,
2082
                            'label' => 'LABEL_PROGRAM',
2083
                            'value' => $extendedProgram->name
2084
                        ]);
2085
 
2086
                    }
2087
                }
2088
 
2089
                if($companyExtendUser->extend_sector_id) {
2090
                    $extendedSector = $companyExtendUserSectorMapper->fetchOne($companyExtendUser->extend_sector_id);
2091
                    if($extendedSector) {
2092
                        array_push($record['details'],[
2093
                            'uuid' => $extendedSector->uuid,
2094
                            'label' => 'LABEL_SECTOR',
2095
                            'value' => $extendedSector->name
2096
                        ]);
2097
                    }
2098
                }
2099
 
2100
                if($companyExtendUser->extend_partner_id) {
2101
                    $extendedPartner = $companyExtendUserPartnerMapper->fetchOne($companyExtendUser->extend_partner_id);
2102
                    if($extendedPartner) {
2103
                        array_push($record['details'],[
2104
                            'uuid' => $extendedPartner->uuid,
2105
                            'label' => 'LABEL_PARTNER',
2106
                            'value' => $extendedPartner->name
2107
                        ]);
2108
                    }
2109
                }
2110
 
2111
                if($companyExtendUser->extend_student_type_id) {
2112
                    $extendedStudentType = $companyExtendUserStudentTypeMapper->fetchOne($companyExtendUser->extend_student_type_id);
2113
                    if($extendedStudentType) {
2114
                        array_push($record['details'],[
2115
                            'uuid' => $extendedStudentType->uuid,
2116
                            'label' => 'LABEL_TYPE',
2117
                            'value' => $extendedStudentType->name
2118
                        ]);
2119
                    }
2120
                }
2121
 
2122
                array_push($data, $record);
2123
            }
2124
 
2125
            return new JsonModel([
2126
                'success' => true,
2127
                'data' => $data
2128
            ]);
2129
 
2130
        } else {
2131
            return new JsonModel([
2132
                'success' => false,
2133
                'data' => 'ERROR_METHOD_NOT_ALLOWED'
2134
            ]);
2135
        }
2136
    }
590 stevensc 2137
 
2138
    /**
2139
     *
2140
     * @return \Laminas\View\Model\JsonModel
2141
     */
167 efrain 2142
    public function syncAction()
2143
    {
2144
        $request = $this->getRequest();
590 stevensc 2145
        if (!$request->isPost()) {
2146
            return new JsonModel(['success' => false, 'data' => 'ERROR_INVALID_REQUEST']);
2147
        }
167 efrain 2148
 
590 stevensc 2149
        $slide_uuid = $this->params()->fromRoute('slide_uuid');
2150
        $topic_uuid = $this->params()->fromRoute('topic_uuid');
283 www 2151
 
590 stevensc 2152
        if (empty($slide_uuid) || empty($topic_uuid)) {
2153
            return new JsonModel(['success' => false, 'data' => 'ERROR_MISSING_PARAMETERS']);
167 efrain 2154
        }
590 stevensc 2155
 
2156
        $currentUser = $this->plugin('currentUserPlugin')->getUser();
2157
        $user_id = $currentUser->id ?? null;
2158
        if (!$user_id) {
2159
            return new JsonModel(['success' => false, 'data' => 'ERROR_USER_NOT_FOUND']);
2160
        }
2161
 
2162
        $accessGrantedIds = $this->getAccessGranted();
2163
 
2164
        // Obtener Slide
2165
        $slideMapper = MicrolearningSlideMapper::getInstance($this->adapter);
2166
        $slide = $slideMapper->fetchOneByUuid($slide_uuid);
2167
        if (!$slide) {
2168
            return new JsonModel(['success' => false, 'data' => 'ERROR_SLIDE_NOT_FOUND']);
2169
        }
2170
 
2171
        // Obtener Cápsula
2172
        $capsuleMapper = MicrolearningCapsuleMapper::getInstance($this->adapter);
2173
        $capsule = $capsuleMapper->fetchById($slide->capsule_id);
2174
        if (!$capsule || !in_array($capsule->id, $accessGrantedIds->capsules)) {
2175
            return new JsonModel(['success' => false, 'data' => 'ERROR_CAPSULE_ACCESS_DENIED']);
2176
        }
2177
 
2178
        // Obtener Tópico
2179
        $topicMapper = MicrolearningTopicMapper::getInstance($this->adapter);
2180
        $topic = $topicMapper->fetchOneByUuid($topic_uuid);
2181
        if (!$topic || !in_array($topic->id, $accessGrantedIds->topics)) {
2182
            return new JsonModel(['success' => false, 'data' => 'ERROR_TOPIC_ACCESS_DENIED']);
2183
        }
2184
 
2185
        // Validar que la cápsula pertenece al tópico
2186
        $topicCapsuleMapper = MicrolearningTopicCapsuleMapper::getInstance($this->adapter);
2187
        $relation = $topicCapsuleMapper->fetchOneByTopicIdAndCapsuleId($topic->id, $capsule->id);
2188
        if (!$relation) {
2189
            return new JsonModel(['success' => false, 'data' => 'ERROR_CAPSULE_DOES_NOT_BELONG_TO_TOPIC']);
2190
        }
2191
 
2192
        // Marcar slide como visto
2193
        $progressMapper = MicrolearningUserProgressMapper::getInstance($this->adapter);
2194
        $progressMapper->markSlideViewed($user_id, $topic->id, $capsule->id, $slide->id);
2195
 
2196
        $data = 'LABEL_THE_USER_PROGRESS_FOR_THIS_SLIDE_HAS_BEEN_COMPLETED';
2197
 
2198
        // Si vio todos los slides → marcar cápsula como completada
2199
        if ($progressMapper->hasViewedAllSlidesInCapsule($user_id, $capsule->id)) {
2200
            $progressMapper->markCapsuleCompleted($user_id, $topic->id, $capsule->id);
2201
            $data = 'LABEL_THE_USER_PROGRESS_FOR_THIS_CAPSULE_HAS_BEEN_COMPLETED';
2202
        }
2203
 
2204
        // Si completó todas las cápsulas del tópico → marcar tópico como completado
2205
        if ($progressMapper->hasCompletedAllCapsulesInTopic($user_id, $topic->id)) {
2206
            $progressMapper->markTopicCompleted($user_id, $topic->id);
2207
            $data = 'LABEL_THE_USER_PROGRESS_FOR_THIS_TOPIC_HAS_BEEN_COMPLETED';
2208
        }
2209
 
2210
        return new JsonModel(['success' => true, 'data' => $data]);
2211
    }
167 efrain 2212
 
119 efrain 2213
    /**
2214
     *
2215
     * @return \LeadersLinked\Controller\MicrolearningUserAccessGrantedIds
2216
     */
2217
    private function getAccessGranted()
2218
    {
2219
        $currentUserPlugin = $this->plugin('currentUserPlugin');
2220
        $currentUser = $currentUserPlugin->getUser();
2221
 
626 stevensc 2222
        $topicUserMapper = MicrolearningTopicUserMapper::getInstance($this->adapter);
2223
        $now = $topicUserMapper->getDatebaseNow();
119 efrain 2224
 
626 stevensc 2225
        $records = $topicUserMapper->fetchAllActiveByUserId($currentUser->id);
119 efrain 2226
 
2227
        $accessGrantedIds = new MicrolearningUserAccessGrantedIds();
2228
 
2229
        foreach($records as $record)
2230
        {
626 stevensc 2231
            if($record->access != MicrolearningTopicUser::ACCESS_UNLIMITED && $record->access != MicrolearningTopicUser::ACCESS_PAY_PERIOD) {
119 efrain 2232
                continue;
2233
            }
626 stevensc 2234
            if($record->access == MicrolearningTopicUser::ACCESS_PAY_PERIOD) {
119 efrain 2235
                if($now < $record->paid_from || $now > $record->paid_to) {
2236
                    continue;
2237
                }
2238
            }
626 stevensc 2239
 
2240
            // Verificar si la empresa está en la lista de empresas permitidas
119 efrain 2241
            if(!in_array($record->company_id, $accessGrantedIds->companies )) {
2242
                array_push($accessGrantedIds->companies, $record->company_id);
2243
            }
2244
 
626 stevensc 2245
            // Verificar si el tópico está en la lista de tópicos permitidos
119 efrain 2246
            if(!in_array($record->topic_id, $accessGrantedIds->topics )) {
2247
                array_push( $accessGrantedIds->topics, $record->topic_id);
2248
            }
2249
        }
2250
 
2251
        return $accessGrantedIds;
2252
    }
2253
 
590 stevensc 2254
    /**
2255
     * Marks a slide as completed and cascades completion status to capsule and topic if needed
2256
     *
2257
     * @return \Laminas\View\Model\JsonModel
2258
     */
2259
    public function completeSlideAction()
2260
    {
2261
        $request = $this->getRequest();
2262
        if($request->isPost()) {
2263
            $currentUserPlugin = $this->plugin('currentUserPlugin');
2264
            $currentUser = $currentUserPlugin->getUser();
2265
 
2266
            $slide_uuid = $this->params()->fromRoute('slide_uuid');
2267
            $topic_uuid = $this->params()->fromRoute('topic_uuid');
2268
            $capsule_uuid = $this->params()->fromRoute('capsule_uuid');
2269
 
2270
            if(empty($slide_uuid) || empty($topic_uuid) || empty($capsule_uuid)) {
2271
                return new JsonModel([
2272
                    'success' => false,
2273
                    'data' => 'ERROR_INVALID_PARAMETERS'
2274
                ]);
2275
            }
2276
 
2277
            // Get slide
2278
            $slideMapper = MicrolearningSlideMapper::getInstance($this->adapter);
2279
            $slide = $slideMapper->fetchOneByUuid($slide_uuid);
2280
 
2281
            if(!$slide) {
2282
                return new JsonModel([
2283
                    'success' => false,
2284
                    'data' => 'ERROR_SLIDE_NOT_FOUND'
2285
                ]);
2286
            }
2287
 
2288
            // Get capsule
2289
            $capsuleMapper = MicrolearningCapsuleMapper::getInstance($this->adapter);
2290
            $capsule = $capsuleMapper->fetchOneByUuid($capsule_uuid);
2291
 
2292
            if(!$capsule) {
2293
                return new JsonModel([
2294
                    'success' => false,
2295
                    'data' => 'ERROR_CAPSULE_NOT_FOUND'
2296
                ]);
2297
            }
2298
 
2299
            // Get topic
2300
            $topicMapper = MicrolearningTopicMapper::getInstance($this->adapter);
2301
            $topic = $topicMapper->fetchOneByUuid($topic_uuid);
2302
 
2303
            if(!$topic) {
2304
                return new JsonModel([
2305
                    'success' => false,
2306
                    'data' => 'ERROR_TOPIC_NOT_FOUND'
2307
                ]);
2308
            }
2309
 
2310
            // Update slide progress
2311
            $userProgressMapper = MicrolearningUserProgressMapper::getInstance($this->adapter);
2312
            $slideProgress = $userProgressMapper->fetchOneByUserIdAndSlideId($currentUser->id, $slide->id);
2313
            $updated_on = $userProgressMapper->getDatebaseNow();
2314
 
2315
            if(!$slideProgress) {
2316
                $slideProgress = new MicrolearningUserProgress();
2317
                $slideProgress->user_id = $currentUser->id;
2318
                $slideProgress->slide_id = $slide->id;
2319
                $slideProgress->topic_id = $topic->id;
2320
                $slideProgress->capsule_id = $capsule->id;
2321
            }
2322
 
2323
            $slideProgress->completed = 1;
2324
            $slideProgress->updated_on = $updated_on;
2325
 
2326
            if($userProgressMapper->update($slideProgress)) {
2327
                $closeCapsule = false;
2328
                $closeTopic = false;
2329
            }
2330
 
2331
            // Check if capsule is completed
2332
            $capsuleProgress = $userProgressMapper->fetchOneByUserIdAndCapsuleId($currentUser->id, $capsule->id);
2333
 
2334
            $capsuleProgress->total_slides = $slideMapper->fetchTotalCountByCompanyIdAndCapsuleId($capsule->company_id, $capsule->id);
2335
            $capsuleProgress->view_slides = $userProgressMapper->fetchCountAllSlideCompletedByUserIdAndCapsuleId($currentUser->id, $capsule->id);
2336
 
2337
            if($capsuleProgress->total_slides) {
2338
                $capsuleProgress->progress = ($capsuleProgress->view_slides * 100) / $capsuleProgress->total_slides;
2339
                $capsuleProgress->progress = $capsuleProgress->progress > 100 ? 100 : $capsuleProgress->progress;
2340
            }
2341
 
2342
            if(!$userProgressMapper->update($capsuleProgress)) {
2343
                return new JsonModel([
2344
                    'success' => false,
2345
                    'data' => $userProgressMapper->getError()
2346
                ]);
2347
            }
2348
 
2349
            if($capsuleProgress->progress >= 100) {
2350
                $closeCapsule = true;
2351
            }
2352
 
2353
            // Check if topic is completed
2354
            $topicProgress = $userProgressMapper->fetchOneByUserIdAndTopicId($currentUser->id, $topic->id);
2355
            if($topicProgress->completed) {
2356
                $closeTopic = true;
2357
            }
2358
 
2359
 
2360
            // Prepare response
2361
            $data = 'LABEL_THE_USER_PROGRESS_FOR_THIS_SLIDE_HAS_BEEN_COMPLETED';
2362
 
2363
            if($closeCapsule) {
2364
                $data = 'LABEL_THE_USER_PROGRESS_FOR_THIS_CAPSULE_HAS_BEEN_COMPLETED';
2365
            }
2366
 
2367
            if($closeTopic) {
2368
                $data = 'LABEL_THE_USER_PROGRESS_FOR_THIS_TOPIC_HAS_BEEN_COMPLETED';
2369
            }
2370
 
2371
            return new JsonModel([
2372
                'success' => true,
2373
                'data' => $data
2374
            ]);
2375
        }
2376
 
2377
        return new JsonModel([
2378
            'success' => false,
2379
            'data' => 'ERROR_METHOD_NOT_ALLOWED'
2380
        ]);
2381
    }
119 efrain 2382
}