Proyectos de Subversion LeadersLinked - Services

Rev

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