Proyectos de Subversion LeadersLinked - Services

Rev

Rev 590 | Rev 593 | 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, [
1699
                    'date' => $dt->format($serviceDatetimeFormat),
1700
                    'image' => $storage->getUserImage($user),
1701
                    'fullname' => trim(trim($user->first_name) . ' ' . trim($user->last_name)),
1702
                    'rating' => strval($record->rating),
1703
                    'comment' => $record->comment,
1704
                    '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]) : '',
1705
                ]);
1706
            }
1707
 
1708
            $storage = Storage::getInstance($this->config, $this->adapter);
283 www 1709
            $path = $storage->getPathMicrolearningCapsule();
244 efrain 1710
 
586 stevensc 1711
            $slides = $this->_getSlidesByCapsule($capsule, $storage);
1712
 
161 efrain 1713
            $data = [
586 stevensc 1714
                'uuid'              => $capsule->uuid,
1715
                'name'              => $capsule->name ? $capsule->name : '',
1716
                'description'       => $capsule->description ? $capsule->description : '',
1717
                'image'             => $capsule->image ? $storage->getGenericImage($path, $capsule->uuid, $capsule->image) : '',
1718
                'link_comment_add'  => $this->url()->fromRoute('microlearning/capsules-comments/add', ['capsule_id' => $capsule->uuid], ['force_canonical' => true]),
1719
                'total_comments'    => strval($dataCountAndRatingAverage['total_comments']),
1720
                'total_rating'      => strval($dataCountAndRatingAverage['total_rating']),
587 stevensc 1721
                'comments'          => $comments,
586 stevensc 1722
                'progress'          => $progress,
1723
                'completed'         => $completed,
1724
                'total_slides'      => count($slides),
1725
                'slides'            => $slides,
1726
                'order'             => $capsule->order,
1727
                'added_on'          => $capsule->added_on,
1728
                'updated_on'        => $capsule->updated_on,
161 efrain 1729
            ];
586 stevensc 1730
 
161 efrain 1731
            return new JsonModel([
1732
                'success' => true,
1733
                'data' => $data
1734
            ]);
1735
        }
586 stevensc 1736
 
1737
        return new JsonModel([
1738
            'success' => false,
1739
            'data' => 'ERROR_METHOD_NOT_ALLOWED'
1740
        ]);
161 efrain 1741
    }
1742
 
119 efrain 1743
    public function slidesAction()
