Proyectos de Subversion LeadersLinked - Backend

Rev

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

Rev Autor Línea Nro. Línea
1 www 1
<?php
2
declare(strict_types=1);
3
 
4
namespace LeadersLinked\Controller;
5
 
6
use Laminas\Db\Adapter\AdapterInterface;
17152 stevensc 7
use Laminas\Log\LoggerInterface;
1 www 8
use Laminas\Mvc\Controller\AbstractActionController;
9
use Laminas\View\Model\ViewModel;
10
use Laminas\View\Model\JsonModel;
17154 stevensc 11
use Laminas\Hydrator\ArraySerializableHydrator;
12
use Laminas\Db\ResultSet\HydratingResultSet;
13
use Laminas\Paginator\Adapter\DbSelect;
14
use Laminas\Paginator\Paginator;
15
use Laminas\Mvc\I18n\Translator;
17002 efrain 16
use LeadersLinked\Mapper\MicrolearningTopicMapper;
17154 stevensc 17
use LeadersLinked\Mapper\MicrolearningUserMapper;
1 www 18
use LeadersLinked\Mapper\UserMapper;
17154 stevensc 19
use LeadersLinked\Mapper\QueryMapper;
1 www 20
use LeadersLinked\Mapper\ApplicationMapper;
21
use LeadersLinked\Mapper\PushMapper;
22
use LeadersLinked\Mapper\PushTemplateMapper;
23
use LeadersLinked\Mapper\DeviceHistoryMapper;
17154 stevensc 24
use LeadersLinked\Mapper\ApplicationVariantMapper;
25
use LeadersLinked\Mapper\NotificationMapper;
26
use LeadersLinked\Mapper\NetworkMapper;
27
use LeadersLinked\Mapper\CompanyMapper;
28
use LeadersLinked\Mapper\CompanyFollowerMapper;
29
use LeadersLinked\Mapper\ConnectionMapper;
1 www 30
use LeadersLinked\Mapper\UserPasswordMapper;
17002 efrain 31
use LeadersLinked\Mapper\MicrolearningExtendUserMapper;
32
use LeadersLinked\Mapper\MicrolearningExtendUserCompanyMapper;
33
use LeadersLinked\Mapper\MicrolearningExtendUserFunctionMapper;
34
use LeadersLinked\Mapper\MicrolearningExtendUserGroupMapper;
35
use LeadersLinked\Mapper\MicrolearningExtendUserInstitutionMapper;
36
use LeadersLinked\Mapper\MicrolearningExtendUserProgramMapper;
37
use LeadersLinked\Mapper\MicrolearningExtendUserPartnerMapper;
38
use LeadersLinked\Mapper\MicrolearningExtendUserSectorMapper;
39
use LeadersLinked\Mapper\MicrolearningExtendUserStudentTypeMapper;
17154 stevensc 40
use LeadersLinked\Mapper\MicrolearningExtendUserCountryMapper;
41
use LeadersLinked\Model\MicrolearningUser;
42
use LeadersLinked\Model\Push;
43
use LeadersLinked\Model\Application;
44
use LeadersLinked\Model\Notification;
45
use LeadersLinked\Model\Network;
46
use LeadersLinked\Model\Connection;
47
use LeadersLinked\Model\CompanyFollower;
48
use LeadersLinked\Model\User;
49
use LeadersLinked\Model\UserType;
50
use LeadersLinked\Model\UserPassword;
17002 efrain 51
use LeadersLinked\Model\MicrolearningExtendUser;
52
use LeadersLinked\Model\MicrolearningExtendUserCompany;
53
use LeadersLinked\Model\MicrolearningExtendUserFunction;
54
use LeadersLinked\Model\MicrolearningExtendUserGroup;
55
use LeadersLinked\Model\MicrolearningExtendUserInstitution;
56
use LeadersLinked\Model\MicrolearningExtendUserProgram;
57
use LeadersLinked\Model\MicrolearningExtendUserPartner;
58
use LeadersLinked\Model\MicrolearningExtendUserSector;
59
use LeadersLinked\Model\MicrolearningExtendUserStudentType;
60
use LeadersLinked\Model\MicrolearningExtendUserCountry;
17248 stevensc 61
use LeadersLinked\Form\Microlearning\TopicUserForm;
17154 stevensc 62
use LeadersLinked\Form\Microlearning\PushMicrolearningNotificationForm;
17248 stevensc 63
use LeadersLinked\Form\Microlearning\TopicCustomerUploadForm;
16766 efrain 64
use LeadersLinked\Library\Functions;
16768 efrain 65
use LeadersLinked\Cache\CacheInterface;
66
use LeadersLinked\Cache\CacheImpl;
17154 stevensc 67
use PhpOffice\PhpSpreadsheet\IOFactory;
17248 stevensc 68
use LeadersLinked\Mapper\MicrolearningTopicUserMapper;
69
use LeadersLinked\Model\MicrolearningTopicUser;
17260 stevensc 70
use LeadersLinked\Library\Storage;
1 www 71
 
