Proyectos de Subversion LeadersLinked - Backend

Rev

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