1744
    {
1745
        $request = $this->getRequest();
1746
        if($request->isGet()) {
1747
            $currentUserPlugin = $this->plugin('currentUserPlugin');
1748
            $currentUser = $currentUserPlugin->getUser();
1749
 
1750
 
1751
 
1752
            $topic_id = $this->params()->fromRoute('topic_id');
283 www 1753
            $topicMapper = MicrolearningTopicMapper::getInstance($this->adapter);
119 efrain 1754
            $topic = $topicMapper->fetchOneByUuid($topic_id);
1755
 
1756
            if(!$topic) {
1757
                return new JsonModel([
1758
                    'success' => false,
1759
                    'data' => 'ERROR_TOPIC_NOT_FOUND'
1760
                ]);
1761
            }
1762
 
1763
            $accessGrantedIds = $this->getAccessGranted();
1764
 
1765
            if(!in_array($topic->id, $accessGrantedIds->topics)) {
1766
                return new JsonModel([
1767
                    'success' => false,
1768
                    'data' => 'ERROR_YOU_DO_NOT_HAVE_ACCESS_TO_THIS_TOPIC'
1769
                ]);
1770
            }
1771
 
1772
            $capsule_id = $this->params()->fromRoute('capsule_id');
283 www 1773
            $capsuleMapper = MicrolearningCapsuleMapper::getInstance($this->adapter);
119 efrain 1774
            $capsule = $capsuleMapper->fetchOneByUuid($capsule_id);
1775
 
1776
            if(!$capsule) {
1777
                return new JsonModel([
1778
                    'success' => false,
1779
                    'data' => 'ERROR_CAPSULE_NOT_FOUND'
1780
                ]);
1781
            }
1782
 
1783
 
1784
 
1785
            if(!in_array($capsule->id, $accessGrantedIds->capsules)) {
1786
                return new JsonModel([
1787
                    'success' => false,
1788
                    'data' => 'ERROR_YOU_DO_NOT_HAVE_ACCESS_TO_THIS_CAPSULE'
1789
                ]);
1790
            }
1791
 
1792
 
1793
 
1794
            $data = [];
1795
 
283 www 1796
            $quizMapper = MicrolearningQuizMapper::getInstance($this->adapter);
119 efrain 1797
 
283 www 1798
            $slideMapper = MicrolearningSlideMapper::getInstance($this->adapter);
1799
            $userProgressMapper = MicrolearningUserProgressMapper::getInstance($this->adapter);
119 efrain 1800
 
333 www 1801
            $storage = Storage::getInstance($this->config, $this->adapter);
283 www 1802
            $path = $storage->getPathMicrolearningSlide();
119 efrain 1803
 
1804
            $slides = $slideMapper->fetchAllByCompanyIdAndTopicIdAndCapsuleId($capsule->company_id, $capsule->topic_id, $capsule->id);
1805
            foreach($slides as $slide)
1806
            {
1807
 
1808
 
1809
                $userProgress = $userProgressMapper->fetchOneByUserIdAndSlideId($currentUser->id, $slide->id);
1810
                if($userProgress) {
224 efrain 1811
                    $completed =  $userProgress->completed ;
119 efrain 1812
                } else {
1813
                    $completed = 0;
1814
                }
1815
 
235 efrain 1816
 
230 efrain 1817
 
235 efrain 1818
                $link_take_a_test = '';
230 efrain 1819
                if($slide->quiz_id) {
235 efrain 1820
 
283 www 1821
                    $quizMapper = MicrolearningQuizMapper::getInstance($this->adapter);
230 efrain 1822
                    $quiz = $quizMapper->fetchOne($slide->quiz_id);
1823
                    if($quiz) {
1824
                        $quiz_uuid = $quiz->uuid;
235 efrain 1825
                        $quiz_data = $this->getQuiz($slide->quiz_id);
1826
                        $link_take_a_test = $this->url()->fromRoute('microlearning/take-a-test', ['slide_id' => $slide->uuid], ['force_canonical' => true]);
230 efrain 1827
                    }
235 efrain 1828
 
1829
                }
119 efrain 1830
 
1831
 
1832
                array_push($data, [
235 efrain 1833
                    'quiz'                  => $quiz_uuid,
1834
                    'quiz_data'             => $quiz_data,
1835
                    'uuid'                  => $slide->uuid,
1836
                    'name'                  => $slide->name ? $slide->name : '',
1837
                    'description'           => $slide->description ? $slide->description : '',
1838
                    'type'                  => $slide->type,
283 www 1839
                    'background'            => $slide->background ? $storage->getGenericImage($path, $slide->uuid, $slide->background) : '',
1840
                    'file'                  => $slide->file ? $storage->getGenericFile($path, $slide->uuid, $slide->file) : '',
235 efrain 1841
                    'order'                 => $slide->order,
1842
                    'completed'             => $completed,
236 efrain 1843
                    'link_take_a_test'      => $link_take_a_test,
235 efrain 1844
                    'added_on'              => $slide->added_on,
1845
                    'updated_on'            => $slide->updated_on,
119 efrain 1846
                ]);
1847
 
1848
 
1849
 
1850
            }
1851
 
1852
            usort($data, function($a, $b) {
1853
 
1854
                $result =  $a['order'] <=> $b['order'];
1855
                if(0 == $result) {
1856
                    $result = strcasecmp($a['added_on'], $b['added_on']);
1857
                    if(0 == $result) {
1858
                        $result = strcasecmp($a['name'], $b['name']);
1859
                    }
1860
                }
1861
 
1862
                if($result < 0) {
1863
                    return 1;
1864
                } else if($result > 0) {
1865
                    return -1;
1866
                } else  {
1867
                    return  0;
1868
                }
1869
            });
1870
 
1871
 
1872
 
1873
                return new JsonModel([
1874
                    'success' => true,
1875
                    'data' => $data
1876
                ]);
1877
 
1878
        } else {
1879
            return new JsonModel([
1880
                'success' => false,
1881
                'data' => 'ERROR_METHOD_NOT_ALLOWED'
1882
            ]);
1883
        }
1884
    }
1885
 
229 efrain 1886
    private function getQuiz($id)
