Proyectos de Subversion LeadersLinked - Backend

Rev

Rev 17270 | | 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
    {
17262 stevensc 649
        try {
650
            $request = $this->getRequest();
651
 
652
            $currentUserPlugin = $this->plugin('currentUserPlugin');
653
            $currentNetworkPlugin = $this->plugin('currentNetworkPlugin');
17261 stevensc 654
 
17262 stevensc 655
            $currentUser    = $currentUserPlugin->getUser();
656
            $currentCompany = $currentUserPlugin->getCompany();
657
            $currentNetwork = $currentNetworkPlugin->getNetwork();
658
 
659
            $topic_uuid     = $this->params()->fromRoute('topic_uuid');
17261 stevensc 660
 
17262 stevensc 661
            if(!$currentUser) {
662
                $this->logger->err('Upload failed: Current user not found');
663
                return new JsonModel([
664
                    'success'   => false,
665
                    'data'   => 'ERROR_USER_NOT_FOUND'
666
                ]);
667
            }
17261 stevensc 668
 
17262 stevensc 669
            if(!$currentCompany) {
670
                $this->logger->err('Upload failed: Current company not found');
671
                return new JsonModel([
672
                    'success'   => false,
673
                    'data'   => 'ERROR_COMPANY_NOT_FOUND'
674
                ]);
675
            }
17261 stevensc 676
 
17262 stevensc 677
            if(!$currentNetwork) {
678
                $this->logger->err('Upload failed: Current network not found');
679
                return new JsonModel([
680
                    'success'   => false,
681
                    'data'   => 'ERROR_NETWORK_NOT_FOUND'
682
                ]);
683
            }
17261 stevensc 684
 
17262 stevensc 685
            if(!$topic_uuid) {
686
                $this->logger->err('Upload failed: Topic UUID not provided');
687
                return new JsonModel([
688
                    'success'   => false,
689
                    'data'   => 'ERROR_TOPIC_NOT_FOUND'
690
                ]);
691
            }
17261 stevensc 692
 
17262 stevensc 693
            if(!$request->isPost()) {
694
                $this->logger->err('Upload failed: Request method not POST');
695
                return new JsonModel([
696
                    'success'   => false,
697
                    'data'   => 'ERROR_METHOD_NOT_ALLOWED'
698
                ]);
699
            }
1 www 700
 
17262 stevensc 701
            $topicMapper = MicrolearningTopicMapper::getInstance($this->adapter);
702
            $topic = $topicMapper->fetchOneByUuid($topic_uuid);
17261 stevensc 703
 
17262 stevensc 704
            if(!$topic) {
705
                $this->logger->err('Upload failed: Topic not found for UUID: ' . $topic_uuid);
17261 stevensc 706
                return new JsonModel([
17262 stevensc 707
                    'success'   => false,
708
                    'data'   => 'ERROR_TOPIC_NOT_FOUND'
17261 stevensc 709
                ]);
710
            }
711
 
17262 stevensc 712
            if($topic->company_id != $currentCompany->id) {
713
                $this->logger->err('Upload failed: Topic does not belong to current company');
714
                return new JsonModel([
715
                    'success'   => false,
716
                    'data'   => 'ERROR_UNAUTHORIZED'
717
                ]);
718
            }
17261 stevensc 719
 
17262 stevensc 720
            $step = Functions::sanitizeFilterString($this->params()->fromPost('step'));
1 www 721
 
17262 stevensc 722
            if($step == 'validation') {
723
                try {
724
                    $userMapper = UserMapper::getInstance($this->adapter);
725
                    $topicUserMapper = MicrolearningTopicUserMapper::getInstance($this->adapter);
17271 stevensc 726
                    $storage = Storage::getInstance($this->config, $this->adapter);
727
 
728
                    // Log uploaded files info
729
                    $files = $request->getFiles()->toArray();
730
                    $this->logger->info('Uploaded files: ' . print_r($files, true));
731
 
732
                    $storage->setFiles($files);
733
 
734
                    if(!$storage->setCurrentFilename('file')) {
735
                        $this->logger->err('Upload failed: Could not set current filename');
736
                        return new JsonModel([
737
                            'success' => false,
738
                            'data' => 'ERROR_UPLOAD_FILE'
739
                        ]);
740
                    }
17262 stevensc 741
 
742
                    $tmp_filename = $storage->getTmpFilename();
743
                    $filename = $storage->getFilename();
744
                    $target_filename = $storage->composePathToFilename(
745
                        Storage::TYPE_MICROLEARNING_ACCESS_FOR_STUDENTS,
746
                        $topic->uuid,
747
                        $filename
748
                    );
1 www 749
 
17262 stevensc 750
                    $this->logger->info('Processing file upload: ' . $target_filename);
751
 
752
                    if(!$storage->putFile($tmp_filename, $target_filename)) {
753
                        $this->logger->err('Upload failed: Could not move file to target location');
754
                        return new JsonModel([
755
                            'success' => false,
756
                            'data' => 'ERROR_UPLOAD_FILE'
757
                        ]);
758
                    }
759
 
760
                    $count_users = 0;
761
                    $users = [];
762
                    $count_errors = 0;
763
                    $errors = [];
764
 
765
                    try {
766
                        $this->logger->info('Loading spreadsheet: ' . $target_filename);
767
                        $spreadsheet = IOFactory::load($target_filename);
768
                        $records = $spreadsheet->getActiveSheet()->toArray(null, true, true, true);
769
                    } catch (\Exception $e) {
770
                        $this->logger->err('Spreadsheet processing failed: ' . $e->getMessage());
771
                        return new JsonModel([
772
                            'success' => false,
773
                            'data' => 'ERROR_UPLOAD_FILE: ' . $e->getMessage()
774
                        ]);
775
                    }
776
 
777
                    $emails = [];
778
                    $row = 0;
779
 
780
                    foreach($records as $record)
781
                    {
782
                        /*
783
                        A = Nombre
784
                        B = Apellido
785
                        C = Email
786
                        D = Contraseña
787
                        E = Empresa
788
                        F = Función
789
                        G = Grupo
790
                        H = Institución
791
                        I = Programa
792
                        J = Socio
793
                        K = Sector
794
                        L = Tipo de Estudiante
795
                        M = País
796
                        N = Es adulto
797
                        */
798
                        $row++;
799
 
800
                        $first_name = Functions::sanitizeFilterString($record['A']);
801
                        $last_name = Functions::sanitizeFilterString($record['B']);
802
                        $email = trim(filter_var($record['C'], FILTER_SANITIZE_EMAIL));
803
                        $password = Functions::sanitizeFilterString($record['D']);
804
 
805
                        $company =  isset($record['E']) ? Functions::sanitizeFilterString($record['E']) : '';
806
                        $function = isset($record['F']) ? Functions::sanitizeFilterString($record['F']) : '';
807
                        $group = isset($record['G']) ? Functions::sanitizeFilterString($record['G']) : '';
808
                        $institution = isset($record['H']) ? Functions::sanitizeFilterString($record['H']) : '';
809
                        $program = isset($record['I']) ? Functions::sanitizeFilterString($record['I']) : '';
810
                        $partner = isset($record['J']) ? Functions::sanitizeFilterString($record['J']) : '';
811
                        $sector = isset($record['K']) ? Functions::sanitizeFilterString($record['K']) : '';
812
                        $studentType = isset($record['L']) ? Functions::sanitizeFilterString($record['L']) : '';
813
                        $country =  isset($record['M']) ? Functions::sanitizeFilterString($record['M']) : '';
814
                        $isAdult = isset($record['N']) ? Functions::sanitizeFilterString($record['N']) : '';
815
 
816
                        if($row == 1) {
817
                            continue;
818
                        }
819
 
820
                        //||  empty($password)
821
                        if(empty($first_name) || empty($last_name) || !filter_var($email, FILTER_VALIDATE_EMAIL) ) {
822
                            continue;
823
                        }
824
 
825
                        if(!in_array($email, $emails)) {
826
                            $user = $userMapper->fetchOneByEmail($email);
827
                            $assigned_topics = $user ? $topicUserMapper->fetchCountByCompanyIdAndTopicIdAndUserId($topic->company_id, $topic->id, $user->id) : 0;
828
                            $count_users++;
829
 
830
                            array_push($emails, $email);
831
                            array_push($users, [
832
                                'id' => $count_users,
833
                                'first_name' => $first_name,
834
                                'last_name' => $last_name,
835
                                'password'  => $password,
836
                                'email' => $email,
837
                                'assigned_topics' => $assigned_topics,
838
                                'company' => $company,
839
                                'function' => $function,
840
                                'group' => $group,
841
                                'institution' => $institution,
842
                                'program' => $program,
843
                                'partner' => $partner,
844
                                'sector' => $sector,
845
                                'studentType' => $studentType,
846
                                'country' => $country,
847
                                'isAdult' => $isAdult,
848
                            ]);
849
                        } else {
850
                            $count_errors++;
851
                            array_push($errors,[
852
                                'id' => $count_errors,
853
                                'first_name' => $first_name,
854
                                'last_name' => $last_name,
855
                                'password'  => $password,
856
                                'email' => $email,
857
                                'status' => 'DUPLICATE IN EXCEL'
858
                            ]);
859
                        }
860
                    }
861
 
17269 stevensc 862
                    $this->logger->info('Users: ' . print_r($users, true));
863
                    $this->logger->info('Errors: ' . print_r($errors, true));
864
 
17268 stevensc 865
                    try {
17269 stevensc 866
                        $this->logger->info('Cache users: ' . print_r($users, true));
17268 stevensc 867
                        $key = md5($currentUser->id . '-' . $topic->uuid . '-' . $topic->uuid);
868
                        $this->cache->setItem($key, serialize($users));
869
                    } catch (\Exception $e) {
870
                        $this->logger->err('Cache operation failed: ' . $e->getMessage());
871
                        return new JsonModel([
872
                            'success' => false,
873
                            'data' => 'ERROR_CACHE_SET_ITEM: ' . $e->getMessage()
874
                        ]);
875
                    }
17267 stevensc 876
 
17262 stevensc 877
                    return new JsonModel([
878
                        'success' => true,
879
                        'data' => [
17268 stevensc 880
                            'key' => $key,
17262 stevensc 881
                            'topic' => $topic->name,
882
                            'items' => [
883
                                'ok' => $users,
884
                                'error' => $errors,
885
                            ],
886
                        ]
17261 stevensc 887
                    ]);
17262 stevensc 888
                } catch (\Exception $e) {
889
                    $this->logger->err('Validation step failed: ' . $e->getMessage());
890
                    throw $e;
17261 stevensc 891
                }
892
            }
17270 stevensc 893
 
894
            if($step == 'process') {
895
                $key = Functions::sanitizeFilterString($this->params()->fromPost('key'));
17271 stevensc 896
 
17270 stevensc 897
                if(!$key) {
898
                    return new JsonModel([
899
                        'success' => false,
900
                        'data' => 'ERROR_CACHE_KEY_EMPTY'
901
                    ]);
902
                }
17271 stevensc 903
 
17270 stevensc 904
                $value = $this->cache->getItem($key);
17271 stevensc 905
 
17270 stevensc 906
                if(!$value) {
907
                    return new JsonModel([
908
                        'success' => false,
909
                        'data' => 'ERROR_CACHE_NOT_FOUND'
910
                    ]);
911
                }
912
 
913
                $records = unserialize($value);
914
                $this->logger->info('Records: ' . print_r($records, true));
17271 stevensc 915
 
17270 stevensc 916
                if(!$records) {
917
                    return new JsonModel([
918
                        'success' => false,
919
                        'data' => 'ERROR_CACHE_INVALID'
920
                    ]);
921
                }
922
 
923
                // get the network, company, company follower
924
                $networkMapper = NetworkMapper::getInstance($this->adapter);
925
                $companyMapper = CompanyMapper::getInstance($this->adapter);
926
                $companyFollowerMapper = CompanyFollowerMapper::getInstance($this->adapter);
927
 
928
                // get the connection, user, user password, topic user
929
                $connectionMapper = ConnectionMapper::getInstance($this->adapter);
930
                $userMapper = UserMapper::getInstance($this->adapter);
931
                $userPasswordMapper = UserPasswordMapper::getInstance($this->adapter);
932
                $topicUserMapper = MicrolearningTopicUserMapper::getInstance($this->adapter);
933
 
934
                // get the microlearning extend user, microlearning extend user company, microlearning extend user function, microlearning extend user group, microlearning extend user institution, microlearning extend user program, microlearning extend user partner, microlearning extend user sector, microlearning extend user student type, microlearning extend user country
935
                $microlearningExtendUserMapper = MicrolearningExtendUserMapper::getInstance($this->adapter);
936
                $microlearningExtendUserCompanyMapper = MicrolearningExtendUserCompanyMapper::getInstance($this->adapter);
937
                $microlearningExtendUserFunctionMapper = MicrolearningExtendUserFunctionMapper::getInstance($this->adapter);
938
                $microlearningExtendUserGroupMapper = MicrolearningExtendUserGroupMapper::getInstance($this->adapter);
939
                $microlearningExtendUserInstitutionMapper = MicrolearningExtendUserInstitutionMapper::getInstance($this->adapter);
940
                $microlearningExtendUserProgramMapper = MicrolearningExtendUserProgramMapper::getInstance($this->adapter);
941
                $microlearningExtendUserPartnerMapper = MicrolearningExtendUserPartnerMapper::getInstance($this->adapter);
942
                $microlearningExtendUserSectorMapper = MicrolearningExtendUserSectorMapper::getInstance($this->adapter);
943
                $microlearningExtendUserStudentTypeMapper = MicrolearningExtendUserStudentTypeMapper::getInstance($this->adapter);
944
                $microlearningExtendUserCountryMapper = MicrolearningExtendUserCountryMapper::getInstance($this->adapter);
945
 
946
                // get the network default, user default for connection, company for follower
947
                $networkDefault = $networkMapper->fetchOneByDefault();
948
                $userDefaultForConnection = $userMapper->fetchOneDefaultForConnection();
949
 
950
                $companyForFollower = $companyMapper->fetchOneDefaultForFollowers();
951
 
952
                // create the csv
953
                $csv = "FIRST NAME|LAST NAME|EMAIL|STATUS\r\n";
954
 
955
                // get the users processed, users assigned, user ids
956
                $users_processed = 0;
957
                $users_assigned = 0;
958
                $user_ids = [];
959
                foreach($records as $record)
960
                {
961
                    $first_name = $record['first_name'];
962
                    $last_name = $record['last_name'];
963
                    $password = $record['password'];
964
                    $email = $record['email'];
965
                    $company = $record['company'];
966
                    $function = $record['function'];
967
                    $group = $record['group'];
968
                    $institution = $record['institution'];
969
                    $program = $record['program'];
970
                    $partner = $record['partner'];
971
                    $sector = $record['sector'];
972
                    $studentType = $record['studentType'];
973
                    $country = $record['country'];
974
                    $isAdult = strtolower(trim( $record['isAdult'])) == User::IS_ADULT_YES;
975
 
976
                    $user = $userMapper->fetchOneByEmail($email);
977
 
978
                    // if the user is not found, create the user
979
                    if(!$user) {
980
                        // if the password is not empty, create the user
981
                        if($password) {
982
                            $password_hash = password_hash($password, PASSWORD_DEFAULT);
983
 
984
                            $user = new User();
985
 
986
                            $user->network_id = $currentNetwork->id;
987
                            $user->blocked = User::BLOCKED_NO;
988
                            $user->email_verified = User::EMAIL_VERIFIED_YES;
989
                            $user->email = $email;
990
                            $user->first_name = $first_name;
991
                            $user->last_name = $last_name;
992
                            $user->password = $password_hash;
993
                            $user->login_attempt = 0;
994
                            $user->usertype_id = UserType::USER;
995
                            $user->status = User::STATUS_ACTIVE;
996
                            $user->is_adult = $isAdult ? User::IS_ADULT_YES : User::IS_ADULT_NO;
997
 
998
                            $result = $userMapper->insert($user);
999
                            if($result) {
1000
                                $userPassword = new UserPassword();
1001
                                $userPassword->user_id = $user->id;
1002
                                $userPassword->password = $password_hash;
1003
                                $userPasswordMapper->insert($userPassword);
1004
 
1005
 
1006
                                $csv .= "$first_name|$last_name|$email|CREATE USER \r\n";
1007
                            } else {
1008
                                $csv .= "$first_name|$last_name|$email|FAIL CREATE USER \r\n";
1009
 
1010
                                continue;
1011
                            }
1012
 
1013
                        }
1014
                    } else {
1015
                        $user->is_adult = $isAdult ? User::IS_ADULT_YES : User::IS_ADULT_NO;
1016
                        if($user->email_verified == User::EMAIL_VERIFIED_NO || $user->status != User::STATUS_ACTIVE) {
1017
                            $user->email_verified = User::EMAIL_VERIFIED_YES;
1018
                            $user->status != User::STATUS_ACTIVE;
1019
                        }
1020
                        if(!$userMapper->update($user)) {
1021
                            $csv .= "$first_name|$last_name|$email|FAIL UPDATE USER \r\n";
1022
                            continue;
1023
                        }
1024
                    }
1025
 
1026
 
1027
                    $user_id_in_default_network = 0;
1028
                    if($user->is_adult == User::IS_ADULT_YES) {
1029
 
1030
                        if($currentNetwork->default == Network::DEFAULT_YES) {
1031
 
1032
                            $user_id_in_default_network = $user->id;
1033
 
1034
 
1035
 
1036
                        } else {
1037
 
1038
                            $userInDefaultNetwork = $userMapper->fetchOneByEmailAndNetworkId($user->email, $networkDefault->id);
1039
                            if($userInDefaultNetwork) {
1040
                                $user_id_in_default_network = $userInDefaultNetwork->id;
1041
 
1042
                                if($userInDefaultNetwork->email_verified == User::EMAIL_VERIFIED_NO || $userInDefaultNetwork->status != User::STATUS_ACTIVE) {
1043
                                    $userInDefaultNetwork->email_verified = User::EMAIL_VERIFIED_YES;
1044
                                    $userInDefaultNetwork->status != User::STATUS_ACTIVE;
1045
 
1046
                                    if(!$userMapper->update($userInDefaultNetwork)) {
1047
                                        $csv .= "$first_name|$last_name|$email|FAIL UPDATE USER IN DEFAULT NETWORK \r\n";
1048
                                        continue;
1049
                                    }
1050
                                }
1051
 
1052
 
1053
                            } else {
1054
                                $userInDefaultNetwork = new User();
1055
                                $userInDefaultNetwork->network_id = $networkDefault->id;
1056
                                $userInDefaultNetwork->blocked = User::BLOCKED_NO;
1057
                                $userInDefaultNetwork->email_verified = User::EMAIL_VERIFIED_YES;
1058
                                $userInDefaultNetwork->email = $email;
1059
                                $userInDefaultNetwork->first_name = $first_name;
1060
                                $userInDefaultNetwork->last_name = $last_name;
1061
                                $userInDefaultNetwork->password = $password_hash;
1062
                                $userInDefaultNetwork->login_attempt = 0;
1063
                                $userInDefaultNetwork->usertype_id = UserType::USER;
1064
                                $userInDefaultNetwork->status = User::STATUS_ACTIVE;
1065
                                $userInDefaultNetwork->is_adult = $isAdult == User::IS_ADULT_YES;
1066
                                $result = $userMapper->insert($userInDefaultNetwork);
1067
                                if($result) {
1068
                                    $user_id_in_default_network = $userInDefaultNetwork->id;
1069
 
1070
 
1071
                                    $userPassword = new UserPassword();
1072
                                    $userPassword->user_id = $userInDefaultNetwork->id;
1073
                                    $userPassword->password = $password_hash;
1074
                                    $userPasswordMapper->insert($userPassword);
1075
 
1076
                                    $csv .= "$first_name|$last_name|$email|CREATE USER IN DEFAULT NETWORK \r\n";
1077
                                } else {
1078
                                    $csv .= "$first_name|$last_name|$email|FAIL CREATE USER IN DEFAULT NETWORK \r\n";
1079
                                }
1080
 
1081
                            }
1082
 
1083
 
1084
                        }
1085
                    }
1086
 
1087
                    if($user_id_in_default_network) {
1088
 
1089
                        if($userDefaultForConnection) {
1090
 
1091
                            $connection = $connectionMapper->fetchOneByUserId1AndUserId2($userDefaultForConnection->id, $user_id_in_default_network);
1092
                            if($connection) {
1093
                                if($connection->status != Connection::STATUS_ACCEPTED) {
1094
                                    $connection->status = Connection::STATUS_ACCEPTED;
1095
                                    $connectionMapper->update($connection);
1096
 
1097
                                }
1098
 
1099
 
1100
                            } else {
1101
                                $connection = new Connection();
1102
                                $connection->request_to = $user_id_in_default_network;
1103
                                $connection->request_from = $userDefaultForConnection->id;
1104
                                $connection->status = Connection::STATUS_ACCEPTED;
1105
                                $connectionMapper->insert($connection);
1106
                            }
1107
                        }
1108
 
1109
                        if($companyForFollower) {
1110
                            $companyFollower = $companyFollowerMapper->fetchOneByCompanyIdAndUserId($companyForFollower->id, $user_id_in_default_network);
1111
                            if(!$companyFollower) {
1112
                                $companyFollower = new CompanyFollower();
1113
                                $companyFollower->company_id = $companyForFollower->id;
1114
                                $companyFollower->follower_id = $user_id_in_default_network;
1115
 
1116
                                $companyFollowerMapper->insert($companyFollower);
1117
 
1118
 
1119
                            }
1120
                        }
1121
 
1122
 
1123
                    }
1124
 
1125
 
1126
                    if(!in_array($user->id, $user_ids)) {
1127
                        array_push($user_ids, $user->id);
1128
                    }
1129
 
1130
                    /*
1131
                    echo '$filterCompany = ' . $filterCompany . PHP_EOL;
1132
                    echo '$filterFunctio = ' . $filterFunction . PHP_EOL;
1133
                    echo '$filterGroup = ' . $filterGroup . PHP_EOL;
1134
                    echo '$filterInstitution = ' . $filterInstitution . PHP_EOL;
1135
                    echo '$filterPartner = ' . $filterPartner . PHP_EOL;
1136
                    echo '$filterProgram = ' . $filterProgram . PHP_EOL;
1137
                    echo '$filterSector = ' . $filterSector . PHP_EOL;
1138
                    echo '$filterStudentType = ' . $filterStudentType . PHP_EOL;
1139
                    */
1140
 
1141
 
1142
                    $extendUser = $microlearningExtendUserMapper->fetchOneByCompanyIdAndUserId($currentCompany->id, $user->id);
1143
                    if(!$extendUser) {
1144
                        $extendUser = new MicrolearningExtendUser();
1145
                        $extendUser->company_id = $currentCompany->id;
1146
                        $extendUser->user_id = $user->id;
1147
                    }
1148
 
1149
 
1150
                    if($company) {
1151
                        $record = $microlearningExtendUserCompanyMapper->fetchOneByCompanyIdAndName($currentCompany->id, $company);
1152
 
1153
                        if(!$record) {
1154
                            $record = new MicrolearningExtendUserCompany();
1155
                            $record->company_id = $currentCompany->id;
1156
                            $record->name = $company;
1157
 
1158
                            $microlearningExtendUserCompanyMapper->insert($record);
1159
                        }
1160
 
1161
 
1162
 
1163
 
1164
                        if($record->id) {
1165
                            $extendUser->extend_company_id = $record->id;
1166
                        }
1167
                    }
1168
 
1169
                    if($function) {
1170
                        $record = $microlearningExtendUserFunctionMapper->fetchOneByCompanyIdAndName($currentCompany->id, $function);
1171
                        if(!$record) {
1172
                            $record = new MicrolearningExtendUserFunction();
1173
                            $record->company_id = $currentCompany->id;
1174
                            $record->name = $function;
1175
 
1176
                            $microlearningExtendUserFunctionMapper->insert($record);
1177
                        }
1178
 
1179
                        if($record->id) {
1180
                            $extendUser->extend_function_id = $record->id;
1181
                        }
1182
                    }
1183
 
1184
                    if($group) {
1185
                        $record = $microlearningExtendUserGroupMapper->fetchOneByCompanyIdAndName($currentCompany->id, $group);
1186
                        if(!$record) {
1187
                            $record = new MicrolearningExtendUserGroup();
1188
                            $record->company_id = $currentCompany->id;
1189
                            $record->name = $group;
1190
 
1191
                            $microlearningExtendUserGroupMapper->insert($record);
1192
                        }
1193
 
1194
                        if($record->id) {
1195
                            $extendUser->extend_group_id = $record->id;
1196
                        }
1197
                    }
1198
 
1199
                    if($institution) {
1200
                        $record = $microlearningExtendUserInstitutionMapper->fetchOneByCompanyIdAndName($currentCompany->id, $institution);
1201
                        if(!$record) {
1202
                            $record = new MicrolearningExtendUserInstitution();
1203
                            $record->company_id = $currentCompany->id;
1204
                            $record->name = $institution;
1205
 
1206
                            $microlearningExtendUserInstitutionMapper->insert($record);
1207
                        }
1208
 
1209
                        if($record->id) {
1210
                            $extendUser->extend_institution_id = $record->id;
1211
                        }
1212
                    }
1213
 
1214
                    if($program) {
1215
                        $record = $microlearningExtendUserProgramMapper->fetchOneByCompanyIdAndName($currentCompany->id, $program);
1216
                        if(!$record) {
1217
                            $record = new MicrolearningExtendUserProgram();
1218
                            $record->company_id = $currentCompany->id;
1219
                            $record->name = $program;
1220
 
1221
                            $microlearningExtendUserProgramMapper->insert($record);
1222
                        }
1223
 
1224
                        if($record->id) {
1225
                            $extendUser->extend_program_id = $record->id;
1226
                        }
1227
                    }
1228
 
1229
                    if($partner) {
1230
 
1231
 
1232
                        $record = $microlearningExtendUserPartnerMapper->fetchOneByCompanyIdAndName($currentCompany->id, $partner);
1233
                        if(!$record) {
1234
                            $record = new MicrolearningExtendUserPartner();
1235
                            $record->company_id = $currentCompany->id;
1236
                            $record->name = $partner;
1237
 
1238
                            $microlearningExtendUserPartnerMapper->insert($record);
1239
                        }
1240
 
1241
                        if($record->id) {
1242
                            $extendUser->extend_partner_id = $record->id;
1243
                        }
1244
                    }
1245
 
1246
                    if($sector) {
1247
                        $record = $microlearningExtendUserSectorMapper->fetchOneByCompanyIdAndName($currentCompany->id, $sector);
1248
                        if(!$record) {
1249
                            $record = new MicrolearningExtendUserSector();
1250
                            $record->company_id = $currentCompany->id;
1251
                            $record->name = $sector;
1252
 
1253
                            $microlearningExtendUserSectorMapper->insert($record);
1254
                        }
1255
 
1256
                        if($record->id) {
1257
                            $extendUser->extend_sector_id = $record->id;
1258
                        }
1259
                    }
1260
 
1261
                    if($studentType) {
1262
                        $record = $microlearningExtendUserStudentTypeMapper->fetchOneByCompanyIdAndName($currentCompany->id, $studentType);
1263
                        if(!$record) {
1264
                            $record = new MicrolearningExtendUserStudentType();
1265
                            $record->company_id = $currentCompany->id;
1266
                            $record->name = $studentType;
1267
 
1268
                            $microlearningExtendUserStudentTypeMapper->insert($record);
1269
                        }
1270
                        if($record->id) {
1271
                            $extendUser->extend_student_type_id = $record->id;
1272
                        }
1273
                    }
1274
 
1275
                    if($country) {
1276
                        $record = $microlearningExtendUserCountryMapper->fetchOneByCompanyIdAndName($currentCompany->id, $country);
1277
                        if(!$record) {
1278
                            $record = new MicrolearningExtendUserCountry();
1279
                            $record->company_id = $currentCompany->id;
1280
                            $record->name = $country;
1281
 
1282
                            $microlearningExtendUserCountryMapper->insert($record);
1283
                        }
1284
                        if($record->id) {
1285
                            $extendUser->extend_country_id = $record->id;
1286
                        }
1287
                    }
1288
 
1289
 
1290
 
1291
 
1292
 
1293
                    if($extendUser->id) {
1294
                        $result =   $microlearningExtendUserMapper->update($extendUser);
1295
                    } else {
1296
                        $result = $microlearningExtendUserMapper->insert($extendUser);
1297
                    }
1298
 
1299
 
1300
 
1301
                }
1302
 
1303
                $notificationMapper = NotificationMapper::getInstance($this->adapter);
1304
 
1305
                $users_processed = 0;
1306
                $users_previous = 0;
1307
                foreach($user_ids as $user_id)
1308
                {
1309
                    $user = $userMapper->fetchOne($user_id);
1310
                    $first_name = $user->first_name;
1311
                    $last_name = $user->last_name;
1312
                    $email = $user->email;
1313
 
1314
 
1315
                    $users_processed++;
1316
                    $topicUser = $topicUserMapper->fetchOneByUserIdAndTopicId($user_id, $topic->id);
1317
                    if($topicUser) {
1318
                        $users_previous++;
1319
                        $csv .= "$first_name|$last_name|$email|PREVIOUS FOUND \r\n";
1320
                    } else {
1321
                        $topicUser = new MicrolearningTopicUser();
1322
                        $topicUser->company_id = $topic->company_id;
1323
                        $topicUser->topic_id = $topic->id;
1324
                        $topicUser->topic_id = $topic->id;
1325
                        $topicUser->user_id = $user_id;
1326
                        $topicUser->access = MicrolearningTopicUser::ACCESS_UNLIMITED;
1327
 
1328
                        if($topicUserMapper->insert($topicUser)) {
1329
 
1330
                            $notification = new Notification();
1331
                            $notification->company_id = $topic->company_id;
1332
                            $notification->user_id = $user_id;
1333
                            $notification->topic_id = $topic->id;
1334
                            $notification->topic_id = $topic->id;
1335
                            $notification->type = Notification::TYPE_NEW_MICROLEARNING_CAPSULE;
1336
                            $notification->message  = 'LABEL_NOTIFICATION_NEW_MICROLEARNING_CAPSULE' . ' : ' . $topic->name;
1337
                            $notification->url      = '/microlearning/topics/' . $topic->uuid .  '/detail';
1338
 
1339
                            $notificationMapper->insert($notification);
1340
 
1341
 
1342
                            $csv .= "$first_name|$last_name|$email|CAPSULE USER ASSIGNED\r\n";
1343
                            $users_assigned++;
1344
 
1345
 
1346
                            $topicUser = $topicUserMapper->fetchOne($topicUser->id);
1347
                            if($topicUser) {
1348
                                $microlearningUserMapper = MicrolearningUserMapper::getInstance($this->adapter);
1349
                                $microlearningUser = $microlearningUserMapper->fetchOneByUserIdAndCompanyId($topicUser->user_id, $topicUser->company_id);
1350
                                if($microlearningUser) {
1351
                                    $microlearningUser->updated_on = $topicUser->updated_on;
1352
 
1353
                                    $microlearningUserMapper->update($microlearningUser);
1354
 
1355
                                } else {
1356
                                    $microlearningUser = new MicrolearningUser();
1357
                                    $microlearningUser->company_id = $topicUser->company_id;
1358
                                    $microlearningUser->user_id = $topicUser->user_id;
1359
                                    $microlearningUser->added_on = $topicUser->added_on;
1360
                                    $microlearningUser->updated_on = $topicUser->updated_on;
1361
 
1362
                                    $microlearningUserMapper->insert($microlearningUser);
1363
                                }
1364
                            }
1365
                        } else {
1366
                            $csv .= "$first_name|$last_name|$email|CAPSULE USER PREVIOUS \r\n";
1367
                        }
1368
 
1369
                    }
1370
 
1371
 
1372
 
1373
                }
1374
 
1375
                $users_in_the_topic = $topicUserMapper->fetchCountByCompanyIdAndTopicId($topic->company_id, $topic->id);
1376
 
1377
                return new JsonModel([
1378
                    'success' => true,
1379
                    'data' => [
1380
                        'users_assigned' => $users_assigned,
1381
                        'users_processed' => $users_processed,
1382
                        'users_in_the_topic' => $users_in_the_topic,
1383
                        'users_previous' => $users_previous,
1384
                        'csv_base64_content' => base64_encode($csv),
1385
                        'csv_filename' => 'topic-users-' .date('Y-m-d-h-i-s').  '.csv'
1386
                    ]
17271 stevensc 1387
                ]);
17270 stevensc 1388
            }
17262 stevensc 1389
 
17271 stevensc 1390
 
17261 stevensc 1391
            return new JsonModel([
17262 stevensc 1392
                'success' => false,
1393
                'data' => 'ERROR_PARAMETERS_ARE_INVALID'
17261 stevensc 1394
            ]);
17262 stevensc 1395
        } catch (\Exception $e) {
1396
            $this->logger->err('Fatal error in uploadAction: ' . $e->getMessage() . "\n" . $e->getTraceAsString());
17263 stevensc 1397
            return new JsonModel([
17269 stevensc 1398
                'success' => false,
1399
                'data' => 'ERROR_INTERNAL_SERVER_ERROR'
1400
            ]);
1 www 1401
        }
1402
    }