72
class MicrolearningAccessForStudentsController extends AbstractActionController
73
{
74
    /**
17152 stevensc 75
     * @var AdapterInterface
1 www 76
     */
77
    private $adapter;
78
 
79
    /**
17152 stevensc 80
     * @var CacheInterface
1 www 81
     */
16769 efrain 82
    private $cache;
83
 
84
    /**
17152 stevensc 85
     * @var LoggerInterface
16769 efrain 86
     */
1 www 87
    private $logger;
88
 
89
    /**
90
     * @var array
91
     */
92
    private $config;
93
 
94
    /**
17152 stevensc 95
     * @var Translator
16768 efrain 96
     */
16769 efrain 97
    private $translator;
16768 efrain 98
 
99
    /**
17152 stevensc 100
     * @param AdapterInterface $adapter
101
     * @param CacheInterface $cache
102
     * @param LoggerInterface $logger
1 www 103
     * @param array $config
17152 stevensc 104
     * @param Translator $translator
1 www 105
     */
16769 efrain 106
    public function __construct($adapter, $cache, $logger, $config, $translator)
1 www 107
    {
17152 stevensc 108
        $this->adapter = $adapter;
109
        $this->cache = $cache;
110
        $this->logger = $logger;
111
        $this->config = $config;
112
        $this->translator = $translator;
1 www 113
    }
114
 
115
    public function indexAction()
116
    {
17154 stevensc 117
        try {
118
            $currentUserPlugin = $this->plugin('currentUserPlugin');
119
            $currentUser = $currentUserPlugin->getUser();
120
            $currentCompany = $currentUserPlugin->getCompany();
1 www 121
 
17154 stevensc 122
            $request = $this->getRequest();
1 www 123
 
17154 stevensc 124
            if($request->isGet())
125
            {
126
                $headers  = $request->getHeaders();
127
                $isJson = false;
1 www 128
 
17154 stevensc 129
                if($headers->has('Accept')) {
130
                    $accept = $headers->get('Accept');
131
                    $prioritized = $accept->getPrioritized();
1 www 132
 
17154 stevensc 133
                    foreach($prioritized as $key => $value) {
134
                        $raw = trim($value->getRaw());
135
                        if(!$isJson) $isJson = strpos($raw, 'json');
1 www 136
                    }
137
                }
138
 
17154 stevensc 139
                if($isJson) {
140
                    try {
17178 stevensc 141
                        $topic_uuid     = Functions::sanitizeFilterString($request->getQuery('topic_uuid'));
17154 stevensc 142
 
143
                        $data = [
144
                            'link_upload' => '',
145
                            'items' => [] ,
146
                            'total' => 0,
147
                        ];
148
 
149
                        if(!$topic_uuid) {
150
                            return new JsonModel([
151
                                'success' => true,
152
                                'data' => $data
153
                            ]);
154
                        }
155
 
156
                        $topicMapper = MicrolearningTopicMapper::getInstance($this->adapter);
17178 stevensc 157
                        $topic = $topicMapper->fetchOneByUuid($topic_uuid);
17154 stevensc 158
 
159
                        if(!$topic) {
160
                            return new JsonModel([
161
                                'success' => true,
162
                                'data' => 'ERROR_TOPIC_NOT_FOUND'
163
                            ]);
164
                        }
165
 
166
                        if($topic->company_id != $currentCompany->id) {
167
                            return new JsonModel([
168
                                'success' => true,
169
                                'data' => 'ERROR_UNAUTHORIZED'
170
                            ]);
171
                        }
17156 stevensc 172
 
17248 stevensc 173
                        $data['link_upload'] = $this->url()->fromRoute('microlearning/access-for-students/upload',['topic_uuid' => $topic->uuid]);
174
                        $data['link_notification'] = $this->url()->fromRoute('microlearning/access-for-students/notification',['topic_uuid' => $topic->uuid]);
17154 stevensc 175
 
176
                        $search = $this->params()->fromQuery('search', []);
177
                        $search = empty($search['value']) ? '' :  Functions::sanitizeFilterString($search['value']);
178
 
179
                        $page               = intval($this->params()->fromQuery('start', 1), 10);
180
                        $records_x_page     = intval($this->params()->fromQuery('length', 10), 10);
181
                        $order =  $this->params()->fromQuery('order', []);
182
                        $order_field        = empty($order[0]['column']) ? 99 :  intval($order[0]['column'], 10);
183
                        $order_direction    = empty($order[0]['dir']) ? 'ASC' : strtoupper(Functions::sanitizeFilterString($order[0]['dir']));
184
 
185
                        $fields =  ['uuid', 'first_name', 'last_name', 'email'];
186
                        $order_field = isset($fields[$order_field]) ? $fields[$order_field] : 'first_name';
187
 
188
                        if(!in_array($order_direction, ['ASC', 'DESC'])) {
189
                            $order_direction = 'ASC';
190
                        }
191
 
192
                        $acl = $this->getEvent()->getViewModel()->getVariable('acl');
193
                        $allowRevoke = $acl->isAllowed($currentUser->usertype_id, 'microlearning/access-for-students/revoke');
194
                        $allowUnlimit = $acl->isAllowed($currentUser->usertype_id, 'microlearning/access-for-students/unlimit');
195
                        $allowCancel = $acl->isAllowed($currentUser->usertype_id, 'microlearning/access-for-students/cancel');
196
                        $allowReactive = $acl->isAllowed($currentUser->usertype_id, 'microlearning/access-for-students/reactive');
197
 
198
                        $queryMapper = QueryMapper::getInstance($this->adapter);
199
                        $sql = $queryMapper->getSql();
200
                        $select = $sql->select();
201
                        $select->columns(['access', 'paid_from', 'paid_to', 'added_on', 'updated_on']);
17248 stevensc 202
                        $select->from(['tb1' => MicrolearningTopicUserMapper::_TABLE] );
17154 stevensc 203
                        $select->join(['tb2' => UserMapper::_TABLE], 'tb1.user_id = tb2.id', ['uuid', 'first_name', 'last_name', 'email']);
17248 stevensc 204
                        $select->where->equalTo('tb1.company_id', $topic->company_id);
17161 stevensc 205
                        $select->where->equalTo('tb1.topic_id', $topic->id);
17154 stevensc 206
 
207
                        if($search) {
208
                            $select->where->nest()
209
                            ->like('first_name', '%' . $search . '%')
210
                            ->or->like('last_name', '%' . $search . '%')
211
                            ->or->like('email', '%' . $search . '%')
212
                            ->unnest();
1 www 213
 
17154 stevensc 214
                        }
215
 
216
 
217
                        $select->order($order_field . ' ' . $order_direction);
218
 
219
                        $hydrator   = new ArraySerializableHydrator();
220
                        $resultset  = new HydratingResultSet($hydrator);
221
 
222
                        $adapter = new DbSelect($select, $sql, $resultset);
223
                        $paginator = new Paginator($adapter);
224
                        $paginator->setItemCountPerPage($records_x_page);
225
                        $paginator->setCurrentPageNumber($page);
226
 
227
 
228
                        $items = [ ];
229
                        $records = $paginator->getCurrentItems();
230
                        foreach($records as $record)
231
                        {
232
                            $params = [
233
                                'topic_uuid' => $topic->uuid,
234
                                'user_uuid' => $record['uuid']
235
                            ];
1 www 236
 
17154 stevensc 237
                            $actions = [];
1 www 238
 
17154 stevensc 239
                            switch($record['access'])
240
                            {
17248 stevensc 241
                                case MicrolearningTopicUser::ACCESS_UNLIMITED :
17154 stevensc 242
                                    $actions['link_revoke'] = $allowRevoke ? $this->url()->fromRoute('microlearning/access-for-students/revoke', $params) : '';
243
                                    $details['access'] = 'LABEL_UNLIMIT';
244
                                    break;
245
 
17248 stevensc 246
                                case MicrolearningTopicUser::ACCESS_REVOKE :
17154 stevensc 247
                                    $actions['link_unlimit'] = $allowUnlimit ? $this->url()->fromRoute('microlearning/access-for-students/unlimit', $params) : '';
248
                                    $details['access'] = 'LABEL_REVOKED';
249
                                    break;
250
 
17248 stevensc 251
                                case MicrolearningTopicUser::ACCESS_PAY_PERIOD :
17154 stevensc 252
                                    $actions['link_cancel'] = $allowCancel ? $this->url()->fromRoute('microlearning/access-for-students/cancel', $params) : '';
253
 
254
                                    $dt_paid_from = \DateTime::createFromFormat('Y-m-d', $record['paid_from']);
255
                                    $dt_paid_to = \DateTime::createFromFormat('Y-m-d', $record['paid_to']);
256
 
257
                                    $details['access'] = 'LABEL_PAY_PERIOD';
258
                                    $details['paid_from'] = $dt_paid_from->format('d/m/Y');
259
                                    $details['paid_to'] = $dt_paid_to->format('d/m/Y');
260
                                    break;
261
 
17248 stevensc 262
                                case MicrolearningTopicUser::ACCESS_SUPENDED :
17154 stevensc 263
                                    $dt_paid_from = \DateTime::createFromFormat('Y-m-d', $record['paid_from']);
264
                                    $dt_paid_to = \DateTime::createFromFormat('Y-m-d', $record['paid_to']);
265
 
266
                                    $details['access'] = 'LABEL_SUSPENDED';
267
                                    $details['paid_from'] = $dt_paid_from->format('d/m/Y');
268
                                    $details['paid_to'] = $dt_paid_to->format('d/m/Y');
269
                                    break;
270
 
17248 stevensc 271
                                case MicrolearningTopicUser::ACCESS_CANCELLED :
17154 stevensc 272
 
273
                                    $date = date('Y-m-d');
274
                                    if($allowCancel && $record['paid_from'] <= $date && $record['paid_to'] >= $date) {
275
                                        $actions['link_reactive'] = $allowReactive ? $this->url()->fromRoute('microlearning/access-for-students/reactive', $params) : '';
276
                                    }
277
 
278
                                    $dt_paid_from = \DateTime::createFromFormat('Y-m-d', $record['paid_from']);
279
                                    $dt_paid_to = \DateTime::createFromFormat('Y-m-d', $record['paid_to']);
280
 
281
                                    $details['access'] = 'LABEL_CANCELLED';
282
                                    $details['paid_from'] = $dt_paid_from->format('d/m/Y');
283
                                    $details['paid_to'] = $dt_paid_to->format('d/m/Y');
284
                                    break;
285
 
1 www 286
                            }
287
 
17154 stevensc 288
                            $dt_added_on = \DateTime::createFromFormat('Y-m-d H:i:s', $record['added_on']);
289
                            $details['added_on'] = $dt_added_on->format('d/m/Y h:i a');
1 www 290
 
17154 stevensc 291
                            $dt_updated_on = \DateTime::createFromFormat('Y-m-d H:i:s', $record['updated_on']);
292
                            $details['updated_on'] = $dt_updated_on->format('d/m/Y h:i a');
1 www 293
 
17154 stevensc 294
                            $item = [
295
                                'uuid' => $record['uuid'],
296
                                'first_name' => $record['first_name'],
297
                                'last_name' => $record['last_name'],
298
                                'email' => $record['email'],
299
                                'details' => $details,
300
                                'actions' => $actions
301
                            ];
17249 stevensc 302
 
17154 stevensc 303
                            array_push($items, $item);
304
                        }
305
 
306
                        $data['items'] = $items;
307
                        $data['total'] = $paginator->getTotalItemCount();
308
 
309
                        return new JsonModel([
310
                            'success' => true,
311
                            'data' => $data
312
                        ]);
313
                    } catch (\Exception $e) {
314
                        $this->logger->err('Error in indexAction: ' . $e->getMessage());
315
                        return new JsonModel([
316
                            'success' => false,
317
                            'data' => 'An error occurred while processing your request'
318
                        ]);
1 www 319
                    }
17154 stevensc 320
                } else {
321
                    $topicMapper = MicrolearningTopicMapper::getInstance($this->adapter);
322
                    $topics = $topicMapper->fetchAllByCompanyId($currentCompany->id);
1 www 323
 
17154 stevensc 324
                    if($topics) {
325
                        $topic_id = $topics[0]->id;
326
                    }  else {
327
                        $topic_id = 0;
328
                    }
1 www 329
 
17248 stevensc 330
                    $form = new TopicUserForm($this->adapter, $currentCompany->id, $topic_id);
17154 stevensc 331
                    $formPushNotification = new PushMicrolearningNotificationForm($this->adapter, $currentCompany->id);
17248 stevensc 332
                    $formTopicCustomer = new TopicCustomerUploadForm();
1 www 333
 
17154 stevensc 334
                    $this->layout()->setTemplate('layout/layout-backend');
335
                    $viewModel = new ViewModel();
336
                    $viewModel->setTemplate('leaders-linked/microlearning-access-for-students/index.phtml');
337
                    $viewModel->setVariables([
338
                        'form' => $form,
339
                        'formPushNotification' => $formPushNotification,
17248 stevensc 340
                        'formTopicCustomer' => $formTopicCustomer
17154 stevensc 341
                    ]);
1 www 342
 
17154 stevensc 343
                    return $viewModel ;
1 www 344
                }
345
 
17154 stevensc 346
            } else {
1 www 347
                return new JsonModel([
17154 stevensc 348
                    'success' => false,
349
                    'data' => 'ERROR_METHOD_NOT_ALLOWED'
1 www 350
                ]);
351
            }
17154 stevensc 352
        } catch (\Exception $e) {
353
            $this->logger->err('Fatal error in indexAction: ' . $e->getMessage());
17155 stevensc 354
            return new JsonModel([
355
                'success' => false,
356
                'data' => $e->getMessage()
357
            ]);
1 www 358
        }
359
    }
17248 stevensc 360
 
361
    /**
362
     * Revokes unlimited access for a user to a specific microlearning topic
363
     *
364
     * This action handles the revocation of unlimited access privileges for a user.
365
     * It checks various conditions before proceeding with the revocation:
366
     * - Validates current user and company
367
     * - Verifies topic and user existence
368
     * - Ensures proper authorization
369
     * - Confirms the user has unlimited access before revoking
370
     *
371
     * @return JsonModel Returns a JSON response indicating success or failure
372
     */
1 www 373
    public function revokeAction()
374
    {
17248 stevensc 375
        // Get the current request object
1 www 376
        $request = $this->getRequest();
377
 
17248 stevensc 378
        // Get current user and company from plugin
1 www 379
        $currentUserPlugin = $this->plugin('currentUserPlugin');
380
        $currentUser    = $currentUserPlugin->getUser();
381
        $currentCompany = $currentUserPlugin->getCompany();
382
 
17248 stevensc 383
        // Get topic and user UUIDs from route parameters
1 www 384
        $request    = $this->getRequest();
385
        $topic_uuid     = $this->params()->fromRoute('topic_uuid');
386
        $user_uuid   = $this->params()->fromRoute('user_uuid');
17248 stevensc 387
 
388
        // Validate current user exists
389
        if(!$currentUser) {
1 www 390
            return new JsonModel([
391
                'success'   => false,
17248 stevensc 392
                'data'   => 'ERROR_UNAUTHORIZED'
1 www 393
            ]);
394
        }
17248 stevensc 395
 
396
        // Validate current company exists
397
        if(!$currentCompany) {
1 www 398
            return new JsonModel([
399
                'success'   => false,
400
                'data'   => 'ERROR_UNAUTHORIZED'
401
            ]);
402
        }
17248 stevensc 403
 
404
        // Validate topic UUID was provided
405
        if(!$topic_uuid) {
406
            return new JsonModel([
407
                'success'   => false,
408
                'data'   => 'ERROR_TOPIC_NOT_FOUND'
409
            ]);
410
        }
411
 
412
        // Validate user UUID was provided
413
        if(!$user_uuid) {
414
            return new JsonModel([
415
                'success'   => false,
416
                'data'   => 'ERROR_USER_NOT_FOUND'
417
            ]);
418
        }
1 www 419
 
17248 stevensc 420
        // Fetch topic by UUID and validate it exists
421
        $topicMapper = MicrolearningTopicMapper::getInstance($this->adapter);
422
        $topic = $topicMapper->fetchOneByUuid($topic_uuid);
423
        if(!$topic) {
1 www 424
            return new JsonModel([
425
                'success'   => false,
17248 stevensc 426
                'data'   => 'ERROR_TOPIC_NOT_FOUND'
1 www 427
            ]);
428
        }
429
 
17248 stevensc 430
        // Validate topic belongs to current company
431
        if($topic->company_id != $currentCompany->id) {
1 www 432
            return new JsonModel([
433
                'success'   => false,
434
                'data'   => 'ERROR_UNAUTHORIZED'
435
            ]);
436
        }
437
 
17248 stevensc 438
        // Fetch user by UUID and validate it exists
1 www 439
        $userMapper = UserMapper::getInstance($this->adapter);
440
        $user = $userMapper->fetchOneByUuid($user_uuid);
441
 
442
        if(!$user) {
443
            return new JsonModel([
444
                'success'   => false,
445
                'data'   => 'ERROR_USER_NOT_FOUND'
446
            ]);
447
        }
448
 
17248 stevensc 449
        // Fetch topic-user relationship and validate it exists
450
        $topicUserMapper = MicrolearningTopicUserMapper::getInstance($this->adapter);
451
        $topicUser = $topicUserMapper->fetchOneByUserIdAndTopicId($user->id, $topic->id);
452
        if(!$topicUser) {
1 www 453
            return new JsonModel([
454
                'success'   => false,
455
                'data'   => 'ERROR_UNAUTHORIZED'
456
            ]);
457
        }
458
 
17248 stevensc 459
        // Process revocation only for POST requests
1 www 460
        if($request->isPost()) {
17248 stevensc 461
            // Validate user has unlimited access before revoking
462
            if($topicUser->access != MicrolearningTopicUser::ACCESS_UNLIMITED) {
1 www 463
                return new JsonModel([
464
                    'success'   => false,
465
                    'data'   => 'ERROR_USER_ACCESS_CANNT_BE_REVOKE'
466
                ]);
467
            }
17248 stevensc 468
 
469
            // Update access to revoked status
470
            $topicUser->access = MicrolearningTopicUser::ACCESS_REVOKE;
471
            if($topicUserMapper->update($topicUser)) {
1 www 472
 
17248 stevensc 473
                // Refresh topic user data after update
474
                $topicUser = $topicUserMapper->fetchOne($topicUser->id);
475
                if($topicUser) {
476
                    // Update or create microlearning user record
17002 efrain 477
                    $microlearningUserMapper = MicrolearningUserMapper::getInstance($this->adapter);
17248 stevensc 478
                    $microlearningUser = $microlearningUserMapper->fetchOneByUserIdAndCompanyId($topicUser->user_id, $topicUser->company_id);
17002 efrain 479
                    if($microlearningUser) {
17248 stevensc 480
                        // Update existing microlearning user
481
                        $microlearningUser->updated_on = $topicUser->updated_on;
17002 efrain 482
                        $microlearningUserMapper->update($microlearningUser);
1 www 483
 
484
                    } else {
17248 stevensc 485
                        // Create new microlearning user
17002 efrain 486
                        $microlearningUser = new MicrolearningUser();
17248 stevensc 487
                        $microlearningUser->company_id = $topicUser->company_id;
488
                        $microlearningUser->user_id = $topicUser->user_id;
489
                        $microlearningUser->added_on = $topicUser->added_on;
490
                        $microlearningUser->updated_on = $topicUser->updated_on;
1 www 491
 
17002 efrain 492
                        $microlearningUserMapper->insert($microlearningUser);
1 www 493
                    }
494
                }
495
 
496
                return new JsonModel([
497
                    'success' => true,
498
                    'data' => 'LABEL_USER_ACCESS_HAS_BEEN_REVOKE'
499
                ]);
500
 
501
            } else {
502
 
503
                return new JsonModel([
504
                    'success'   => false,
17248 stevensc 505
                    'data'      => $topicUserMapper->getError()
1 www 506
                ]);
507
            }
508
        }
509
 
17248 stevensc 510
        // Return error for non-POST requests
1 www 511
        return new JsonModel([
512
            'success' => false,
513
            'data' => 'ERROR_METHOD_NOT_ALLOWED'
514
        ]);
515
    }
516
 
517
    public function unlimitAction()
518
    {
17248 stevensc 519
        try {
520
            $request    = $this->getRequest();
521
 
522
            $currentUserPlugin = $this->plugin('currentUserPlugin');
523
            $currentUser    = $currentUserPlugin->getUser();
524
            $currentCompany = $currentUserPlugin->getCompany();
525
 
526
            $topic_uuid     = $this->params()->fromRoute('topic_uuid');
527
            $user_uuid   = $this->params()->fromRoute('user_uuid');
528
 
529
            if(!$currentUser) {
530
                return new JsonModel([
531
                    'success'   => false,
532
                    'data'   => 'ERROR_UNAUTHORIZED'
533
                ]);
534
            }
535
 
536
            if(!$currentCompany) {
537
                return new JsonModel([
538
                    'success'   => false,
539
                    'data'   => 'ERROR_UNAUTHORIZED'
540
                ]);
541
            }
542
 
543
            if(!$topic_uuid) {
544
                return new JsonModel([
545
                    'success'   => false,
546
                    'data'   => 'ERROR_TOPIC_NOT_FOUND'
547
                ]);
548
            }
549
 
550
            if(!$user_uuid) {
551
                return new JsonModel([
552
                    'success'   => false,
553
                    'data'   => 'ERROR_USER_NOT_FOUND'
554
                ]);
555
            }
556
 
557
            if(!$request->isPost()) {
558
                return new JsonModel([
559
                    'success'   => false,
560
                    'data'   => 'ERROR_METHOD_NOT_ALLOWED'
561
                ]);
562
            }
563
 
564
            $topicMapper = MicrolearningTopicMapper::getInstance($this->adapter);
565
            $topic = $topicMapper->fetchOneByUuid($topic_uuid);
566
            if(!$topic) {
567
                return new JsonModel([
568
                    'success'   => false,
569
                    'data'   => 'ERROR_TOPIC_NOT_FOUND'
570
                ]);
571
            }
1 www 572
 
17248 stevensc 573
            if($topic->company_id != $currentCompany->id) {
574
                return new JsonModel([
575
                    'success'   => false,
576
                    'data'   => 'ERROR_UNAUTHORIZED'
577
                ]);
578
            }
1 www 579
 
17248 stevensc 580
            $userMapper = UserMapper::getInstance($this->adapter);
581
            $user = $userMapper->fetchOneByUuid($user_uuid);
1 www 582
 
17248 stevensc 583
            if(!$user) {
1 www 584
                return new JsonModel([
585
                    'success'   => false,
17248 stevensc 586
                    'data'   => 'ERROR_USER_NOT_FOUND'
1 www 587
                ]);
588
            }
17248 stevensc 589
 
590
            $topicUserMapper = MicrolearningTopicUserMapper::getInstance($this->adapter);
591
            $topicUser = $topicUserMapper->fetchOneByUserIdAndTopicId($user->id, $topic->id);
592
            if(!$topicUser) {
1 www 593
                return new JsonModel([
17248 stevensc 594
                    'success'   => false,
595
                    'data'   => 'ERROR_UNAUTHORIZED'
1 www 596
                ]);
17248 stevensc 597
            }
598
 
599
            if($topicUser->access != MicrolearningTopicUser::ACCESS_REVOKE) {
1 www 600
                return new JsonModel([
601
                    'success'   => false,
17248 stevensc 602
                    'data'   => 'ERROR_USER_ACCESS_CANNT_BE_UNLIMIT'
1 www 603
                ]);
604
            }
17248 stevensc 605
 
606
            $topicUser->access = MicrolearningTopicUser::ACCESS_UNLIMITED;
607
            $topicUser->updated_on = date('Y-m-d H:i:s');
608
 
609
            try {
610
                $topicUserMapper->update($topicUser);
611
 
612
                $microlearningUserMapper = MicrolearningUserMapper::getInstance($this->adapter);
613
                $microlearningUser = $microlearningUserMapper->fetchOneByUserIdAndCompanyId($topicUser->user_id, $topicUser->company_id);
614
 
615
                if(!$microlearningUser) {
616
                    $microlearningUser = new MicrolearningUser();
617
                    $microlearningUser->company_id = $topicUser->company_id;
618
                    $microlearningUser->user_id = $topicUser->user_id;
619
                    $microlearningUser->added_on = $topicUser->added_on;
620
                    $microlearningUser->updated_on = $topicUser->updated_on;
621
                    $microlearningUserMapper->insert($microlearningUser);
622
                } else {
623
                    $microlearningUser->updated_on = $topicUser->updated_on;
624
                    $microlearningUserMapper->update($microlearningUser);
625
                }
626
            } catch (\Exception $e) {
627
                $this->logger->err('Error updating topic user: ' . $e->getMessage());
628
                return new JsonModel([
629
                    'success'   => false,
630
                    'data'      => 'ERROR_UPDATING_TOPIC_USER'
631
                ]);
632
            }
633
 
634
            return new JsonModel([
635
                'success' => true,
636
                'data' => 'LABEL_USER_ACCESS_HAS_BEEN_UNLIMITED'
637
            ]);
638
        } catch (\Exception $e) {
639
            $this->logger->err('Fatal error in unlimitAction: ' . $e->getMessage());
640
            return new JsonModel([
641
                'success' => false,
642
                'data' => $e->getMessage()
643
            ]);
1 www 644
        }
645
    }
646
 
647
    public function uploadAction()
648
    {
649
        $request = $this->getRequest();
650
 
651
        $currentUserPlugin = $this->plugin('currentUserPlugin');
17261 stevensc 652
        $currentNetworkPlugin = $this->plugin('currentNetworkPlugin');
653
 
1 www 654
        $currentUser    = $currentUserPlugin->getUser();
655
        $currentCompany = $currentUserPlugin->getCompany();
15394 efrain 656
        $currentNetwork = $currentNetworkPlugin->getNetwork();
657
 
1 www 658
        $topic_uuid     = $this->params()->fromRoute('topic_uuid');
17261 stevensc 659
 
660
        if(!$currentUser) {
661
            return new JsonModel([
662
                'success'   => false,
663
                'data'   => 'ERROR_USER_NOT_FOUND'
664
            ]);
665
        }
666
 
667
        if(!$currentCompany) {
668
            return new JsonModel([
669
                'success'   => false,
670
                'data'   => 'ERROR_COMPANY_NOT_FOUND'
671
            ]);
672
        }
673
 
674
        if(!$currentNetwork) {
675
            return new JsonModel([
676
                'success'   => false,
677
                'data'   => 'ERROR_NETWORK_NOT_FOUND'
678
            ]);
679
        }
680
 
681
        if(!$topic_uuid) {
682
            return new JsonModel([
683
                'success'   => false,
684
                'data'   => 'ERROR_TOPIC_NOT_FOUND'
685
            ]);
686
        }
687
 
688
        if(!$request->isPost()) {
689
            return new JsonModel([
690
                'success'   => false,
691
                'data'   => 'ERROR_METHOD_NOT_ALLOWED'
692
            ]);
693
        }
1 www 694
 
17002 efrain 695
        $topicMapper = MicrolearningTopicMapper::getInstance($this->adapter);
1 www 696
        $topic = $topicMapper->fetchOneByUuid($topic_uuid);
17261 stevensc 697
 
1 www 698
        if(!$topic) {
699
            return new JsonModel([
700
                'success'   => false,
701
                'data'   => 'ERROR_TOPIC_NOT_FOUND'
702
            ]);
703
        }
704
 
705
        if($topic->company_id != $currentCompany->id) {
706
            return new JsonModel([
707
                'success'   => false,
708
                'data'   => 'ERROR_UNAUTHORIZED'
709
            ]);
710
        }
711
 
17261 stevensc 712
        $step = Functions::sanitizeFilterString($this->params()->fromPost('step'));
713
 
714
        $storage = Storage::getInstance($this->config, $this->adapter);
715
        $storage->setFiles($request->getFiles()->toArray());
716
 
717
        if(!$storage->setCurrentFilename('file')) {
718
            return new JsonModel([
719
                'success' => false,
720
                'data' => 'ERROR_UPLOAD_FILE'
721
            ]);
722
        }
1 www 723
 
17261 stevensc 724
        if($step == 'validation') {
725
            $userMapper = UserMapper::getInstance($this->adapter);
726
            $topicUserMapper = MicrolearningTopicUserMapper::getInstance($this->adapter);
1 www 727
 
17261 stevensc 728
            $tmp_filename = $storage->getTmpFilename();
729
            $filename =   $storage->getFilename();
730
            $target_filename = $storage->composePathToFilename(
731
                Storage::TYPE_MICROLEARNING_ACCESS_FOR_STUDENTS,
732
                $topic->uuid,
733
                $filename
734
            );
735
 
736
            if(!$storage->putFile($tmp_filename, $target_filename)) {
737
                return new JsonModel([
738
                    'success' => false,
739
                    'data' => 'ERROR_UPLOAD_FILE'
740
                ]);
741
            }
742
 
743
 
744
            $count_users = 0;
745
            $users = [];
746
            $count_errors = 0;
747
            $errors = [];
748
 
749
            try {
750
                $spreadsheet = IOFactory::load($target_filename);
751
                $records = $spreadsheet->getActiveSheet()->toArray(null, true, true, true);
752
            } catch (\Exception $e) {
753
                return new JsonModel([
754
                    'success' => false,
755
                    'data' => 'ERROR_UPLOAD_FILE' . $e->getMessage()
756
                ]);
757
            }
758
 
759
            $emails = [];
760
            $row = 0;
761
 
762
            foreach($records as $record)
763
            {
764
                /*
765
                A = Nombre
766
                B = Apellido
767
                C = Email
768
                D = Contraseña
769
                E = Empresa
770
                F = Función
771
                G = Grupo
772
                H = Institución
773
                I = Programa
774
                J = Socio
775
                K = Sector
776
                L = Tipo de Estudiante
777
                M = País
778
                N = Es adulto
779
                */
780
                $row++;
1 www 781
 
17261 stevensc 782
                $first_name = Functions::sanitizeFilterString($record['A']);
783
                $last_name = Functions::sanitizeFilterString($record['B']);
784
                $email = trim(filter_var($record['C'], FILTER_SANITIZE_EMAIL));
785
                $password = Functions::sanitizeFilterString($record['D']);
1 www 786
 
17261 stevensc 787
                $company =  isset($record['E']) ? Functions::sanitizeFilterString($record['E']) : '';
788
                $function = isset($record['F']) ? Functions::sanitizeFilterString($record['F']) : '';
789
                $group = isset($record['G']) ? Functions::sanitizeFilterString($record['G']) : '';
790
                $institution = isset($record['H']) ? Functions::sanitizeFilterString($record['H']) : '';
791
                $program = isset($record['I']) ? Functions::sanitizeFilterString($record['I']) : '';
792
                $partner = isset($record['J']) ? Functions::sanitizeFilterString($record['J']) : '';
793
                $sector = isset($record['K']) ? Functions::sanitizeFilterString($record['K']) : '';
794
                $studentType = isset($record['L']) ? Functions::sanitizeFilterString($record['L']) : '';
795
                $country =  isset($record['M']) ? Functions::sanitizeFilterString($record['M']) : '';
796
                $isAdult = isset($record['N']) ? Functions::sanitizeFilterString($record['N']) : '';
797
 
798
                if($row == 1) {
799
                    continue;
1 www 800
                }
801
 
17261 stevensc 802
                //||  empty($password)
803
                if(empty($first_name) || empty($last_name) || !filter_var($email, FILTER_VALIDATE_EMAIL) ) {
804
                    continue;
1 www 805
                }
806
 
17261 stevensc 807
                if(!in_array($email, $emails)) {
1 www 808
                    $user = $userMapper->fetchOneByEmail($email);
17261 stevensc 809
                    $assigned_topics = $user ? $topicUserMapper->fetchCountByCompanyIdAndTopicIdAndUserId($topic->company_id, $topic->id, $user->id) : 0;
810
                    $count_users++;
1 www 811
 
17261 stevensc 812
                    array_push($emails, $email);
813
                    array_push($users, [
814
                        'id' => $count_users,
815
                        'first_name' => $first_name,
816
                        'last_name' => $last_name,
817
                        'password'  => $password,
818
                        'email' => $email,
819
                        'assigned_topics' => $assigned_topics,
820
                        'company' => $company,
821
                        'function' => $function,
822
                        'group' => $group,
823
                        'institution' => $institution,
824
                        'program' => $program,
825
                        'partner' => $partner,
826
                        'sector' => $sector,
827
                        'studentType' => $studentType,
828
                        'country' => $country,
829
                        'isAdult' => $isAdult,
830
                    ]);
831
                } else {
832
                    $count_errors++;
833
                    array_push($errors,[
834
                        'id' => $count_errors,
835
                        'first_name' => $first_name,
836
                        'last_name' => $last_name,
837
                        'password'  => $password,
838
                        'email' => $email,
839
                        'status' => 'DUPLICATE IN EXCEL'
840
                    ]);
841
                }
842
            }
4 efrain 843
 
17261 stevensc 844
            try {
845
                $key = md5($currentUser->id . '-' . $topic->uuid . '-' . $topic->uuid);
846
                $this->cache->setItem($key, serialize($users));
847
            } catch (\Exception $e) {
1 www 848
                return new JsonModel([
849
                    'success' => false,
17261 stevensc 850
                    'data' => 'ERROR_CACHE_SET_ITEM' . $e->getMessage()
851
                ]);
852
            }
1 www 853
 
17261 stevensc 854
            return new JsonModel([
855
                'success' => true,
856
                'data' => [
857
                    'key' => $key,
858
                    'topic' => $topic->name,
859
                    'items' => [
860
                        'ok' => $users,
861
                        'error' => $errors,
862
                    ],
863
                ]
864
            ]);
1 www 865
        }
866
 
867
        return new JsonModel([
868
            'success' => false,
17261 stevensc 869
            'data' => 'ERROR_PARAMETERS_ARE_INVALID'
1 www 870
        ]);
871
    }
872
 
17248 stevensc 873
    /**
874
     * Handles sending push notifications to selected users about a microlearning topic
875
     *
876
     * This action processes push notifications for microlearning topics:
877
     * 1. Validates user permissions and input data
878
     * 2. Processes the notification form
879
     * 3. Sends push notifications to selected users' devices
880
     *
881
     * Required parameters:
882
     * - topic_uuid: UUID of the microlearning topic
883
     * - customer_uuids: Array of user UUIDs to receive the notification
884
     * - push_template_id: UUID of the push notification template to use
885
     *
886
     * @return JsonModel Returns JSON response with:
887
     *                   - success: true/false
888
     *                   - data: Contains push_to_send count or error message
889
     * @throws \Throwable When an error occurs during processing
890
     */
1 www 891
    public function notificationAction()
892
    {
17248 stevensc 893
        try {
894
            // Get current request and user context
895
            $request = $this->getRequest();
1 www 896
 
17248 stevensc 897
            $currentUserPlugin = $this->plugin('currentUserPlugin');
898
            $currentUser    = $currentUserPlugin->getUser();
899
            $currentCompany = $currentUserPlugin->getCompany();
900
 
901
            $topic_uuid     = $this->params()->fromRoute('topic_uuid');
902
 
903
            // Validate topic UUID exists
904
            if(!$topic_uuid) {
905
                return new JsonModel([
906
                    'success'   => false,
907
                    'data'   => 'ERROR_TOPIC_UUID_NOT_FOUND'
908
                ]);
909
            }
910
 
911
            // Validate company exists
912
            if(!$currentCompany) {
913
                return new JsonModel([
914
                    'success'   => false,
915
                    'data'   => 'ERROR_COMPANY_NOT_FOUND'
916
                ]);
917
            }
918
 
919
            // Fetch and validate topic
920
            $topicMapper = MicrolearningTopicMapper::getInstance($this->adapter);
921
            $topic = $topicMapper->fetchOneByUuid($topic_uuid);
922
            if(!$topic) {
923
                return new JsonModel([
924
                    'success'   => false,
925
                    'data'   => 'ERROR_TOPIC_NOT_FOUND'
926
                ]);
927
            }
1 www 928
 
17248 stevensc 929
            // Validate topic belongs to current company
930
            if($topic->company_id != $currentCompany->id) {
931
                return new JsonModel([
932
                    'success'   => false,
933
                    'data'   => 'ERROR_UNAUTHORIZED'
934
                ]);
935
            }
936
 
937
            // Validate request method
938
            if(!$request->isPost()) {
939
                return new JsonModel([
940
                    'success' => false,
941
                    'data' => 'ERROR_METHOD_NOT_ALLOWED'
942
                ]);
943
            }
944
 
945
            // Process notification form
1 www 946
            $dataPost = $request->getPost()->toArray();
15390 efrain 947
            $form = new PushMicrolearningNotificationForm($this->adapter, $currentCompany->id);
1 www 948
 
949
            $form->setData($dataPost);
950
 
17248 stevensc 951
            // Validate form data
952
            if(!$form->isValid()) {
953
                $messages = [];
954
                $form_messages = (array) $form->getMessages();
955
                foreach($form_messages  as $fieldname => $field_messages)
956
                {
957
                    $messages[$fieldname] = array_values($field_messages);
1 www 958
                }
959
 
17248 stevensc 960
                return new JsonModel([
961
                    'success'   => false,
962
                    'data'      => $messages
963
                ]);
964
            }
965
 
966
            // Validate selected users
967
            $customer_uuids = $this->params()->fromPost('customer_uuids');
968
            if(!$customer_uuids) {
969
                return new JsonModel([
970
                    'success' => false,
971
                    'data' => 'ERROR_NOT_SELECTED_CUSTOMERS'
972
                ]);
1 www 973
 
17248 stevensc 974
            }
975
 
976
            // Get push template
977
            $push_template_uuid = Functions::sanitizeFilterString($form->get('push_template_id')->getValue());
978
            $pushMapper = PushMapper::getInstance($this->adapter);
979
            $pushTemplateMapper = PushTemplateMapper::getInstance($this->adapter);
980
            $pushTemplate = $pushTemplateMapper->fetchOneByUuid($push_template_uuid);
981
 
982
            if(!$pushTemplate) {
983
                return new JsonModel([
984
                    'success' => false,
985
                    'data' => 'ERROR_PUSH_TEMPLATE_NOT_FOUND'
986
                ]);
987
            }
988
 
989
            // Initialize push notification process
990
            $applicationMapper = ApplicationMapper::getInstance($this->adapter);
991
            $application = $applicationMapper->fetchOne(Application::TWOGETSKILLS);
992
 
993
            $topicUserMapper = MicrolearningTopicUserMapper::getInstance($this->adapter);
994
 
995
            $push_to_send = 0;
996
 
997
            // Process each selected user
998
            $userMapper = UserMapper::getInstance($this->adapter);
999
            $deviceHistoryMapper = DeviceHistoryMapper::getInstance($this->adapter);
1000
            foreach($customer_uuids as $customer_uuid)
1001
            {
1002
                $user = $userMapper->fetchOneByUuid($customer_uuid);
1003
                if(!$user) {
1004
                    continue;
1 www 1005
                }
1006
 
17248 stevensc 1007
                $topicUser = $topicUserMapper->fetchOneByUserIdAndTopicId($user->id, $topic->id);
1008
                if(!$topicUser) {
1009
                    continue;
1010
                }
1 www 1011
 
17248 stevensc 1012
                // Get user's latest device
1013
                $device = $deviceHistoryMapper->fetchLastDeviceByApplicationIdAndUserId(Application::TWOGETSKILLS, $user->id);
1 www 1014
 
17248 stevensc 1015
                if($device && $device->token) {
1 www 1016
 
17248 stevensc 1017
                    $key = $application->key;
1018
                    if($device->variant_id) {
13755 efrain 1019
 
17248 stevensc 1020
                        $applicationVariantMapper = ApplicationVariantMapper::getInstance($this->adapter);
1021
                        $applicationVariant = $applicationVariantMapper->fetchOneByApplicationIdAndVariantId($device->application_id, $device->variant_id);
1022
                        if($applicationVariant) {
1023
                            $key = $applicationVariant->key;
1024
                        } else {
1025
                            $applicationVariant = $applicationVariantMapper->fetchOneByApplicationIdAndDefault($device->application_id);
13755 efrain 1026
                            if($applicationVariant) {
1027
                                $key = $applicationVariant->key;
1028
                            }
1029
                        }
1030
 
17248 stevensc 1031
                    }
1032
 
1033
                    // Create push notification
1034
                    $push = new Push();
1035
                    $push->status = Push::STATUS_PENDING;
1036
                    $push->data = json_encode([
1037
                        'server' => [
1038
                            'key' => $key,
1039
                        ],
1040
                        'push' => [
1041
                            'registration_ids'   => [
1042
                                $device->token,
1 www 1043
                            ],
17248 stevensc 1044
                            'notification' => [
1045
                                'body' =>  $pushTemplate->body,
1046
                                'title' => $pushTemplate->title,
1047
                                'vibrate' => 1,
1048
                                'sound' =>  1
1049
                            ],
1050
                            'data' => [
1051
                                'command' => 'content-refresh',
1052
                                'new_topics' => '0',
1 www 1053
                            ]
17248 stevensc 1054
                        ]
1055
                    ]);
1056
 
1057
                    if($pushMapper->insert($push)) {
1058
                        $push_to_send = $push_to_send + 1;
1 www 1059
                    }
17248 stevensc 1060
 
1 www 1061
                }
17248 stevensc 1062
            }
1063
 
1064
            // Validate notifications were created
1065
            if(0 == $push_to_send) {
1 www 1066
                return new JsonModel([
17248 stevensc 1067
                    'success' => false,
1068
                    'data' => 'ERROR_NO_USER_DEVICES_WERE_FOUND_TO_SEND_PUSH'
1 www 1069
                ]);
1070
            }
17248 stevensc 1071
 
1072
            return new JsonModel([
1073
                'success' => true,
1074
                'data' => [
1075
                    'push_to_send' => $push_to_send,
1076
                ]
1077
            ]);
1078
        } catch (\Throwable $e) {
1079
            $this->logger->error($e->getMessage());
1080
            return new JsonModel([
1081
                'success' => false,
1082
                'data' => 'ERROR_INTERNAL_SERVER_ERROR'
1083
            ]);
1 www 1084
        }
17248 stevensc 1085
    }
1 www 1086
}