1887
    {
1888
        $serviceDatetimeFormat = $this->config['leaderslinked.services.datetime'];
1889
 
1890
        $data = [];
1891
 
283 www 1892
        $quizMapper = MicrolearningQuizMapper::getInstance($this->adapter);
229 efrain 1893
        $quiz = $quizMapper->fetchOne($id);
1894
 
1895
        if(!$quiz) {
1896
            return [];
1897
        }
1898
 
1899
        $companyMapper = CompanyMapper::getInstance($this->adapter);
1900
        $company = $companyMapper->fetchOne($quiz->company_id);
1901
 
283 www 1902
        $questionMapper = MicrolearningQuestionMapper::getInstance($this->adapter);
1903
        $answerMapper = MicrolearningAnswerMapper::getInstance($this->adapter);
229 efrain 1904
 
1905
        $record_questions = [];
1906
        $questions = $questionMapper->fetchAllByQuizId($quiz->id);
1907
        foreach($questions as $question)
1908
        {
1909
            $record_answers = [];
1910
 
1911
            $answers = $answerMapper->fetchAllByQuizIdAndQuestionId($question->quiz_id, $question->id);
1912
            foreach($answers as $answer)
1913
            {
1914
                $dtAddedOn = \DateTime::createFromFormat('Y-m-d H:i:s', $answer->added_on);
1915
                $dtUpdatedOn = \DateTime::createFromFormat('Y-m-d H:i:s', $answer->updated_on);
1916
 
1917
                array_push($record_answers, [
1918
                    'uuid' => $answer->uuid,
1919
                    'text' => trim($answer->text),
1920
                    'correct' => $answer->correct ? $answer->correct  : 0 ,
1921
                    'points' => strval(intval($answer->points, 10)),
1922
                    'added_on'  => $dtAddedOn->format($serviceDatetimeFormat),
1923
                    'updated_on'    => $dtUpdatedOn->format($serviceDatetimeFormat),
1924
                ]);
1925
            }
1926
 
1927
            $dtAddedOn = \DateTime::createFromFormat('Y-m-d H:i:s', $question->added_on);
1928
            $dtUpdatedOn = \DateTime::createFromFormat('Y-m-d H:i:s', $question->updated_on);
1929
 
1930
            array_push($record_questions, [
1931
                'uuid'          => $question->uuid,
1932
                'text'          => trim($question->text),
1933
                'type'          => $question->type,
1934
                'maxlength'     => strval($question->maxlength),
1935
                'points'        => strval($question->points),
1936
                'answers'       => $record_answers,
1937
                'added_on'      => $dtAddedOn->format($serviceDatetimeFormat),
1938
                'updated_on'    => $dtUpdatedOn->format($serviceDatetimeFormat),
1939
            ]);
1940
        }
1941
 
1942
        $dtAddedOn = \DateTime::createFromFormat('Y-m-d H:i:s', $quiz->added_on);
1943
        $dtUpdatedOn = \DateTime::createFromFormat('Y-m-d H:i:s', $quiz->updated_on);
1944
 
1945
        array_push($data, [
1946
            'uuid' => $quiz->uuid,
1947
            'name' => $quiz->name,
1948
            'text' => trim($quiz->text ? $quiz->text : ''),
1949
            'failed' => trim($quiz->failed ? $quiz->failed : ''),
1950
            'points' => strval($quiz->points),
1951
            'minimum_points_required' => strval($quiz->minimum_points_required),
1952
            'max_time' => $quiz->max_time ? $quiz->max_time : 5,
1953
            'company_uuid' => $company->uuid,
1954
            'company_name' => $company->name,
1955
            'company_image' => $this->url()->fromRoute('services/storage',['type' => 'company', 'code' => $company->uuid, 'filename' => $company->image], ['force_canonical' => true]),
1956
            'questions'     => $record_questions,
1957
            'added_on'      => $dtAddedOn->format($serviceDatetimeFormat),
1958
            'updated_on'    => $dtUpdatedOn->format($serviceDatetimeFormat),
1959
        ]);
1960
 
1961
        return $data;
1962
 
1963
    }
161 efrain 1964
 
229 efrain 1965
 
161 efrain 1966
    public function getSlideAction()