1403
 
17248 stevensc 1404
    /**
1405
     * Handles sending push notifications to selected users about a microlearning topic
1406
     *
1407
     * This action processes push notifications for microlearning topics:
1408
     * 1. Validates user permissions and input data
1409
     * 2. Processes the notification form
1410
     * 3. Sends push notifications to selected users' devices
1411
     *
1412
     * Required parameters:
1413
     * - topic_uuid: UUID of the microlearning topic
1414
     * - customer_uuids: Array of user UUIDs to receive the notification
1415
     * - push_template_id: UUID of the push notification template to use
1416
     *
1417
     * @return JsonModel Returns JSON response with:
1418
     *                   - success: true/false
1419
     *                   - data: Contains push_to_send count or error message
1420
     * @throws \Throwable When an error occurs during processing
1421
     */
1 www 1422
    public function notificationAction()
1423
    {
17248 stevensc 1424
        try {
1425
            // Get current request and user context
1426
            $request = $this->getRequest();
1 www 1427
 
17248 stevensc 1428
            $currentUserPlugin = $this->plugin('currentUserPlugin');
1429
            $currentUser    = $currentUserPlugin->getUser();
1430
            $currentCompany = $currentUserPlugin->getCompany();
1431
 
1432
            $topic_uuid     = $this->params()->fromRoute('topic_uuid');
1433
 
1434
            // Validate topic UUID exists
1435
            if(!$topic_uuid) {
1436
                return new JsonModel([
1437
                    'success'   => false,
1438
                    'data'   => 'ERROR_TOPIC_UUID_NOT_FOUND'
1439
                ]);
1440
            }
1441
 
1442
            // Validate company exists
1443
            if(!$currentCompany) {
1444
                return new JsonModel([
1445
                    'success'   => false,
1446
                    'data'   => 'ERROR_COMPANY_NOT_FOUND'
1447
                ]);
1448
            }
1449
 
1450
            // Fetch and validate topic
1451
            $topicMapper = MicrolearningTopicMapper::getInstance($this->adapter);
1452
            $topic = $topicMapper->fetchOneByUuid($topic_uuid);
1453
            if(!$topic) {
1454
                return new JsonModel([
1455
                    'success'   => false,
1456
                    'data'   => 'ERROR_TOPIC_NOT_FOUND'
1457
                ]);
1458
            }
1 www 1459
 
17248 stevensc 1460
            // Validate topic belongs to current company
1461
            if($topic->company_id != $currentCompany->id) {
1462
                return new JsonModel([
1463
                    'success'   => false,
1464
                    'data'   => 'ERROR_UNAUTHORIZED'
1465
                ]);
1466
            }
1467
 
1468
            // Validate request method
1469
            if(!$request->isPost()) {
1470
                return new JsonModel([
1471
                    'success' => false,
1472
                    'data' => 'ERROR_METHOD_NOT_ALLOWED'
1473
                ]);
1474
            }
1475
 
1476
            // Process notification form
1 www 1477
            $dataPost = $request->getPost()->toArray();
15390 efrain 1478
            $form = new PushMicrolearningNotificationForm($this->adapter, $currentCompany->id);
1 www 1479
 
1480
            $form->setData($dataPost);
1481
 
17248 stevensc 1482
            // Validate form data
1483
            if(!$form->isValid()) {
1484
                $messages = [];
1485
                $form_messages = (array) $form->getMessages();
1486
                foreach($form_messages  as $fieldname => $field_messages)
1487
                {
1488
                    $messages[$fieldname] = array_values($field_messages);
1 www 1489
                }
1490
 
17248 stevensc 1491
                return new JsonModel([
1492
                    'success'   => false,
1493
                    'data'      => $messages
1494
                ]);
1495
            }
1496
 
1497
            // Validate selected users
1498
            $customer_uuids = $this->params()->fromPost('customer_uuids');
1499
            if(!$customer_uuids) {
1500
                return new JsonModel([
1501
                    'success' => false,
1502
                    'data' => 'ERROR_NOT_SELECTED_CUSTOMERS'
1503
                ]);
1 www 1504
 
17248 stevensc 1505
            }
1506
 
1507
            // Get push template
1508
            $push_template_uuid = Functions::sanitizeFilterString($form->get('push_template_id')->getValue());
1509
            $pushMapper = PushMapper::getInstance($this->adapter);
1510
            $pushTemplateMapper = PushTemplateMapper::getInstance($this->adapter);
1511
            $pushTemplate = $pushTemplateMapper->fetchOneByUuid($push_template_uuid);
1512
 
1513
            if(!$pushTemplate) {
1514
                return new JsonModel([
1515
                    'success' => false,
1516
                    'data' => 'ERROR_PUSH_TEMPLATE_NOT_FOUND'
1517
                ]);
1518
            }
1519
 
1520
            // Initialize push notification process
1521
            $applicationMapper = ApplicationMapper::getInstance($this->adapter);
1522
            $application = $applicationMapper->fetchOne(Application::TWOGETSKILLS);
1523
 
1524
            $topicUserMapper = MicrolearningTopicUserMapper::getInstance($this->adapter);
1525
 
1526
            $push_to_send = 0;
1527
 
1528
            // Process each selected user
1529
            $userMapper = UserMapper::getInstance($this->adapter);
1530
            $deviceHistoryMapper = DeviceHistoryMapper::getInstance($this->adapter);
1531
            foreach($customer_uuids as $customer_uuid)
1532
            {
1533
                $user = $userMapper->fetchOneByUuid($customer_uuid);
1534
                if(!$user) {
1535
                    continue;
1 www 1536
                }
1537
 
17248 stevensc 1538
                $topicUser = $topicUserMapper->fetchOneByUserIdAndTopicId($user->id, $topic->id);
1539
                if(!$topicUser) {
1540
                    continue;
1541
                }
1 www 1542
 
17248 stevensc 1543
                // Get user's latest device
1544
                $device = $deviceHistoryMapper->fetchLastDeviceByApplicationIdAndUserId(Application::TWOGETSKILLS, $user->id);
1 www 1545
 
17248 stevensc 1546
                if($device && $device->token) {
1 www 1547
 
17248 stevensc 1548
                    $key = $application->key;
1549
                    if($device->variant_id) {
13755 efrain 1550
 
17248 stevensc 1551
                        $applicationVariantMapper = ApplicationVariantMapper::getInstance($this->adapter);
1552
                        $applicationVariant = $applicationVariantMapper->fetchOneByApplicationIdAndVariantId($device->application_id, $device->variant_id);
1553
                        if($applicationVariant) {
1554
                            $key = $applicationVariant->key;
1555
                        } else {
1556
                            $applicationVariant = $applicationVariantMapper->fetchOneByApplicationIdAndDefault($device->application_id);
13755 efrain 1557
                            if($applicationVariant) {
1558
                                $key = $applicationVariant->key;
1559
                            }
1560
                        }
1561
 
17248 stevensc 1562
                    }
1563
 
1564
                    // Create push notification
1565
                    $push = new Push();
1566
                    $push->status = Push::STATUS_PENDING;
1567
                    $push->data = json_encode([
1568
                        'server' => [
1569
                            'key' => $key,
1570
                        ],
1571
                        'push' => [
1572
                            'registration_ids'   => [
1573
                                $device->token,
1 www 1574
                            ],
17248 stevensc 1575
                            'notification' => [
1576
                                'body' =>  $pushTemplate->body,
1577
                                'title' => $pushTemplate->title,
1578
                                'vibrate' => 1,
1579
                                'sound' =>  1
1580
                            ],
1581
                            'data' => [
1582
                                'command' => 'content-refresh',
1583
                                'new_topics' => '0',
1 www 1584
                            ]
17248 stevensc 1585
                        ]
1586
                    ]);
1587
 
1588
                    if($pushMapper->insert($push)) {
1589
                        $push_to_send = $push_to_send + 1;
1 www 1590
                    }
17248 stevensc 1591
 
1 www 1592
                }
17248 stevensc 1593
            }
1594
 
1595
            // Validate notifications were created
1596
            if(0 == $push_to_send) {
1 www 1597
                return new JsonModel([
17248 stevensc 1598
                    'success' => false,
1599
                    'data' => 'ERROR_NO_USER_DEVICES_WERE_FOUND_TO_SEND_PUSH'
1 www 1600
                ]);
1601
            }
17248 stevensc 1602
 
1603
            return new JsonModel([
1604
                'success' => true,
1605
                'data' => [
1606
                    'push_to_send' => $push_to_send,
1607
                ]
1608
            ]);
1609
        } catch (\Throwable $e) {
1610
            $this->logger->error($e->getMessage());
1611
            return new JsonModel([
1612
                'success' => false,
1613
                'data' => 'ERROR_INTERNAL_SERVER_ERROR'
1614
            ]);
1 www 1615
        }
17248 stevensc 1616
    }
1 www 1617
}