1967
    {
1968
        $request = $this->getRequest();
1969
        if($request->isGet()) {
1970
            $currentUserPlugin = $this->plugin('currentUserPlugin');
1971
            $currentUser = $currentUserPlugin->getUser();
1972
 
1973
 
1974
 
1975
            $id = $this->params()->fromRoute('id');
283 www 1976
            $slideMapper = MicrolearningSlideMapper::getInstance($this->adapter);
161 efrain 1977
            $slide = $slideMapper->fetchOneByUuid($id);
1978
 
1979
            if(!$slide) {
1980
                return new JsonModel([
1981
                    'success' => false,
1982
                    'data' => 'ERROR_SLIDE_NOT_FOUND'
1983
                ]);
1984
            }
1985
 
1986
            $accessGrantedIds = $this->getAccessGranted();
1987
 
1988
 
1989
 
1990
            if(!in_array($slide->capsule_id, $accessGrantedIds->capsules)) {
1991
                return new JsonModel([
1992
                    'success' => false,
1993
                    'data' => 'ERROR_YOU_DO_NOT_HAVE_ACCESS_TO_THIS_CAPSULE'
1994
                ]);
1995
            }
1996
 
1997
 
283 www 1998
            $topicMapper = MicrolearningTopicMapper::getInstance($this->adapter);
161 efrain 1999
            $topic = $topicMapper->fetchOne($slide->topic_id);
2000
 
283 www 2001
            $capsuleMapper =  MicrolearningCapsuleMapper::getInstance($this->adapter);
161 efrain 2002
            $capsule = $capsuleMapper->fetchOne($slide->capsule_id);
2003
 
2004
 
2005
 
2006
 
2007
 
283 www 2008
            $slideMapper = MicrolearningSlideMapper::getInstance($this->adapter);
2009
            $userProgressMapper = MicrolearningUserProgressMapper::getInstance($this->adapter);
161 efrain 2010
 
2011
 
2012
            $userProgress = $userProgressMapper->fetchOneByUserIdAndSlideId($currentUser->id, $slide->id);
2013
            if($userProgress) {
2014
                $completed = $userProgress->completed;
2015
            } else {
2016
                $completed = 0;
2017
            }
235 efrain 2018
 
2019
            $quiz_uuid = '';
2020
            $quiz_data = [];
2021
            $link_take_a_test = '';
2022
            if($slide->quiz_id) {
2023
 
283 www 2024
                $quizMapper = MicrolearningQuizMapper::getInstance($this->adapter);
235 efrain 2025
                $quiz = $quizMapper->fetchOne($slide->quiz_id);
2026
                if($quiz) {
2027
                    $quiz_uuid = $quiz->uuid;
2028
                    $quiz_data = $this->getQuiz($slide->quiz_id);
2029
                    $link_take_a_test = $this->url()->fromRoute('microlearning/take-a-test', ['slide_id' => $slide->uuid], ['force_canonical' => true]);
2030
                }
161 efrain 2031
 
235 efrain 2032
            }
161 efrain 2033
 
333 www 2034
            $storage = Storage::getInstance($this->config, $this->adapter);
283 www 2035
            $path = $storage->getPathMicrolearningSlide();
161 efrain 2036
 
2037
            $data =[
235 efrain 2038
                'quiz'              => $quiz_uuid,
2039
                'quiz_data'         => $quiz_data,
2040
                'uuid'              => $slide->uuid,
2041
                'name'              => $slide->name ? $slide->name : '',
2042
                'description'       => $slide->description ? $slide->description : '',
2043
                'type'              => $slide->type,
283 www 2044
                'background'        => $slide->background ? $storage->getGenericImage($path, $slide->uuid, $slide->background) : '',
2045
                'file'              => $slide->file ? $storage->getGenericFile($path, $slide->uuid, $slide->file) : '',
235 efrain 2046
                'order'             => $slide->order,
2047
                'completed'         => $completed,
2048
                'link_sync'         => $this->url()->fromRoute('microlearning/sync', ['operation' => 'slide-view', 'topic_uuid' => $topic->uuid, 'capsule_uuid' => $capsule->uuid, 'slide_uuid' => $slide->uuid], ['force_canonical' => true]),
2049
                'link_take_a_test'  => $link_take_a_test,
2050
                'added_on'          => $slide->added_on,
2051
                'updated_on'        => $slide->updated_on,
161 efrain 2052
            ];
2053
 
2054
 
2055
 
2056
 
2057
            return new JsonModel([
2058
                'success' => true,
2059
                'data' => $data
2060
            ]);
2061
 
2062
        } else {
2063
            return new JsonModel([
2064
                'success' => false,
2065
                'data' => 'ERROR_METHOD_NOT_ALLOWED'
2066
            ]);
2067
        }
2068
    }
2069
 
119 efrain 2070
    public function profileAction()
2071
    {
2072
        $request = $this->getRequest();
2073
        if($request->isGet()) {
2074
            $currentUserPlugin = $this->plugin('currentUserPlugin');
2075
            $currentUser = $currentUserPlugin->getUser();
2076
 
2077
 
2078
            $accessGrantedIds = $this->getAccessGranted();
2079
 
2080
            $companyMapper = CompanyMapper::getInstance($this->adapter);
283 www 2081
            $companyExtendUserMapper = MicrolearningExtendUserMapper::getInstance($this->adapter);
2082
            $companyExtendUserCompanyMapper = MicrolearningExtendUserCompanyMapper::getInstance($this->adapter);
2083
            $companyExtendUserFunctionMapper = MicrolearningExtendUserFunctionMapper::getInstance($this->adapter);
2084
            $companyExtendUserGroupMapper = MicrolearningExtendUserGroupMapper::getInstance($this->adapter);
2085
            $companyExtendUserInstitutionMapper = MicrolearningExtendUserInstitutionMapper::getInstance($this->adapter);
2086
            $companyExtendUserPartnerMapper = MicrolearningExtendUserPartnerMapper::getInstance($this->adapter);
2087
            $companyExtendUserProgramMapper = MicrolearningExtendUserProgramMapper::getInstance($this->adapter);
2088
            $companyExtendUserStudentTypeMapper = MicrolearningExtendUserStudentTypeMapper::getInstance($this->adapter);
2089
            $companyExtendUserSectorMapper = MicrolearningExtendUserSectorMapper::getInstance($this->adapter);
119 efrain 2090
 
333 www 2091
            $storage = Storage::getInstance($this->config, $this->adapter);
283 www 2092
 
119 efrain 2093
 
2094
            $data = [];
2095
            foreach($accessGrantedIds->companies as $company_id)
2096
            {
2097
                $company = $companyMapper->fetchOne($company_id);
2098
                if(!$company) {
2099
                    continue;
2100
                }
2101
 
2102
                $record = [
2103
                    'name' => $company->name,
283 www 2104
                    'image' => $storage->getCompanyImage($company),
119 efrain 2105
                    'details' => [],
2106
                ];
2107
 
2108
                $companyExtendUser = $companyExtendUserMapper->fetchOneByCompanyIdAndUserId($company->id, $currentUser->id);
2109
                if(!$companyExtendUser) {
2110
                    continue;
2111
                }
2112
 
2113
                if($companyExtendUser->extend_company_id) {
2114
 
2115
                    $extendedCompany = $companyExtendUserCompanyMapper->fetchOne($companyExtendUser->company_id);
2116
                    if($extendedCompany) {
2117
                        array_push($record['details'],[
2118
                            'uuid' => $extendedCompany->uuid,
2119
                            'label' => 'LABEL_COMPANY',
2120
                            'value' => $extendedCompany->name
2121
                        ]);
2122
                    }
2123
                }
2124
 
2125
                if($companyExtendUser->extend_function_id) {
2126
                    $extendedFunction = $companyExtendUserFunctionMapper->fetchOne($companyExtendUser->extend_function_id);
2127
                    if($extendedFunction) {
2128
                        array_push($record['details'],[
2129
                            'uuid' => $extendedFunction->uuid,
2130
                            'label' => 'LABEL_FUNCTION',
2131
                            'value' => $extendedFunction->name
2132
                        ]);
2133
                    }
2134
                }
2135
 
2136
                if($companyExtendUser->extend_group_id) {
2137
                    $extendedGroup = $companyExtendUserGroupMapper->fetchOne($companyExtendUser->extend_group_id);
2138
                    if($extendedGroup) {
2139
                        array_push($record['details'],[
2140
                            'uuid' => $extendedGroup->uuid,
2141
                            'label' => 'LABEL_GROUP',
2142
                            'value' => $extendedGroup->name
2143
                        ]);
2144
                    }
2145
                }
2146
 
2147
                if($companyExtendUser->extend_institution_id) {
2148
                    $extendedInstitution= $companyExtendUserInstitutionMapper->fetchOne($companyExtendUser->extend_institution_id);
2149
                    if($extendedInstitution) {
2150
                        array_push($record['details'],[
2151
                            'uuid' => $extendedInstitution->uuid,
2152
                            'label' => 'LABEL_INSTITUTION',
2153
                            'value' => $extendedInstitution->name
2154
                        ]);
2155
                    }
2156
                }
2157
 
2158
                if($companyExtendUser->extend_program_id) {
2159
                    $extendedProgram = $companyExtendUserProgramMapper->fetchOne($companyExtendUser->extend_program_id);
2160
                    if($extendedProgram) {
2161
                        array_push($record['details'],[
2162
                            'uuid' => $extendedProgram->uuid,
2163
                            'label' => 'LABEL_PROGRAM',
2164
                            'value' => $extendedProgram->name
2165
                        ]);
2166
 
2167
                    }
2168
                }
2169
 
2170
                if($companyExtendUser->extend_sector_id) {
2171
                    $extendedSector = $companyExtendUserSectorMapper->fetchOne($companyExtendUser->extend_sector_id);
2172
                    if($extendedSector) {
2173
                        array_push($record['details'],[
2174
                            'uuid' => $extendedSector->uuid,
2175
                            'label' => 'LABEL_SECTOR',
2176
                            'value' => $extendedSector->name
2177
                        ]);
2178
                    }
2179
                }
2180
 
2181
                if($companyExtendUser->extend_partner_id) {
2182
                    $extendedPartner = $companyExtendUserPartnerMapper->fetchOne($companyExtendUser->extend_partner_id);
2183
                    if($extendedPartner) {
2184
                        array_push($record['details'],[
2185
                            'uuid' => $extendedPartner->uuid,
2186
                            'label' => 'LABEL_PARTNER',
2187
                            'value' => $extendedPartner->name
2188
                        ]);
2189
                    }
2190
                }
2191
 
2192
                if($companyExtendUser->extend_student_type_id) {
2193
                    $extendedStudentType = $companyExtendUserStudentTypeMapper->fetchOne($companyExtendUser->extend_student_type_id);
2194
                    if($extendedStudentType) {
2195
                        array_push($record['details'],[
2196
                            'uuid' => $extendedStudentType->uuid,
2197
                            'label' => 'LABEL_TYPE',
2198
                            'value' => $extendedStudentType->name
2199
                        ]);
2200
                    }
2201
                }
2202
 
2203
                array_push($data, $record);
2204
            }
2205
 
2206
            return new JsonModel([
2207
                'success' => true,
2208
                'data' => $data
2209
            ]);
2210
 
2211
        } else {
2212
            return new JsonModel([
2213
                'success' => false,
2214
                'data' => 'ERROR_METHOD_NOT_ALLOWED'
2215
            ]);
2216
        }
2217
    }
590 stevensc 2218
 
2219
    /**
2220
     *
2221
     * @return \Laminas\View\Model\JsonModel
2222
     */
167 efrain 2223
    public function syncAction()
2224
    {
2225
        $request = $this->getRequest();
590 stevensc 2226
        if (!$request->isPost()) {
2227
            return new JsonModel(['success' => false, 'data' => 'ERROR_INVALID_REQUEST']);
2228
        }
167 efrain 2229
 
590 stevensc 2230
        $slide_uuid = $this->params()->fromRoute('slide_uuid');
2231
        $topic_uuid = $this->params()->fromRoute('topic_uuid');
283 www 2232
 
590 stevensc 2233
        if (empty($slide_uuid) || empty($topic_uuid)) {
2234
            return new JsonModel(['success' => false, 'data' => 'ERROR_MISSING_PARAMETERS']);
167 efrain 2235
        }
590 stevensc 2236
 
2237
        $currentUser = $this->plugin('currentUserPlugin')->getUser();
2238
        $user_id = $currentUser->id ?? null;
2239
        if (!$user_id) {
2240
            return new JsonModel(['success' => false, 'data' => 'ERROR_USER_NOT_FOUND']);
2241
        }
2242
 
2243
        $accessGrantedIds = $this->getAccessGranted();
2244
 
2245
        // Obtener Slide
2246
        $slideMapper = MicrolearningSlideMapper::getInstance($this->adapter);
2247
        $slide = $slideMapper->fetchOneByUuid($slide_uuid);
2248
        if (!$slide) {
2249
            return new JsonModel(['success' => false, 'data' => 'ERROR_SLIDE_NOT_FOUND']);
2250
        }
2251
 
2252
        // Obtener Cápsula
2253
        $capsuleMapper = MicrolearningCapsuleMapper::getInstance($this->adapter);
2254
        $capsule = $capsuleMapper->fetchById($slide->capsule_id);
2255
        if (!$capsule || !in_array($capsule->id, $accessGrantedIds->capsules)) {
2256
            return new JsonModel(['success' => false, 'data' => 'ERROR_CAPSULE_ACCESS_DENIED']);
2257
        }
2258
 
2259
        // Obtener Tópico
2260
        $topicMapper = MicrolearningTopicMapper::getInstance($this->adapter);
2261
        $topic = $topicMapper->fetchOneByUuid($topic_uuid);
2262
        if (!$topic || !in_array($topic->id, $accessGrantedIds->topics)) {
2263
            return new JsonModel(['success' => false, 'data' => 'ERROR_TOPIC_ACCESS_DENIED']);
2264
        }
2265
 
2266
        // Validar que la cápsula pertenece al tópico
2267
        $topicCapsuleMapper = MicrolearningTopicCapsuleMapper::getInstance($this->adapter);
2268
        $relation = $topicCapsuleMapper->fetchOneByTopicIdAndCapsuleId($topic->id, $capsule->id);
2269
        if (!$relation) {
2270
            return new JsonModel(['success' => false, 'data' => 'ERROR_CAPSULE_DOES_NOT_BELONG_TO_TOPIC']);
2271
        }
2272
 
2273
        // Marcar slide como visto
2274
        $progressMapper = MicrolearningUserProgressMapper::getInstance($this->adapter);
2275
        $progressMapper->markSlideViewed($user_id, $topic->id, $capsule->id, $slide->id);
2276
 
2277
        $data = 'LABEL_THE_USER_PROGRESS_FOR_THIS_SLIDE_HAS_BEEN_COMPLETED';
2278
 
2279
        // Si vio todos los slides → marcar cápsula como completada
2280
        if ($progressMapper->hasViewedAllSlidesInCapsule($user_id, $capsule->id)) {
2281
            $progressMapper->markCapsuleCompleted($user_id, $topic->id, $capsule->id);
2282
            $data = 'LABEL_THE_USER_PROGRESS_FOR_THIS_CAPSULE_HAS_BEEN_COMPLETED';
2283
        }
2284
 
2285
        // Si completó todas las cápsulas del tópico → marcar tópico como completado
2286
        if ($progressMapper->hasCompletedAllCapsulesInTopic($user_id, $topic->id)) {
2287
            $progressMapper->markTopicCompleted($user_id, $topic->id);
2288
            $data = 'LABEL_THE_USER_PROGRESS_FOR_THIS_TOPIC_HAS_BEEN_COMPLETED';
2289
        }
2290
 
2291
        return new JsonModel(['success' => true, 'data' => $data]);
2292
    }
167 efrain 2293
 
119 efrain 2294
    /**
2295
     *
2296
     * @return \LeadersLinked\Controller\MicrolearningUserAccessGrantedIds
2297
     */
2298
    private function getAccessGranted()
2299
    {
2300
        $currentUserPlugin = $this->plugin('currentUserPlugin');
2301
        $currentUser = $currentUserPlugin->getUser();
2302
 
283 www 2303
        $capsuleUserMapper = MicrolearningCapsuleUserMapper::getInstance($this->adapter);
119 efrain 2304
        $now = $capsuleUserMapper->getDatebaseNow();
2305
 
2306
        $records = $capsuleUserMapper->fetchAllActiveByUserId($currentUser->id);
2307
 
2308
        $accessGrantedIds = new MicrolearningUserAccessGrantedIds();
2309
 
2310
 
2311
        foreach($records as $record)
2312
        {
283 www 2313
            if($record->access != MicrolearningCapsuleUser::ACCESS_UNLIMITED && $record->access != MicrolearningCapsuleUser::ACCESS_PAY_PERIOD) {
119 efrain 2314
                continue;
2315
            }
283 www 2316
            if($record->access == MicrolearningCapsuleUser::ACCESS_PAY_PERIOD) {
119 efrain 2317
                if($now < $record->paid_from || $now > $record->paid_to) {
2318
                    continue;
2319
                }
2320
            }
2321
 
2322
 
2323
            if(!in_array($record->company_id, $accessGrantedIds->companies )) {
2324
                array_push($accessGrantedIds->companies, $record->company_id);
2325
            }
2326
 
2327
            if(!in_array($record->topic_id, $accessGrantedIds->topics )) {
2328
                array_push( $accessGrantedIds->topics, $record->topic_id);
2329
            }
2330
 
2331
            if(!in_array($record->capsule_id, $accessGrantedIds->capsules)) {
2332
                array_push( $accessGrantedIds->capsules, $record->capsule_id);
2333
            }
2334
        }
2335
 
2336
        return $accessGrantedIds;
2337
    }
2338
 
590 stevensc 2339
    /**
2340
     * Marks a slide as completed and cascades completion status to capsule and topic if needed
2341
     *
2342
     * @return \Laminas\View\Model\JsonModel
2343
     */
2344
    public function completeSlideAction()
2345
    {
2346
        $request = $this->getRequest();
2347
        if($request->isPost()) {
2348
            $currentUserPlugin = $this->plugin('currentUserPlugin');
2349
            $currentUser = $currentUserPlugin->getUser();
2350
 
2351
            $slide_uuid = $this->params()->fromRoute('slide_uuid');
2352
            $topic_uuid = $this->params()->fromRoute('topic_uuid');
2353
            $capsule_uuid = $this->params()->fromRoute('capsule_uuid');
2354
 
2355
            if(empty($slide_uuid) || empty($topic_uuid) || empty($capsule_uuid)) {
2356
                return new JsonModel([
2357
                    'success' => false,
2358
                    'data' => 'ERROR_INVALID_PARAMETERS'
2359
                ]);
2360
            }
2361
 
2362
            // Get slide
2363
            $slideMapper = MicrolearningSlideMapper::getInstance($this->adapter);
2364
            $slide = $slideMapper->fetchOneByUuid($slide_uuid);
2365
 
2366
            if(!$slide) {
2367
                return new JsonModel([
2368
                    'success' => false,
2369
                    'data' => 'ERROR_SLIDE_NOT_FOUND'
2370
                ]);
2371
            }
2372
 
2373
            // Get capsule
2374
            $capsuleMapper = MicrolearningCapsuleMapper::getInstance($this->adapter);
2375
            $capsule = $capsuleMapper->fetchOneByUuid($capsule_uuid);
2376
 
2377
            if(!$capsule) {
2378
                return new JsonModel([
2379
                    'success' => false,
2380
                    'data' => 'ERROR_CAPSULE_NOT_FOUND'
2381
                ]);
2382
            }
2383
 
2384
            // Get topic
2385
            $topicMapper = MicrolearningTopicMapper::getInstance($this->adapter);
2386
            $topic = $topicMapper->fetchOneByUuid($topic_uuid);
2387
 
2388
            if(!$topic) {
2389
                return new JsonModel([
2390
                    'success' => false,
2391
                    'data' => 'ERROR_TOPIC_NOT_FOUND'
2392
                ]);
2393
            }
2394
 
2395
            // Update slide progress
2396
            $userProgressMapper = MicrolearningUserProgressMapper::getInstance($this->adapter);
2397
            $slideProgress = $userProgressMapper->fetchOneByUserIdAndSlideId($currentUser->id, $slide->id);
2398
            $updated_on = $userProgressMapper->getDatebaseNow();
2399
 
2400
            if(!$slideProgress) {
2401
                $slideProgress = new MicrolearningUserProgress();
2402
                $slideProgress->user_id = $currentUser->id;
2403
                $slideProgress->slide_id = $slide->id;
2404
                $slideProgress->topic_id = $topic->id;
2405
                $slideProgress->capsule_id = $capsule->id;
2406
            }
2407
 
2408
            $slideProgress->completed = 1;
2409
            $slideProgress->updated_on = $updated_on;
2410
 
2411
            if($userProgressMapper->update($slideProgress)) {
2412
                $closeCapsule = false;
2413
                $closeTopic = false;
2414
            }
2415
 
2416
            // Check if capsule is completed
2417
            $capsuleProgress = $userProgressMapper->fetchOneByUserIdAndCapsuleId($currentUser->id, $capsule->id);
2418
 
2419
            $capsuleProgress->total_slides = $slideMapper->fetchTotalCountByCompanyIdAndCapsuleId($capsule->company_id, $capsule->id);
2420
            $capsuleProgress->view_slides = $userProgressMapper->fetchCountAllSlideCompletedByUserIdAndCapsuleId($currentUser->id, $capsule->id);
2421
 
2422
            if($capsuleProgress->total_slides) {
2423
                $capsuleProgress->progress = ($capsuleProgress->view_slides * 100) / $capsuleProgress->total_slides;
2424
                $capsuleProgress->progress = $capsuleProgress->progress > 100 ? 100 : $capsuleProgress->progress;
2425
            }
2426
 
2427
            if(!$userProgressMapper->update($capsuleProgress)) {
2428
                return new JsonModel([
2429
                    'success' => false,
2430
                    'data' => $userProgressMapper->getError()
2431
                ]);
2432
            }
2433
 
2434
            if($capsuleProgress->progress >= 100) {
2435
                $closeCapsule = true;
2436
            }
2437
 
2438
            // Check if topic is completed
2439
            $topicProgress = $userProgressMapper->fetchOneByUserIdAndTopicId($currentUser->id, $topic->id);
2440
            if($topicProgress->completed) {
2441
                $closeTopic = true;
2442
            }
2443
 
2444
 
2445
            // Prepare response
2446
            $data = 'LABEL_THE_USER_PROGRESS_FOR_THIS_SLIDE_HAS_BEEN_COMPLETED';
2447
 
2448
            if($closeCapsule) {
2449
                $data = 'LABEL_THE_USER_PROGRESS_FOR_THIS_CAPSULE_HAS_BEEN_COMPLETED';
2450
            }
2451
 
2452
            if($closeTopic) {
2453
                $data = 'LABEL_THE_USER_PROGRESS_FOR_THIS_TOPIC_HAS_BEEN_COMPLETED';
2454
            }
2455
 
2456
            return new JsonModel([
2457
                'success' => true,
2458
                'data' => $data
2459
            ]);
2460
        }
2461
 
2462
        return new JsonModel([
2463
            'success' => false,
2464
            'data' => 'ERROR_METHOD_NOT_ALLOWED'
2465
        ]);
2466
    }
119 efrain 2467
}