Proyectos de Subversion LeadersLinked - Services

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
<?php
2
declare(strict_types=1);
3
 
4
namespace LeadersLinked\Controller;
5
 
6
 
7
use Laminas\Authentication\AuthenticationService;
8
use Laminas\Authentication\Result as AuthResult;
9
use Laminas\Db\Adapter\AdapterInterface;
10
 
11
use Laminas\Mvc\Controller\AbstractActionController;
12
use Laminas\Log\LoggerInterface;
13
use Laminas\View\Model\JsonModel;
14
 
15
use LeadersLinked\Authentication\AuthAdapter;
16
use LeadersLinked\Mapper\UserMapper;
17
use LeadersLinked\Mapper\EmailTemplateMapper;
18
use LeadersLinked\Model\User;
19
use LeadersLinked\Model\UserType;
20
 
21
use LeadersLinked\Library\AesCipher;
22
use LeadersLinked\Library\QueueEmail;
23
use LeadersLinked\Library\Functions;
24
use LeadersLinked\Model\EmailTemplate;
25
use LeadersLinked\Mapper\UserPasswordMapper;
26
use LeadersLinked\Mapper\DeviceMapper;
27
use LeadersLinked\Model\Device;
28
use LeadersLinked\Mapper\ApplicationMapper;
29
use LeadersLinked\Model\Application;
30
use LeadersLinked\Validator\PasswordStrengthCheck;
31
 
32
use LeadersLinked\Mapper\CompanyMapper;
33
use LeadersLinked\Model\Company;
34
use LeadersLinked\Mapper\CompanyMicrolearningTopicMapper;
35
use LeadersLinked\Mapper\CompanyMicrolearningCapsuleMapper;
36
use LeadersLinked\Mapper\CompanyMicrolearningSlideMapper;
37
use LeadersLinked\Model\CompanyMicrolearningSlide;
38
use LeadersLinked\Mapper\CompanyMicrolearningUserLogMapper;
39
use LeadersLinked\Mapper\CompanyMicrolearningUserProgressMapper;
40
use LeadersLinked\Mapper\CompanyMicrolearningQuizMapper;
41
use LeadersLinked\Mapper\CompanyMicrolearningQuestionMapper;
42
use LeadersLinked\Mapper\CompanyMicrolearningAnswerMapper;
43
use LeadersLinked\Model\CompanyMicrolearningUserProgress;
44
use LeadersLinked\Model\CompanyMicrolearningUserLog;
45
use LeadersLinked\Mapper\DeviceHistoryMapper;
46
use LeadersLinked\Model\DeviceHistory;
47
use LeadersLinked\Mapper\PushMapper;
48
use LeadersLinked\Model\Push;
49
use LeadersLinked\Mapper\CompanyMicrolearningCapsuleUserMapper;
50
use LeadersLinked\Mapper\CompanyServiceMapper;
51
use LeadersLinked\Model\Service;
52
use LeadersLinked\Model\CompanyService;
53
use LeadersLinked\Model\CompanyMicrolearningCapsuleUser;
54
use LeadersLinked\Model\CompanyMicrolearningUserQuiz;
55
use LeadersLinked\Mapper\CompanyMicrolearningUserQuizMapper;
56
use LeadersLinked\Mapper\CompanyMicrolearningUserMapper;
57
use LeadersLinked\Model\CompanyMicrolearningUser;
58
use LeadersLinked\Mapper\PushTemplateMapper;
59
use LeadersLinked\Model\PushTemplate;
60
use LeadersLinked\Mapper\SyncLogMapper;
61
use LeadersLinked\Model\SyncLog;
62
use LeadersLinked\Model\CompanyMicrolearningExtendUser;
63
use LeadersLinked\Mapper\CompanyMicrolearningExtendUserMapper;
64
use LeadersLinked\Model\CompanyMicrolearningExtendUserCompany;
65
use LeadersLinked\Mapper\CompanyMicrolearningCapsuleCommentMapper;
66
use LeadersLinked\Mapper\CompanyMicrolearningExtendUserCompanyMapper;
67
use LeadersLinked\Mapper\CompanyMicrolearningExtendUserFunctionMapper;
68
use LeadersLinked\Mapper\CompanyMicrolearningExtendUserGroupMapper;
69
use LeadersLinked\Mapper\CompanyMicrolearningExtendUserInstitutionMapper;
70
use LeadersLinked\Mapper\CompanyMicrolearningExtendUserPartnerMapper;
71
use LeadersLinked\Mapper\CompanyMicrolearningExtendUserProgramMapper;
72
use LeadersLinked\Mapper\CompanyMicrolearningExtendUserStudentTypeMapper;
73
use LeadersLinked\Mapper\CompanyMicrolearningExtendUserSectorMapper;
74
use Nullix\CryptoJsAes\CryptoJsAes;
75
use LeadersLinked\Model\CompanyMicrolearningTopic;
76
use LeadersLinked\Model\CompanyMicrolearningCapsule;
77
use LeadersLinked\Model\UserDeleted;
78
use LeadersLinked\Mapper\UserDeletedMapper;
79
use LeadersLinked\Mapper\ApplicationVariantMapper;
80
 
81
 
82
class ServiceController extends AbstractActionController
83
{
84
    /**
85
     *
86
     * @var \Laminas\Db\Adapter\AdapterInterface
87
     */
88
    private $adapter;
89
 
90
    /**
91
     *
92
     * @var \LeadersLinked\Cache\CacheInterface
93
     */
94
    private $cache;
95
 
96
 
97
    /**
98
     *
99
     * @var \Laminas\Log\LoggerInterface
100
     */
101
    private $logger;
102
 
103
    /**
104
     *
105
     * @var array
106
     */
107
    private $config;
108
 
109
 
110
    /**
111
     *
112
     * @var \Laminas\Mvc\I18n\Translator
113
     */
114
    private $translator;
115
 
116
 
117
    /**
118
     *
119
     * @param \Laminas\Db\Adapter\AdapterInterface $adapter
120
     * @param \LeadersLinked\Cache\CacheInterface $cache
121
     * @param \Laminas\Log\LoggerInterface LoggerInterface $logger
122
     * @param array $config
123
     * @param \Laminas\Mvc\I18n\Translator $translator
124
     */
125
    public function __construct($adapter, $cache, $logger, $config, $translator)
126
    {
127
        $this->adapter      = $adapter;
128
        $this->cache        = $cache;
129
        $this->logger       = $logger;
130
        $this->config       = $config;
131
        $this->translator   = $translator;
132
    }
133
 
134
    public function indexAction()
135
    {
136
        return new JsonModel(['ok' => false]);
137
    }
138
 
139
    public function signoutAction()
140
    {
141
        $currentUser = $this->plugin('currentUserPlugin');
142
        if($currentUser->hasIdentity()) {
143
            $device_uuid = $currentUser->getDeviceId();
144
            if($device_uuid) {
145
                $deviceMapper = DeviceMapper::getInstance($this->adapter);
146
                $device = $deviceMapper->fetchOne($device_uuid);
147
                if($device) {
148
                    $deviceMapper->signout($device);
149
                }
150
            }
151
 
152
 
153
            $this->logger->info('Desconexión del mobile', ['user_id' => $currentUser->getUserId(), 'ip' => Functions::getUserIP()]);
154
        }
155
        $authService = new \Laminas\Authentication\AuthenticationService();
156
        $authService->clearIdentity();
157
 
158
        return new JsonModel([
159
            'success' => true,
160
            'data' => 'LABEL_SIGNOUT_SUCCESSFULL'
161
        ]);
162
    }
163
 
164
    public function fcmAction()
165
    {
166
        $request = $this->getRequest();
167
 
168
        if($request->isPost()) {
169
 
170
            $rawdata = file_get_contents("php://input");
171
            error_log('$rawdata = ' . $rawdata );
172
 
173
            $device_uuid      = Functions::sanitizeFilterString($this->params()->fromPost('device_uuid', ''));
174
            $token          = Functions::sanitizeFilterString($this->params()->fromPost('token', ''));
175
            $sync_id        = filter_var($this->params()->fromPost('sync_id', ''), FILTER_SANITIZE_NUMBER_INT);
176
 
177
            /*
178
            echo '$device_uuid = ' . $device_uuid .PHP_EOL;
179
            echo '$token = ' . $token .PHP_EOL;
180
            echo '$sync_id  = ' . $sync_id  .PHP_EOL;
181
            */
182
            $ok = $device_uuid && strlen($device_uuid) == 36 && $sync_id;
183
            $ok = $ok && strlen($token) <= 512;
184
 
185
 
186
            if(!$ok) {
187
                return new JsonModel([
188
                    'success' => false,
189
                    'data' => 'ERROR_PARAMETERS_ARE_INVALID',
190
                ]);
191
            }
192
 
193
            $deviceMapper = DeviceMapper::getInstance($this->adapter);
194
            $device = $deviceMapper->fetchOne($device_uuid);
195
            if(!$device) {
196
                return new JsonModel([
197
                    'success' => false,
198
                    'data' => 'ERROR_DEVICE_NOT_FOUND',
199
                ]);
200
            }
201
 
202
 
203
            $applicationMapper = ApplicationMapper::getInstance($this->adapter);
204
            $application = $applicationMapper->fetchOne($device->application_id);
205
            if(!$application) {
206
                return new JsonModel([
207
                    'success' => false,
208
                    'data' => 'ERROR_APPLICATION_NOT_FOUND',
209
                ]);
210
            }
211
 
212
            if($application->status == Application::STATUS_INACTIVE) {
213
                return new JsonModel([
214
                    'success' => false,
215
                    'data' => 'ERROR_APPLICATION_IS_INACTIVE',
216
                ]);
217
            }
218
 
219
 
220
            $syncLog = new SyncLog();
221
            $syncLog->data = json_encode(['token' => $token]);
222
            $syncLog->type = 'token';
223
            $syncLog->device_uuid = $device->id;
224
            $syncLog->ip = Functions::getUserIP();
225
 
226
            $syncLogMapper = SyncLogMapper::getInstance($this->adapter);
227
            $syncLogMapper->insert($syncLog);
228
 
229
            $device->token = $token;
230
            $device->ip = Functions::getUserIP();
231
            $result = $deviceMapper->update($device);
232
 
233
 
234
            if($result) {
235
                return new JsonModel([
236
                    'success' => true,
237
                    'data' => [
238
                        'sync_id' => $sync_id
239
                    ]
240
                ]);
241
            } else {
242
                return new JsonModel([
243
                    'success' => false,
244
                    'data' => 'ERROR_THERE_WAS_AN_ERROR',
245
                ]);
246
            }
247
 
248
        }
249
 
250
        return new JsonModel([
251
            'success' => false,
252
            'data' => 'ERROR_METHOD_NOT_ALLOWED'
253
        ]);
254
    }
255
 
256
    public function checkSessionAction()
257
    {
258
        $request = $this->getRequest();
259
 
260
        if($request->isPost()) {
261
            $device_uuid  = Functions::sanitizeFilterString($this->params()->fromPost('device_id', ''));
262
            $secret     = Functions::sanitizeFilterString($this->params()->fromPost('secret', ''));
263
            $rand       = filter_var($this->params()->fromPost('rand', ''), FILTER_SANITIZE_NUMBER_INT);
264
            $created    = Functions::sanitizeFilterString($this->params()->fromPost('created', ''));
265
 
266
            if(!$device_uuid || !$secret || !$rand || !$created) {
267
                return new JsonModel([
268
                    'success' => false,
269
                    'data' => 'ERROR_PARAMETERS_ARE_INVALID'
270
                ]);
271
            }
272
 
273
            $dt = \DateTime::createFromFormat('Y-m-d\TH:i:s',  $created);
274
            if(!$dt) {
275
                return new JsonModel([
276
                    'success' => false,
277
                    'data' => 'ERROR_PARAMETERS_ARE_INCORRECTLY_FORMATTED'
278
                ]);
279
            }
280
 
281
 
282
            $deviceMapper = DeviceMapper::getInstance($this->adapter);
283
            $device = $deviceMapper->fetchOne($device_uuid);
284
            if(!$device) {
285
                return new JsonModel([
286
                    'success' => false,
287
                    'data' => 'ERROR_DEVICE_NOT_FOUND'
288
                ]);
289
            }
290
 
291
 
292
            $passworVerification = md5($device->password . ':' . $created . ':'  . $rand);
293
            if($secret != $passworVerification) {
294
                return new JsonModel([
295
                    'success' => false,
296
                    'data' => 'ERROR_WEBSERVICE_PASSWORD'
297
                ]);
298
            }
299
 
300
 
301
            $userMapper = UserMapper::getInstance($this->adapter);
302
            $user = $userMapper->fetchOne($device->user_id);
303
 
304
            if(User::BLOCKED_YES == $user->blocked) {
305
                return new JsonModel([
306
                    'success' => false,
307
                    'data' => 'ERROR_USER_IS_BLOCKED'
308
                ]);
309
            }
310
 
311
            if(User::STATUS_INACTIVE == $user->status) {
312
                return new JsonModel([
313
                    'success' => false,
314
                    'data' =>'ERROR_USER_IS_INACTIVE'
315
                ]);
316
            }
317
 
318
 
319
            return new JsonModel([
320
                'success' => true,
321
                'data' => [
322
                    'user_uuid' => $device->user_uuid
323
                ]
324
            ]);
325
 
326
        }
327
 
328
        return new JsonModel([
329
            'success' => false,
330
            'data' => 'ERROR_METHOD_NOT_ALLOWED'
331
        ]);
332
    }
333
 
334
    public function deviceAction()
335
    {
336
 
337
        $rawdata = file_get_contents("php://input");
338
        error_log('$rawdata = ' . $rawdata );
339
 
340
        $request = $this->getRequest();
341
 
342
        if($request->isPost()) {
343
            //print_r($_POST);
344
 
345
 
346
            $application_id = filter_var($this->params()->fromPost('application_id', 0), FILTER_SANITIZE_NUMBER_INT);
347
            $variant_id     = filter_var($this->params()->fromPost('variant_id', 0), FILTER_SANITIZE_NUMBER_INT);
348
            $device_uuid    = Functions::sanitizeFilterString($this->params()->fromPost('device_uuid', ''));
349
            $manufacturer   = Functions::sanitizeFilterString($this->params()->fromPost('manufacturer', ''));
350
            $platform       = Functions::sanitizeFilterString($this->params()->fromPost('platform', ''));
351
            $brand          = Functions::sanitizeFilterString($this->params()->fromPost('brand', ''));
352
            $version        = Functions::sanitizeFilterString($this->params()->fromPost('version', ''));
353
            $model          = Functions::sanitizeFilterString($this->params()->fromPost('model', ''));
354
            $sync_id        = filter_var($this->params()->fromPost('sync_id', ''), FILTER_SANITIZE_NUMBER_INT);
355
 
356
            $ok = $application_id && $device_uuid && strlen($device_uuid) == 36 && $sync_id;
357
            $ok = $ok && strlen($manufacturer) <= 250;
358
            $ok = $ok && strlen($brand) <= 250;
359
            $ok = $ok && strlen($version) <= 250;
360
            $ok = $ok && strlen($model) <= 250;
361
 
362
            /*
363
            echo "application_id = $application_id" . PHP_EOL;
364
            echo "variant_id = $variant_id" . PHP_EOL;
365
            echo "device_uuid = $device_uuid" . PHP_EOL;
366
            echo "sync_id = $sync_id" . PHP_EOL;
367
            echo "manufacture = $manufacturer" . PHP_EOL;
368
            echo "brand = $brand" . PHP_EOL;
369
            echo "version = $version" . PHP_EOL;
370
            echo "model = $model" . PHP_EOL;
371
            */
372
 
373
            if(!$ok) {
374
                return new JsonModel([
375
                    'success' => false,
376
                    'data' => 'ERROR_PARAMETERS_ARE_INVALID',
377
                ]);
378
            }
379
 
380
 
381
            $applicationMapper = ApplicationMapper::getInstance($this->adapter);
382
            $application = $applicationMapper->fetchOne($application_id);
383
            if(!$application) {
384
                return new JsonModel([
385
                    'success' => false,
386
                    'data' => 'ERROR_APPLICATION_NOT_FOUND',
387
                ]);
388
            }
389
 
390
            if($application->status == Application::STATUS_INACTIVE) {
391
                return new JsonModel([
392
                    'success' => false,
393
                    'data' => 'ERROR_APPLICATION_IS_INACTIVE',
394
                ]);
395
            }
396
 
397
            $applicationVariantMapper = ApplicationVariantMapper::getInstance($this->adapter);
398
            if ($variant_id) {
399
                $applicationVariant = $applicationVariantMapper->fetchOneByApplicationIdAndVariantId($application->id, $variant_id);
400
                if(!$applicationVariant) {
401
 
402
                    return new JsonModel([
403
                        'success' => false,
404
                        'data' => 'ERROR_APPLICATION_VARIANT_IS_INVALID',
405
                    ]);
406
                }
407
            } else {
408
                $applicationVariant = $applicationVariantMapper->fetchOneByApplicationIdAndDefault($application->id);
409
            }
410
 
411
 
412
 
413
            $syncLog = new SyncLog();
414
            $syncLog->data = json_encode([
415
                'platform' => $platform,
416
                'manufacturer' => $manufacturer,
417
                'brand' => $brand,
418
                'version' => $version,
419
                'model' => $model,
420
            ]);
421
            $syncLog->type = 'device';
422
            $syncLog->device_uuid = $device_uuid;
423
            $syncLog->ip = Functions::getUserIP();
424
 
425
            $syncLogMapper = SyncLogMapper::getInstance($this->adapter);
426
            $syncLogMapper->insert($syncLog);
427
 
428
 
429
            $deviceMapper = DeviceMapper::getInstance($this->adapter);
430
            $device = $deviceMapper->fetchOne($device_uuid);
431
 
432
 
433
 
434
 
435
            if($device) {
436
                $device->application_id = $application->id;
437
                $device->variant_id     = $applicationVariant->variant_id;
438
                $device->platform       = $platform;
439
                $device->manufacturer   = $manufacturer;
440
                $device->brand          = $brand;
441
                $device->version        = $version;
442
                $device->model          = $model;
443
                $device->ip             = Functions::getUserIP();
444
                $result                 = $deviceMapper->update($device);
445
 
446
            } else {
447
                $device                 = new Device();
448
                $device->id             = $device_uuid;
449
                $device->application_id = $application->id;
450
                $device->variant_id     = $applicationVariant->variant_id;
451
                $device->manufacturer   = $manufacturer;
452
                $device->brand          = $brand;
453
                $device->version        = $version;
454
                $device->model          = $model;
455
                $device->platform       = $platform;
456
                $device->ip             = Functions::getUserIP();
457
                $device->aes            = Functions::generatePassword(16);
458
                $device->password       = Functions::generatePassword(32);
459
                $result                 = $deviceMapper->insert($device);
460
            }
461
 
462
 
463
 
464
            if($result) {
465
                return new JsonModel([
466
                    'success' => true,
467
                    'data' => [
468
                        'sync_id'   => $sync_id,
469
                        'aes'       => $device->aes,
470
                        'password'  => $device->password,
471
                    ]
472
                ]);
473
            } else {
474
                return new JsonModel([
475
                    'success' => false,
476
                    'data' => 'ERROR_THERE_WAS_AN_ERROR',
477
                ]);
478
            }
479
 
480
        }
481
 
482
        return new JsonModel([
483
            'success' => false,
484
            'data' => 'ERROR_METHOD_NOT_ALLOWED'
485
        ]);
486
 
487
    }
488
 
489
    public function microlearningCheckChangesAction()
490
    {
491
        $request = $this->getRequest();
492
 
493
        if($request->isPost()) {
494
            $currentUserPlugin = $this->plugin('currentUserPlugin');
495
            $user = $currentUserPlugin->getUser();
496
 
497
 
498
            //$rawdata = file_get_contents("php://input");
499
            //error_log('url = ' . $_SERVER['REQUEST_URI']);
500
           // error_log('query = ' . $_SERVER['QUERY_STRING']);
501
           // error_log('$rawdata = ' . $rawdata );
502
 
503
 
504
            $serviceDatetimeFormat = $this->config['leaderslinked.services.datetime'];
505
 
506
 
507
            $device_uuid        = Functions::sanitizeFilterString($this->params()->fromPost('device_uuid', ''));
508
            $max_date_changes   = Functions::sanitizeFilterString($this->params()->fromPost('max_date_changes', ''));
509
            $max_ids            = filter_var($this->params()->fromPost('max_ids', 0), FILTER_SANITIZE_NUMBER_INT);
510
            $is_foreground      = filter_var($this->params()->fromPost('is_foreground', 0), FILTER_SANITIZE_NUMBER_INT);
511
            $application_id     = filter_var($this->params()->fromPost('application_id', 0), FILTER_SANITIZE_NUMBER_INT);
512
            $variant_id         = filter_var($this->params()->fromPost('variant_id', 0), FILTER_SANITIZE_NUMBER_INT);
513
 
514
 
515
            $ids = [];
516
            for($i = 1; $i <= $max_ids; $i++)
517
            {
518
                $id = trim(Functions::sanitizeFilterString($this->params()->fromPost('id_' . $i, '')));
519
 
520
 
521
 
522
                if(empty($id)) {
523
                    continue;
524
                }
525
 
526
 
527
 
528
 
529
                $pattern = '/[A-Za-z0-9\-]+\|[A-Za-z0-9\-]+/';
530
                $matches = [];
531
                preg_match($pattern, $id, $matches, PREG_OFFSET_CAPTURE);
532
 
533
 
534
 
535
                if($matches) {
536
                    array_push($ids, $id);
537
                }
538
            }
539
 
540
 
541
            if(empty($ids)) {
542
                $max_date_changes = '';
543
            }  else {
544
 
545
 
546
                if($max_date_changes) {
547
                    $dt = \DateTime::createFromFormat($serviceDatetimeFormat, $max_date_changes);
548
                    if($dt) {
549
                      $max_date_changes = $dt->format('Y-m-d H:i:s');
550
                    } else {
551
                        $max_date_changes = '';
552
                    }
553
                } else {
554
                    $max_date_changes = '';
555
                }
556
            }
557
 
558
            $ok = $device_uuid && strlen($device_uuid);
559
 
560
            if(!$ok) {
561
                return new JsonModel([
562
                    'success' => false,
563
                    'data' => 'ERROR_PARAMETERS_ARE_INVALID',
564
                ]);
565
            }
566
 
567
            $deviceMapper = DeviceMapper::getInstance($this->adapter);
568
            $device = $deviceMapper->fetchOne($device_uuid);
569
 
570
 
571
            if(!$device) {
572
                return new JsonModel([
573
                    'success' => false,
574
                    'data' => 'ERROR_DEVICE_NOT_FOUND'
575
                ]);
576
            } else {
577
                if ($application_id && $variant_id) {
578
                    $applicationMapper = ApplicationMapper::getInstance($this->adapter);
579
                    $application = $applicationMapper->fetchOne($application_id);
580
                    if(!$application) {
581
                        return new JsonModel([
582
                            'success' => false,
583
                            'data' => 'ERROR_APPLICATION_NOT_FOUND',
584
                        ]);
585
                    }
586
 
587
                    if($application->status == Application::STATUS_INACTIVE) {
588
                        return new JsonModel([
589
                            'success' => false,
590
                            'data' => 'ERROR_APPLICATION_IS_INACTIVE',
591
                        ]);
592
                    }
593
 
594
                    $applicationVariantMapper = ApplicationVariantMapper::getInstance($this->adapter);
595
                    if ($variant_id) {
596
                        $applicationVariant = $applicationVariantMapper->fetchOneByApplicationIdAndVariantId($application->id, $variant_id);
597
                        if(!$applicationVariant) {
598
 
599
                            return new JsonModel([
600
                                'success' => false,
601
                                'data' => 'ERROR_APPLICATION_VARIANT_IS_INVALID',
602
                            ]);
603
                        }
604
                    } else {
605
                        $applicationVariant = $applicationVariantMapper->fetchOneByApplicationIdAndDefault($application->id);
606
                    }
607
 
608
 
609
                    $device->application_id = $application->id;
610
                    $device->variant_id = $applicationVariant->variant_id;
611
                }
612
 
613
 
614
                $device->ip = Functions::getUserIP();
615
                $deviceMapper->update($device);
616
            }
617
 
618
            //Cargamos la fecha máxima del cambio
619
            $companyMicrolearningUserMapper = CompanyMicrolearningUserMapper::getInstance($this->adapter);
620
            $max_date_changes_db = $companyMicrolearningUserMapper->fetchMaxDateChanges($user->id);
621
 
622
 
623
 
624
 
625
            //Si la fecha es vacia agregamos la fecha máxima de la asignación de la capsula
626
            if(!$max_date_changes_db) {
627
                $companyUsers = [];
628
                $companyMicrolearningCapsuleUserMapper = CompanyMicrolearningCapsuleUserMapper::getInstance($this->adapter);
629
                $capsules = $companyMicrolearningCapsuleUserMapper->fetchAllActiveByUserId($user->id);
630
                foreach($capsules as $capsule)
631
                {
632
 
633
 
634
 
635
                    if(empty($companyUsers[$capsule->company_id])) {
636
                        $companyUsers[$capsule->company_id] = $capsule->updated_on;
637
                    } else {
638
 
639
                        if($capsule->updated_on > $companyUsers[$capsule->company_id]) {
640
                            $companyUsers[$capsule->company_id] = $capsule->updated_on;
641
                        }
642
 
643
                    }
644
 
645
                }
646
 
647
                $max_date_changes_db = '';
648
                foreach($companyUsers as $company_id => $update_on)
649
                {
650
 
651
                    $max_date_changes_db = $max_date_changes_db < $update_on ? $update_on : $max_date_changes_db;
652
 
653
                    $companyMicrolearningUser = new CompanyMicrolearningUser();
654
                    $companyMicrolearningUser->company_id = $company_id;
655
                    $companyMicrolearningUser->user_id = $user->id;
656
                    $companyMicrolearningUser->added_on = $update_on;
657
                    $companyMicrolearningUser->updated_on = $update_on;
658
 
659
                    $companyMicrolearningUserMapper->insert($companyMicrolearningUser);
660
                }
661
            }
662
 
663
            /*
664
            echo '$max_date_changes  = ' . $max_date_changes  . PHP_EOL;
665
            echo '$max_date_changes_db  = ' . $max_date_changes_db. PHP_EOL;
666
            exit;
667
            */
668
           // $max_date_changes = '';
669
 
670
 
671
            //Si la que tiene el dispositivo es diferente a la fecha máxima almacenada
672
            $newCapsules = 0;
673
            if($max_date_changes != $max_date_changes_db) {
674
                if(is_array($ids)) {
675
                    /*
676
                    $companyMicrolearningTopicMapper = CompanyMicrolearningTopicMapper::getInstance($this->adapter);
677
                    $companyMicrolearningTopics = $companyMicrolearningTopicMapper->fetchAllActive();
678
 
679
                    $topics = [];
680
                    foreach($companyMicrolearningTopics as $topic)
681
                    {
682
                        $topics[$topic->id] = $topic->uuid;
683
                    }
684
 
685
                    $companyMicrolearningCapsuleMapper = CompanyMicrolearningCapsuleMapper::getInstance($this->adapter);
686
                    $companyMicrolearningCapsules = $companyMicrolearningCapsuleMapper->fetchAllActive();
687
 
688
                    $capsules = [];
689
                    foreach($companyMicrolearningCapsules as $capsule)
690
                    {
691
                        $capsules[$capsule->id] = $capsule->uuid;
692
                    }
693
                    */
694
 
695
                    $topicMapper = CompanyMicrolearningTopicMapper::getInstance($this->adapter);
696
                    $capsuleMapper = CompanyMicrolearningCapsuleMapper::getInstance($this->adapter);
697
 
698
 
699
                    $companyMicrolearningCapsuleUserMapper = CompanyMicrolearningCapsuleUserMapper::getInstance($this->adapter);
700
                    $userCapsules = $companyMicrolearningCapsuleUserMapper->fetchAllActiveByUserId($user->id);
701
 
702
 
703
                    //print_r($user_capsules);
704
 
705
                    foreach($userCapsules as $userCapsule)
706
                    {
707
 
708
                        $topic  = $topicMapper->fetchOne($userCapsule->topic_id);
709
                        $capsule = $capsuleMapper->fetchOne($userCapsule->capsule_id);
710
 
711
                        if($topic && $capsule) {
712
                            if($topic->status == CompanyMicrolearningTopic::STATUS_ACTIVE && $capsule->status == CompanyMicrolearningCapsule::STATUS_ACTIVE) {
713
                                $key = $topic->uuid . '|' . $capsule->uuid;
714
                                if(!in_array($key, $ids)) {
715
                                    $newCapsules++;
716
                                }
717
                            }
718
                        }
719
                    }
720
                }
721
            }
722
 
723
            $dataSync = [];
724
 
725
            //echo 'Vamos a lanzar un PUSH' . PHP_EOL;
726
            if($newCapsules) {
727
 
728
 
729
                if($device->token && $is_foreground)
730
                {
731
 
732
 
733
 
734
                    $applicationMapper = ApplicationMapper::getInstance($this->adapter);
735
                    $application = $applicationMapper->fetchOne(Application::TWOGETSKILLS);
736
 
737
 
738
 
739
 
740
                    $pushMapper = PushMapper::getInstance($this->adapter);
741
                    $pushTemplateMapper = PushTemplateMapper::getInstance($this->adapter);
742
                    $pushTemplate = $pushTemplateMapper->fetchOneByCodeAndCompanyId(PushTemplate::ID_MICRO_LEARNING_NEW_CONTENT, $applicationVariant->company_id);
743
 
744
                    if(!$pushTemplate) {
745
                        $pushTemplate = $pushTemplateMapper-> fetchOneByCodeDefault(PushTemplate::ID_MICRO_LEARNING_NEW_CONTENT);
746
 
747
                    }
748
 
749
 
750
                    //echo 'PushTemplate' . PHP_EOL;
751
                    //print_r($pushTemplate);
752
 
753
 
754
 
755
                    //echo 'Application';
756
                    //print_r($application);
757
                    if($pushTemplate && $application) {
758
                         $push = new Push();
759
                        $push->status = Push::STATUS_PENDING;
760
                        $push->data = json_encode([
761
                            'server' => [
762
                                'key' =>   $application->key,
763
                            ],
764
                            'push' => [
765
                                'registration_ids'   => [
766
                                    $device->token,
767
                                ],
768
                                'notification' => [
769
                                    'body' =>  $pushTemplate->body,
770
                                    'title' => $pushTemplate->title,
771
                                    'vibrate' => 1,
772
                                    'sound' =>  1,
773
 
774
 
775
                                ],
776
                                'content_available' => true,
777
                                'data' => [
778
                                    'command' => 'content-refresh',
779
                                    'new_capsules' => strval($newCapsules),
780
                                ]
781
                            ]
782
                        ]);
783
 
784
 
785
                        //print_r($push);
786
 
787
                        $pushMapper->insert($push);
788
                    }
789
                }
790
 
791
                /*
792
                if(!$is_foreground) {
793
                    $dataSync = $this->getSyncData($user,false, false);
794
                }
795
                */
796
            }
797
 
798
 
799
            //error_log('$max_date_changes_db = ' . $max_date_changes_db);
800
 
801
            $dt = \DateTime::createFromFormat('Y-m-d H:i:s', $max_date_changes_db);
802
            if($dt) {
803
                $max_date_changes_db = $dt->format($serviceDatetimeFormat);
804
            } else {
805
                $max_date_changes_db = '';
806
            }
807
 
808
            $ratingAndComments = [];
809
 
810
            $capsuleMapper = CompanyMicrolearningCapsuleMapper::getInstance($this->adapter);
811
            $capsuleCommentMapper = CompanyMicrolearningCapsuleCommentMapper::getInstance($this->adapter);
812
 
813
            $companyMicrolearningCapsuleUserMapper = CompanyMicrolearningCapsuleUserMapper::getInstance($this->adapter);
814
            $userCapsules = $companyMicrolearningCapsuleUserMapper->fetchAllActiveByUserId($user->id);
815
 
816
            foreach($userCapsules as $userCapsule)
817
            {
818
                $capsule = $capsuleMapper->fetchOne($userCapsule->capsule_id);
819
                if($capsule) {
820
 
821
                    $record = $capsuleCommentMapper->fetchCountAndRatingAverage($capsule->company_id, $capsule->topic_id, $capsule->id);
822
 
823
 
824
                    array_push($ratingAndComments, [
825
                        'uuid' => $capsule->uuid,
826
                        'total_comments' => $record['total_comments'],
827
                        'total_rating' => $record['total_rating'],
828
                    ]);
829
                }
830
 
831
            }
832
 
833
 
834
 
835
 
836
            $data = [
837
                'success'   => true,
838
                'data'      =>[
839
                    'user' => [
840
                        'uuid'              => $user->uuid,
841
                        'first_name'        => $user->first_name,
842
                        'last_name'         => $user->last_name,
843
                        'email'             => $user->email,
844
                        'image'             => $this->url()->fromRoute('services/storage',['type' => 'user', 'code' => $user->uuid, 'filename' => $user->image], ['force_canonical' => true]),
845
                    ],
846
                    'rating_and_comments'   => $ratingAndComments,
847
                    'new_capsules'          => strval($newCapsules),
848
                    'max_date_changes'      => $max_date_changes_db,
849
 
850
                    'topics'            => [],
851
                    'quizzes'           => [],
852
                    'extended'          => [],
853
                ]
854
            ];
855
 
856
            /*
857
 
858
 
859
            $data = [
860
                'success'   => true,
861
                'data'      =>[
862
                    'user' => [
863
                        'uuid' => $user->uuid,
864
                        'first_name' => $user->first_name,
865
                        'last_name' => $user->last_name,
866
                        'email' => $user->email,
867
                        'image' => $this->url()->fromRoute('services/storage',['type' => 'user', 'code' => $user->uuid, 'filename' => $user->image], ['force_canonical' => true]),
868
                    ],
869
                    'new_capsules' => $newCapsules,
870
                    'max_date_changes' => $max_date_changes_db,
871
                    'topics'    => isset( $dataSync['topics'] ) ? $dataSync['topics'] : [],
872
                    'quizzes'   => isset( $dataSync['quizzes'] ) ? $dataSync['quizzes'] : [],
873
                    'extended'=> isset( $dataSync['extended'] ) ? $dataSync['extended'] : [],
874
                ]
875
            ];
876
            */
877
            return new JsonModel($data);
878
        }
879
 
880
        return new JsonModel([
881
            'success' => false,
882
            'data' => 'ERROR_METHOD_NOT_ALLOWED'
883
        ]);
884
 
885
    }
886
 
887
 
888
 
889
    public function microlearningRefreshAction()
890
    {
891
        $request = $this->getRequest();
892
 
893
        if($request->isGet()) {
894
            $currentUserPlugin = $this->plugin('currentUserPlugin');
895
            $user = $currentUserPlugin->getUser();
896
 
897
            $dataSync = $this->getSyncData($user,false, false);
898
 
899
            //Cargamos la fecha máxima del cambio
900
            $companyMicrolearningUserMapper = CompanyMicrolearningUserMapper::getInstance($this->adapter);
901
            $max_date_changes_db = $companyMicrolearningUserMapper->fetchMaxDateChanges($user->id);
902
 
903
            //Si la fecha es vacia agregamos la fecha máxima de la asignación de la capsula
904
            if(!$max_date_changes_db) {
905
                $companyUsers = [];
906
                $companyMicrolearningCapsuleUserMapper = CompanyMicrolearningCapsuleUserMapper::getInstance($this->adapter);
907
                $capsules = $companyMicrolearningCapsuleUserMapper->fetchAllActiveByUserId($user->id);
908
                foreach($capsules as $capsule)
909
                {
910
 
911
 
912
 
913
                    if(empty($companyUsers[$capsule->company_id])) {
914
                        $companyUsers[$capsule->company_id] = $capsule->updated_on;
915
                    } else {
916
 
917
                        if($capsule->updated_on > $companyUsers[$capsule->company_id]) {
918
                            $companyUsers[$capsule->company_id] = $capsule->updated_on;
919
                        }
920
 
921
                    }
922
 
923
                }
924
 
925
                $max_date_changes_db = '';
926
                foreach($companyUsers as $company_id => $update_on)
927
                {
928
 
929
                    $max_date_changes_db = $max_date_changes_db < $update_on ? $update_on : $max_date_changes_db;
930
 
931
                    $companyMicrolearningUser = new CompanyMicrolearningUser();
932
                    $companyMicrolearningUser->company_id = $company_id;
933
                    $companyMicrolearningUser->user_id = $user->id;
934
                    $companyMicrolearningUser->added_on = $update_on;
935
                    $companyMicrolearningUser->updated_on = $update_on;
936
 
937
                    $companyMicrolearningUserMapper->insert($companyMicrolearningUser);
938
                }
939
            }
940
 
941
            $dt = \DateTime::createFromFormat('Y-m-d H:i:s', $max_date_changes_db);
942
            if($dt) {
943
                $serviceDatetimeFormat = $this->config['leaderslinked.services.datetime'];
944
                $max_date_changes_db = $dt->format($serviceDatetimeFormat);
945
            } else {
946
                $max_date_changes_db = '';
947
            }
948
 
949
            return new JsonModel([
950
                'success'   => true,
951
                'data'      =>[
952
                    'user' => [
953
                        'uuid' => $user->uuid,
954
                        'first_name' => $user->first_name,
955
                        'last_name' => $user->last_name,
956
                        'email' => $user->email,
957
                        'image' => $this->url()->fromRoute('services/storage',['type' => 'user', 'code' => $user->uuid, 'filename' => $user->image], ['force_canonical' => true]),
958
                    ],
959
                    'max_date_changes' => $max_date_changes_db,
960
                    'topics'    => $dataSync['topics'],
961
                    'quizzes'   => $dataSync['quizzes'],
962
                    'extended'   => $dataSync['extended'],
963
 
964
                ]
965
            ]);
966
        }
967
 
968
        return new JsonModel([
969
            'success' => false,
970
            'data' => 'ERROR_METHOD_NOT_ALLOWED'
971
        ]);
972
    }
973
 
974
 
975
    public function signinAction()
976
    {
977
        $request = $this->getRequest();
978
 
979
        if($request->isPost()) {
980
 
981
 
982
            $rawdata = file_get_contents("php://input");
983
            error_log('url = ' . $_SERVER['REQUEST_URI']);
984
            error_log('query = ' . $_SERVER['QUERY_STRING']);
985
            error_log('$rawdata = ' . $rawdata );
986
 
987
 
988
            $application_id = filter_var($this->params()->fromPost('application_id', 0), FILTER_SANITIZE_NUMBER_INT);
989
            $variant_id     = filter_var($this->params()->fromPost('variant_id', 0), FILTER_SANITIZE_NUMBER_INT);
990
            $device_uuid    = Functions::sanitizeFilterString($this->params()->fromPost('device_uuid', ''));
991
            $email          = filter_var($this->params()->fromPost('email', ''), FILTER_SANITIZE_EMAIL);
992
            $password       = Functions::sanitizeFilterString($this->params()->fromPost('password', ''));
993
            $encrypter      = Functions::sanitizeFilterString($this->params()->fromPost('encrypter', ''));
994
 
995
 
996
 
997
            $ok = $application_id && $device_uuid && strlen($device_uuid) == 36;
998
            $ok = $ok && $email && $password;
999
            //$ok = $ok && in_array($encrypter, ['CryptoJsAes','RNCryptor','AesCipher']);
1000
 
1001
            if(!$ok) {
1002
                return new JsonModel([
1003
                    'success' => false,
1004
                    'data' => 'ERROR_PARAMETERS_ARE_INVALID',
1005
                ]);
1006
            }
1007
 
1008
 
1009
            $applicationMapper = ApplicationMapper::getInstance($this->adapter);
1010
            $application = $applicationMapper->fetchOne($application_id);
1011
            if(!$application) {
1012
                return new JsonModel([
1013
                    'success' => false,
1014
                    'data' => 'ERROR_APPLICATION_NOT_FOUND',
1015
                ]);
1016
            }
1017
 
1018
            if($application->status == Application::STATUS_INACTIVE) {
1019
                return new JsonModel([
1020
                    'success' => false,
1021
                    'data' => 'ERROR_APPLICATION_IS_INACTIVE',
1022
                ]);
1023
            }
1024
 
1025
            $applicationVariantMapper = ApplicationVariantMapper::getInstance($this->adapter);
1026
            if ($variant_id) {
1027
                $applicationVariant = $applicationVariantMapper->fetchOneByApplicationIdAndVariantId($application->id, $variant_id);
1028
            } else {
1029
                $applicationVariant = $applicationVariantMapper->fetchOneByApplicationIdAndDefault($application->id);
1030
            }
1031
 
1032
 
1033
            $deviceMapper = DeviceMapper::getInstance($this->adapter);
1034
            $device = $deviceMapper->fetchOne($device_uuid);
1035
            /*
1036
            if(!$device) {
1037
                $device                 = new Device();
1038
                $device->id             = $device_uuid;
1039
                $device->application_id = $application->id;
1040
                $device->variant_id     = $applicationVariant->variant_id;
1041
                $device->ip             = Functions::getUserIP();
1042
                $device->aes            = Functions::generatePassword(16);
1043
                $device->password       = Functions::generatePassword(32);
1044
                $result                 = $deviceMapper->insert($device);
1045
 
1046
                if(!$result) {
1047
                    return new JsonModel([
1048
                        'success' => false,
1049
                        'data' => 'ERROR_DEVICE_NOT_FOUND',
1050
                    ]);
1051
                }
1052
            }*/
1053
            if(!$device) {
1054
                return new JsonModel([
1055
                    'success' => false,
1056
                    'data' => 'ERROR_DEVICE_NOT_FOUND',
1057
                ]);
1058
            }
1059
 
1060
 
1061
 
1062
            if($encrypter == 'CryptoJsAes') {
1063
 
1064
 
1065
                $email = html_entity_decode($email);
1066
                $password = html_entity_decode($password);
1067
 
1068
 
1069
                ob_start();
1070
 
1071
                $email      = CryptoJsAes::decrypt($email, $device->aes);
1072
                $password   = CryptoJsAes::decrypt($password, $device->aes);
1073
 
1074
                ob_end_clean();
1075
 
1076
                if(!$email || !$password) {
1077
                    return new JsonModel([
1078
                        'success' => false,
1079
                        'data' => 'ERROR_WEBSERVICE_PASSWORD_ENCRYPTION_FAILED',
1080
                    ]);
1081
                }
1082
            } else if($encrypter == 'RNCryptor') {
1083
 
1084
                error_log("RNCryptor");
1085
                error_log("Device UUID : " . $device->id);
1086
                error_log("AES : " . $device->aes);
1087
                error_log("Email Encrypted : " . $email);
1088
                error_log("Password Encrypted : " . $password);
1089
 
1090
                $cryptor = new \RNCryptor\RNCryptor\Decryptor;
1091
                $email = $cryptor->decrypt($email, $device->aes);
1092
                $password = $cryptor->decrypt($password, $device->aes);
1093
 
1094
                error_log("Email Decrypted : " . $email . PHP_EOL);
1095
                error_log("Password Decrypted : " . $password . PHP_EOL);
1096
 
1097
                if(!$email || !$password) {
1098
                    return new JsonModel([
1099
                        'success' => false,
1100
                        'data' => 'ERROR_WEBSERVICE_PASSWORD_ENCRYPTION_FAILED',
1101
                    ]);
1102
                }
1103
 
1104
 
1105
            } else if($encrypter == 'AesCipher') {
1106
 
1107
                error_log("AesCipher");
1108
                error_log("Device UUID : " . $device->id);
1109
                error_log("AES : " . $device->aes);
1110
                error_log("Email Encrypted : " . $email);
1111
                error_log("Password Encrypted : " . $password);
1112
 
1113
                $emailDecrypted = AesCipher::decrypt($device->aes,$email);
1114
                $passwordDecrypted = AesCipher::decrypt($device->aes,$password);
1115
                if($emailDecrypted->hasError() || $passwordDecrypted->hasError()) {
1116
                    return new JsonModel([
1117
                        'success' => false,
1118
                        'data' => 'ERROR_WEBSERVICE_PASSWORD_ENCRYPTION_FAILED',
1119
                    ]);
1120
                }
1121
 
1122
                $email = $emailDecrypted->getData();
1123
                $password = $passwordDecrypted->getData();
1124
 
1125
                error_log("Email Decrypted : " . $email . PHP_EOL);
1126
                error_log("Password Decrypted : " . $password . PHP_EOL);
1127
 
1128
            } else {
1129
                $email   = filter_var($email, FILTER_SANITIZE_EMAIL);
1130
            }
1131
 
1132
            $companyMapper = CompanyMapper::getInstance($this->adapter);
1133
            $company = $companyMapper->fetchOne($applicationVariant->company_id);
1134
 
1135
 
1136
            $authAdapter = new AuthAdapter($this->adapter);
1137
            $authAdapter->setData($email, $password, $company->network_id);
1138
 
1139
            $authService = new AuthenticationService();
1140
            $result = $authService->authenticate($authAdapter);
1141
 
1142
            $ip = Functions::getUserIP();
1143
            if($result->getCode() == AuthResult::SUCCESS) {
1144
 
1145
                $userMapper = UserMapper::getInstance($this->adapter);
1146
                $user = $userMapper->fetchOneByEmailAndNetworkId($email, $company->network_id);
1147
 
1148
 
1149
                $device->user_id    = $user->id;
1150
                $device->ip         = $ip;
1151
 
1152
                if ($application_id && $variant_id) {
1153
                    $device->application_id = $application_id;
1154
                    $device->variant_id = $variant_id;
1155
                }
1156
 
1157
                if($deviceMapper->update($device)) {
1158
 
1159
 
1160
 
1161
                    $deviceHistoryMapper = DeviceHistoryMapper::getInstance($this->adapter);
1162
                    $deviceHistory = $deviceHistoryMapper->fetchOneByDeviceIdAndUserIdAndIp($device->id, $user->id, $ip);
1163
                    if($deviceHistory) {
1164
                        $deviceHistory->ip = $ip;
1165
                        $deviceHistoryMapper->update($deviceHistory);
1166
                    } else {
1167
                        $deviceHistory = new DeviceHistory();
1168
                        $deviceHistory->device_id = $device->id;
1169
                        $deviceHistory->user_id = $user->id;
1170
                        $deviceHistory->ip = $ip;
1171
                        $deviceHistoryMapper->insert($deviceHistory);
1172
                    }
1173
 
1174
                    $pushMapper = PushMapper::getInstance($this->adapter);
1175
 
1176
                    $userDevices =  $deviceMapper->fetchAllByUserIdAndApplicationId($user->id, $device->application_id);
1177
                    foreach($userDevices as $userDevice)
1178
                    {
1179
 
1180
                        if($userDevice->id != $device->id ) {
1181
                            $deviceMapper->releaseUserFormDevice($userDevice);
1182
 
1183
 
1184
                            if($userDevice->token) {
1185
 
1186
                                $key = $application->key;
1187
                                if ($device->variant_id) {
1188
                                    $applicationVariant = $applicationVariantMapper->fetchOneByApplicationIdAndVariantId($application->id, $variant_id);
1189
                                    if($applicationVariant) {
1190
                                        $key = $applicationVariant->key;
1191
 
1192
                                    } else {
1193
                                        $applicationVariant = $applicationVariantMapper->fetchOneByApplicationIdAndDefault($application->id);
1194
                                        if($applicationVariant) {
1195
                                            $key = $applicationVariant->key;
1196
                                        }
1197
                                    }
1198
                                }
1199
 
1200
 
1201
                                $push = new Push();
1202
                                $push->status = Push::STATUS_PENDING;
1203
                                $push->data = json_encode([
1204
                                    'server' => [
1205
                                        'key' =>  $key,
1206
                                     ],
1207
                                     'push' => [
1208
                                        'registration_ids'   => [
1209
                                            $userDevice->token,
1210
                                         ],
1211
                                         'notification' => [
1212
                                             'body' =>  'Se registro un inicio de sesión en otro dispositivo',
1213
                                             'title' => 'Nuevo inicio de sesión',
1214
                                             'vibrate' => 1,
1215
                                             'sound' =>  1
1216
                                         ],
1217
                                        'data' => [
1218
                                            'command' => 'signout'
1219
                                        ]
1220
                                     ]
1221
                                 ]);
1222
 
1223
                                $pushMapper->insert($push);
1224
 
1225
                            }
1226
                        }
1227
                    }
1228
 
1229
 
1230
                    $companyUsers = [];
1231
                    $companyMicrolearningCapsuleUserMapper = CompanyMicrolearningCapsuleUserMapper::getInstance($this->adapter);
1232
                    $capsules = $companyMicrolearningCapsuleUserMapper->fetchAllActiveByUserId($user->id);
1233
                    foreach($capsules as $capsule)
1234
                    {
1235
 
1236
 
1237
 
1238
                        if(empty($companyUsers[$capsule->company_id])) {
1239
                            $companyUsers[$capsule->company_id] = $capsule->updated_on;
1240
                        } else {
1241
 
1242
                            if($capsule->updated_on > $companyUsers[$capsule->company_id]) {
1243
                                $companyUsers[$capsule->company_id] = $capsule->updated_on;
1244
                            }
1245
 
1246
                        }
1247
 
1248
                    }
1249
 
1250
                    $companyMicrolearningUserMapper = CompanyMicrolearningUserMapper::getInstance($this->adapter);
1251
 
1252
                    $maxDateChanges = $companyMicrolearningUserMapper->fetchMaxDateChanges($user->id);
1253
                    if(!$maxDateChanges) {
1254
 
1255
 
1256
                        $maxDateChanges = '';
1257
                        foreach($companyUsers as $company_id => $update_on)
1258
                        {
1259
 
1260
                            $maxDateChanges = $maxDateChanges < $update_on ? $update_on : $maxDateChanges;
1261
 
1262
                            $companyMicrolearningUser = new CompanyMicrolearningUser();
1263
                            $companyMicrolearningUser->company_id = $company_id;
1264
                            $companyMicrolearningUser->user_id = $user->id;
1265
                            $companyMicrolearningUser->added_on = $update_on;
1266
                            $companyMicrolearningUser->updated_on = $update_on;
1267
 
1268
                            $companyMicrolearningUserMapper->insert($companyMicrolearningUser);
1269
                        }
1270
 
1271
 
1272
                    }
1273
 
1274
 
1275
 
1276
                   $dt = \DateTime::createFromFormat('Y-m-d H:i:s', $maxDateChanges);
1277
                   if($dt) {
1278
                       $serviceDatetimeFormat = $this->config['leaderslinked.services.datetime'];
1279
                       $maxDateChanges = $dt->format($serviceDatetimeFormat);
1280
                   } else {
1281
                       $maxDateChanges = '';
1282
                   }
1283
 
1284
 
1285
                    $data = [
1286
                        'success'   => true,
1287
                        'data'      =>[
1288
                            'user' => [
1289
                                'uuid' => $user->uuid,
1290
                                'first_name' => $user->first_name,
1291
                                'last_name' => $user->last_name,
1292
                                'email' => $user->email,
1293
                                'image' => $this->url()->fromRoute('services/storage',['type' => 'user', 'code' => $user->uuid, 'filename' => $user->image], ['force_canonical' => true]),
1294
 
1295
                             ],
1296
                            'max_date_changes' => $maxDateChanges,
1297
                            'device' => [
1298
                                'aes' => $device->aes,
1299
                                'password' => $device->password
1300
                            ]
1301
 
1302
                        ]
1303
                    ];
1304
 
1305
                    if($application->id == Application::TWOGETSKILLS) {
1306
                        $dataSync = $this->getSyncData($user);
1307
 
1308
                        $data['data']['topics'] = $dataSync['topics'];
1309
                        $data['data']['quizzes'] = $dataSync['quizzes'];
1310
                        $data['data']['userlog'] = $dataSync['userlog'];
1311
                        $data['data']['progress'] = $dataSync['progress'];
1312
                        $data['data']['extended'] = $dataSync['extended'];
1313
                    }
1314
 
1315
 
1316
 
1317
                    return new JsonModel($data);
1318
 
1319
 
1320
 
1321
                } else {
1322
                    return new JsonModel([
1323
                        'success' => false,
1324
                        'data' => 'ERROR_THERE_WAS_AN_ERROR',
1325
                    ]);
1326
                }
1327
 
1328
 
1329
            } else {
1330
                $message = $result->getMessages()[0];
1331
                if(!in_array($message, ['ERROR_USER_NOT_FOUND', 'ERROR_USER_PROVIDER_NOT_FOUND', 'ERROR_USER_EMAIL_HASNT_BEEN_VARIFIED', 'ERROR_USER_IS_BLOCKED',
1332
                    'ERROR_USER_IS_INACTIVE', 'ERROR_ENTERED_PASS_INCORRECT_USER_IS_BLOCKED', 'ERROR_ENTERED_PASS_INCORRECT_2',
1333
                    'ERROR_ENTERED_PASS_INCORRECT_1', 'ERROR_USER_REQUEST_ACCESS_IS_PENDING', 'ERROR_USER_REQUEST_ACCESS_IS_REJECTED'  ])) {
1334
                }
1335
 
1336
                switch($message)
1337
                {
1338
                    case 'ERROR_USER_NOT_FOUND' :
1339
                        $this->logger->err('Error de ingreso a LeadersLinked de ' . $email . ' - Email no existe', ['ip' => Functions::getUserIP()]);
1340
                        break;
1341
 
1342
                    case 'ERROR_USER_EMAIL_HASNT_BEEN_VARIFIED' :
1343
                        $this->logger->err('Error de ingreso a LeadersLinked de ' . $email . ' - Email no verificado', ['ip' => Functions::getUserIP()]);
1344
                        break;
1345
 
1346
                    case 'ERROR_USER_IS_BLOCKED' :
1347
                        $this->logger->err('Error de ingreso a LeadersLinked de ' . $email . ' - Usuario bloqueado', ['ip' => Functions::getUserIP()]);
1348
                        break;
1349
 
1350
                    case 'ERROR_USER_IS_INACTIVE' :
1351
                        $this->logger->err('Error de ingreso a LeadersLinked de ' . $email . ' - Usuario inactivo', ['ip' => Functions::getUserIP()]);
1352
                        break;
1353
 
1354
 
1355
                    case 'ERROR_ENTERED_PASS_INCORRECT_USER_IS_BLOCKED':
1356
                        $this->logger->err('Error de ingreso a LeadersLinked de ' . $email . ' - 3er Intento Usuario bloqueado', ['ip' => Functions::getUserIP()]);
1357
                        break;
1358
 
1359
 
1360
                    case 'ERROR_ENTERED_PASS_INCORRECT_2' :
1361
                        $this->logger->err('Error de ingreso a LeadersLinked de ' . $email . ' - 1er Intento', ['ip' => Functions::getUserIP()]);
1362
                        break;
1363
 
1364
 
1365
                    case 'ERROR_ENTERED_PASS_INCORRECT_1' :
1366
                        $this->logger->err('Error de ingreso a LeadersLinked de ' . $email . ' - 2do Intento', ['ip' => Functions::getUserIP()]);
1367
                        break;
1368
 
1369
 
1370
                    case 'ERROR_USER_REQUEST_ACCESS_IS_PENDING' :
1371
                        $this->logger->err('Error de ingreso a LeadersLinked de ' . $email . ' - Falta verificar que pertence a la Red Privada', ['ip' => Functions::getUserIP()]);
1372
                        break;
1373
 
1374
                    case  'ERROR_USER_REQUEST_ACCESS_IS_REJECTED' :
1375
                        $this->logger->err('Error de ingreso a LeadersLinked de ' . $email . ' - Rechazado por no pertence a la Red Privada', ['ip' => Functions::getUserIP()]);
1376
                        break;
1377
 
1378
 
1379
                    default :
1380
                        $message = 'ERROR_UNKNOWN';
1381
                        $this->logger->err('Error de ingreso a LeadersLinked de ' . $email . ' - Error desconocido', ['ip' => Functions::getUserIP()]);
1382
                        break;
1383
 
1384
 
1385
                }
1386
 
1387
 
1388
                return new JsonModel([
1389
                    'success'   => false,
1390
                    'data'   => $message
1391
                ]);
1392
            }
1393
 
1394
        }
1395
 
1396
        return new JsonModel([
1397
            'success' => false,
1398
            'data' => 'ERROR_METHOD_NOT_ALLOWED'
1399
        ]);
1400
 
1401
    }
1402
 
1403
 
1404
 
1405
 
1406
    public function storageAction()
1407
    {
1408
 
1409
        // Get the file name from GET variable.
1410
        $code       = $this->params()->fromRoute('code', '');
1411
        $fileName   = $this->params()->fromRoute('filename', '');
1412
        $type       = $this->params()->fromRoute('type', 'user');
1413
 
1414
 
1415
        $no_image = $this->config['leaderslinked.images_default.no_image'];
1416
        $path = '';
1417
        switch($type)
1418
        {
1419
            case 'user' :
1420
                $no_image = $this->config['leaderslinked.images_default.user_image'];
1421
                $path = $this->config['leaderslinked.fullpath.user'];
1422
                break;
1423
 
1424
 
1425
            case 'user-profile' :
1426
                $no_image = $this->config['leaderslinked.images_default.user_profile'];
1427
                $path = $this->config['leaderslinked.fullpath.user'];
1428
                break;
1429
 
1430
            case 'user-cover' :
1431
                $no_image = $this->config['leaderslinked.images_default.user_cover'];
1432
                $path = $this->config['leaderslinked.fullpath.user'];
1433
                break;
1434
 
1435
            case 'company' :
1436
                $no_image = $this->config['leaderslinked.images_default.company_profile'];
1437
                $path = $this->config['leaderslinked.fullpath.company'];
1438
                break;
1439
 
1440
            case 'company-cover' :
1441
                $no_image = $this->config['leaderslinked.images_default.company_cover'];
1442
                $path = $this->config['leaderslinked.fullpath.company'];
1443
                break;
1444
 
1445
            case 'group' :
1446
                $no_image = $this->config['leaderslinked.images_default.group_profile'];
1447
                $path = $this->config['leaderslinked.fullpath.group'];
1448
                break;
1449
 
1450
            case 'group-cover' :
1451
                $no_image = $this->config['leaderslinked.images_default.group_cover'];
1452
                $path = $this->config['leaderslinked.fullpath.group'];
1453
                break;
1454
 
1455
            case 'job' :
1456
                $path = $this->config['leaderslinked.fullpath.job'];
1457
                break;
1458
 
1459
            case 'chat' :
1460
                $path = $this->config['leaderslinked.fullpath.chat'];
1461
                break;
1462
 
1463
            case 'feed' :
1464
                $path = $this->config['leaderslinked.fullpath.feed'];
1465
                break;
1466
 
1467
            case 'post' :
1468
                $path = $this->config['leaderslinked.fullpath.post'];
1469
                break;
1470
 
1471
            case 'microlearning-topic' :
1472
                $path = $this->config['leaderslinked.fullpath.microlearning_topic'];
1473
                break;
1474
 
1475
            case 'microlearning-capsule' :
1476
                $path = $this->config['leaderslinked.fullpath.microlearning_capsule'];
1477
                break;
1478
 
1479
            case 'microlearning-slide' :
1480
                $path = $this->config['leaderslinked.fullpath.microlearning_slide'];
1481
                break;
1482
 
1483
            default :
1484
                $path = $this->config['leaderslinked.fullpath.image'];
1485
                break;
1486
 
1487
        }
1488
        if($code && $fileName) {
1489
            $request_fullpath = $path . $code . DIRECTORY_SEPARATOR . $fileName;
1490
        } else {
1491
            $request_fullpath = $no_image;
1492
        }
1493
 
1494
        if(empty($fileName)) {
1495
            $extensions     = explode('.',$request_fullpath);
1496
            $extension      = strtolower(trim($extensions[count($extensions)-1]));
1497
            if ($extension=='jpg' || $extension=='jpeg' || $extension=='gif' || $extension == 'png') {
1498
                $request_fullpath =  $no_image;
1499
            }
1500
        }
1501
 
1502
 
1503
        if(file_exists($request_fullpath)) {
1504
 
1505
            // Try to open file
1506
            if (!is_readable($request_fullpath)) {
1507
                return $this->getResponse()->setStatusCode(500);
1508
            }
1509
 
1510
            // Get file size in bytes.
1511
            $fileSize = filesize($request_fullpath);
1512
 
1513
            // Get MIME type of the file.
1514
            $mimeType = mime_content_type($request_fullpath);
1515
            if($mimeType===false) {
1516
                $mimeType = 'application/octet-stream';
1517
            }
1518
 
1519
            $request_fullpath = trim($request_fullpath);
1520
            $length = strlen($request_fullpath);
1521
            if(substr($request_fullpath, $length - 1) == '/') {
1522
                $request_fullpath = substr($request_fullpath, 0, $length - 1);
1523
            }
1524
 
1525
 
1526
            $filename = basename($request_fullpath);
1527
 
1528
            header('Content-type: ' . $mimeType);
1529
            readfile($request_fullpath);
1530
 
1531
 
1532
            exit;
1533
            //header("X-Sendfile: $request_fullpath");
1534
            //header("Content-type: application/octet-stream");
1535
            //header('Content-Disposition: attachment; filename="' . basename($filename) . '"');
1536
 
1537
 
1538
            /*
1539
 
1540
 
1541
            if ($fd = fopen ($request_fullpath, "r")) {
1542
 
1543
                $fsize = filesize($request_fullpath);
1544
 
1545
                header("Content-type: $mimeType");
1546
                header("Accept-Ranges: bytes");
1547
 
1548
                //header("Content-Disposition: attachment; filename=\"$filename\"");
1549
 
1550
                header("Content-length: $fsize");
1551
                header("Cache-control: private");
1552
 
1553
                while(!feof($fd)) {
1554
                    $buffer = fread($fd, 2048);
1555
                    echo $buffer;
1556
                }
1557
            }
1558
 
1559
            fclose ($fd);
1560
            exit;*/
1561
 
1562
 
1563
            /*
1564
             $fileContent = file_get_contents($request_fullpath);
1565
            $response = $this->getResponse();
1566
            $headers = $response->getHeaders();
1567
            $headers->addHeaderLine('Accept-Ranges: bytes');
1568
            $headers->addHeaderLine('Content-type: ' . $mimeType);
1569
            $headers->addHeaderLine('Content-length: ' . $fileSize);
1570
 
1571
            /*
1572
            Date: Tue, 13 Jul 2021 03:11:42 GMT
1573
            Server: Apache/2.4.41 (Ubuntu)
1574
            Last-Modified: Mon, 28 Jun 2021 16:43:04 GMT
1575
            ETag: "54e4-5c5d62eed581e"
1576
            Accept-Ranges: bytes
1577
            Content-Length: 21732
1578
            Cache-Control: max-age=1
1579
            Expires: Tue, 13 Jul 2021 03:11:43 GMT
1580
            Keep-Alive: timeout=5, max=100
1581
            Connection: Keep-Alive
1582
            Content-Type: audio/mpeg
1583
            */
1584
 
1585
            /*
1586
            if($fileContent!==false) {
1587
                error_log($_SERVER['REQUEST_URI']);
1588
                error_log($request_fullpath);
1589
                return $response->setContent($fileContent);
1590
 
1591
                header('Content-Type: '.$mimeType );
1592
                readfile_chunked($filename);
1593
                exit;
1594
 
1595
            } else {
1596
                error_log('500');
1597
                $this->getResponse()->setStatusCode(500);
1598
                return;
1599
            }*/
1600
        } else {
1601
            error_log('404');
1602
            return $this->getResponse()->setStatusCode(404);
1603
        }
1604
 
1605
        return $this->getResponse();
1606
    }
1607
 
1608
 
1609
    public function syncAction()
1610
    {
1611
        $request = $this->getRequest();
1612
 
1613
        if($request->isPost()) {
1614
 
1615
 
1616
 
1617
 
1618
            $serviceDatetimeFormat = $this->config['leaderslinked.services.datetime'];
1619
 
1620
            $device_uuid    = Functions::sanitizeFilterString($this->params()->fromPost('device_uuid', ''));
1621
            $sync_id        = filter_var($this->params()->fromPost('sync_id', ''), FILTER_SANITIZE_NUMBER_INT);
1622
            $data           = $this->params()->fromPost('data', '');
1623
            $application_id = filter_var($this->params()->fromPost('application_id', 0), FILTER_SANITIZE_NUMBER_INT);
1624
            $variant_id     = filter_var($this->params()->fromPost('variant_id', 0), FILTER_SANITIZE_NUMBER_INT);
1625
 
1626
 
1627
            //error_log('device_uuid = ' . $device_uuid);
1628
            //error_log('sync_id = ' . $sync_id);
1629
            //error_log(print_r($data, true));
1630
 
1631
 
1632
            //$rawdata = file_get_contents("php://input");
1633
           // error_log('$rawdata = ' . $rawdata );
1634
 
1635
            $ok = $device_uuid && strlen($device_uuid) == 36 && $data && $sync_id;
1636
 
1637
            if(!$ok) {
1638
                return new JsonModel([
1639
                    'success' => false,
1640
                    'data' => 'ERROR_PARAMETERS_ARE_INVALID',
1641
                ]);
1642
            }
1643
 
1644
            $deviceMapper = DeviceMapper::getInstance($this->adapter);
1645
            $device = $deviceMapper->fetchOne($device_uuid);
1646
 
1647
 
1648
            if(!$device) {
1649
                return new JsonModel([
1650
                    'success' => false,
1651
                    'data' => 'ERROR_DEVICE_NOT_FOUND'
1652
                ]);
1653
            } else {
1654
 
1655
                if ($application_id && $variant_id) {
1656
                    $applicationMapper = ApplicationMapper::getInstance($this->adapter);
1657
                    $application = $applicationMapper->fetchOne($application_id);
1658
                    if(!$application) {
1659
                        return new JsonModel([
1660
                            'success' => false,
1661
                            'data' => 'ERROR_APPLICATION_NOT_FOUND',
1662
                        ]);
1663
                    }
1664
 
1665
                    if($application->status == Application::STATUS_INACTIVE) {
1666
                        return new JsonModel([
1667
                            'success' => false,
1668
                            'data' => 'ERROR_APPLICATION_IS_INACTIVE',
1669
                        ]);
1670
                    }
1671
 
1672
                    $applicationVariantMapper = ApplicationVariantMapper::getInstance($this->adapter);
1673
                    if ($variant_id) {
1674
                        $applicationVariant = $applicationVariantMapper->fetchOneByApplicationIdAndVariantId($application->id, $variant_id);
1675
                        if(!$applicationVariant) {
1676
 
1677
                            return new JsonModel([
1678
                                'success' => false,
1679
                                'data' => 'ERROR_APPLICATION_VARIANT_IS_INVALID',
1680
                            ]);
1681
                        }
1682
                    } else {
1683
                        $applicationVariant = $applicationVariantMapper->fetchOneByApplicationIdAndDefault($application->id);
1684
                    }
1685
 
1686
 
1687
                    $device->application_id = $application->id;
1688
                    $device->variant_id = $applicationVariant->variant_id;
1689
                }
1690
 
1691
                $device->ip = Functions::getUserIP();
1692
                $deviceMapper->update($device);
1693
            }
1694
 
1695
 
1696
 
1697
 
1698
 
1699
            $data = json_decode($data, true);
1700
            $sync_type      = isset($data['sync_type']) ? Functions::sanitizeFilterString($data['sync_type']) : '';
1701
            $user_uuid      = isset($data['user_uuid']) ? Functions::sanitizeFilterString($data['user_uuid']) : '';
1702
            $company_uuid   = isset($data['company_uuid']) ? Functions::sanitizeFilterString($data['company_uuid']) :  '';
1703
 
1704
 
1705
            $syncLog = new SyncLog();
1706
            $syncLog->data = json_encode($data);
1707
            $syncLog->type = $sync_type;
1708
            $syncLog->device_uuid = $device->id;
1709
            $syncLog->ip = Functions::getUserIP();
1710
 
1711
 
1712
 
1713
 
1714
            $syncLogMapper = SyncLogMapper::getInstance($this->adapter);
1715
            $syncLogMapper->insert($syncLog);
1716
 
167 efrain 1717
 
1 efrain 1718
            if($user_uuid && $device->application_id = Application::TWOGETSKILLS  && $company_uuid && in_array($sync_type, ['microlearning-progress', 'microlearning-userlog', 'microlearning-quiz'])) {
1719
                $userMapper = UserMapper::getInstance($this->adapter);
1720
                $user = $userMapper->fetchOneByUuid($user_uuid);
1721
 
1722
 
1723
 
1724
                if(!$user) {
1725
                    return new JsonModel([
1726
                        'success' => false,
1727
                        'data' => [
1728
                            'sync_id' => $sync_id,
1729
                            'message' => 'ERROR_USER_NOT_FOUND',
1730
                            'fatal' => true
1731
                        ]
1732
                    ]);
1733
                }
1734
 
1735
 
1736
                if($user->status != User::STATUS_ACTIVE) {
1737
                    return new JsonModel([
1738
                        'success' => false,
1739
                        'data' => [
1740
                            'sync_id' => $sync_id,
1741
                            'message' => 'ERROR_USER_IS_NOT_ACTIVE',
1742
                            'fatal' => true
1743
                        ]
1744
                    ]);
1745
                }
1746
 
1747
                $companyMapper = CompanyMapper::getInstance($this->adapter);
1748
                $company = $companyMapper->fetchOneByUuid($company_uuid);
1749
                if(!$company) {
1750
                    return new JsonModel([
1751
                        'success' => false,
1752
                        'data' => [
1753
                            'sync_id' => $sync_id,
1754
                            'message' => 'ERROR_COMPANY_NOT_FOUND',
1755
                            'fatal' => true
1756
                        ]
1757
                    ]);
1758
                }
1759
 
1760
                if($company->status != Company::STATUS_ACTIVE) {
1761
                    return new JsonModel([
1762
                        'success' => false,
1763
                        'data' => [
1764
                            'sync_id' => $sync_id,
1765
                            'message' => 'ERROR_COMPANY_IS_NOT_FOUND',
1766
                            'fatal' => true
1767
                        ]
1768
                    ]);
1769
                }
1770
 
1771
 
1772
 
1773
 
1774
 
1775
                $companyServiceMapper = CompanyServiceMapper::getInstance($this->adapter);
1776
                $companyService = $companyServiceMapper->fetchOneByCompanyIdAndServiceId($company->id, Service::MICRO_LEARNING);
1777
                if(!$companyService) {
1778
                    return new JsonModel([
1779
                        'success' => false,
1780
                        'data' => [
1781
                            'sync_id' => $sync_id,
1782
                            'message' => 'ERROR_COMPANY_SERVICE_NOT_FOUND',
1783
                            'fatal' => true
1784
                        ]
1785
                    ]);
1786
                }
1787
 
1788
                $serviceActive = true;
1789
                $now = date('Y-m-d H:i:s');
1790
                if($companyService->status == CompanyService::ACTIVE) {
1791
 
1792
                    if($now < $companyService->paid_from || $now > $companyService->paid_to) {
1793
                        $serviceActive = false;
1794
                    }
1795
 
1796
                } else {
1797
                    $serviceActive = false;
1798
                }
1799
 
1800
                if( !$serviceActive) {
1801
                    return new JsonModel([
1802
                        'success' => false,
1803
                        'data' => [
1804
                            'sync_id' => $sync_id,
1805
                            'message' => 'ERROR_COMPANY_SERVICE_IS_NOT_ACTIVE',
1806
                            'fatal' => true
1807
                        ]
1808
                    ]);
1809
                }
1810
 
1811
                $topicMapper = CompanyMicrolearningTopicMapper::getInstance($this->adapter);
1812
                $topic_uuid = isset($data['topic_uuid']) ? Functions::sanitizeFilterString($data['topic_uuid']) :  '';
1813
                if($topic_uuid) {
1814
                    $topic = $topicMapper->fetchOneByUuid($topic_uuid);
1815
 
1816
                    if(!$topic) {
1817
                        return new JsonModel([
1818
                            'success' => false,
1819
                            'data' => [
1820
                                'sync_id' => $sync_id,
1821
                                'message' => 'ERROR_TOPIC_NOT_FOUND',
1822
                            ]
1823
                        ]);
1824
                    }
1825
 
1826
                    if($topic->company_id != $company->id) {
1827
                        return new JsonModel([
1828
                            'success' => false,
1829
                            'data' => [
1830
                                'sync_id' => $sync_id,
1831
                                'message' => 'ERROR_INVALID_PARAMETERS_TOPIC_COMPANY',
1832
                            ]
1833
                        ]);
1834
                    }
1835
 
1836
                } else {
1837
                    $topic = null;
1838
                }
1839
 
1840
                $capsule_uuid     = isset($data['capsule_uuid']) ? Functions::sanitizeFilterString($data['capsule_uuid']) :  '';
1841
                $capsuleMapper = CompanyMicrolearningCapsuleMapper::getInstance($this->adapter);
1842
                if($capsule_uuid) {
1843
 
1844
                    $capsule = $capsuleMapper->fetchOneByUuid($capsule_uuid);
1845
                    if(!$capsule) {
1846
                        return new JsonModel([
1847
                            'success' => false,
1848
                            'data' => [
1849
                                'sync_id' => $sync_id,
1850
                                'message' => 'ERROR_CAPSULE_NOT_FOUND',
1851
                            ]
1852
                        ]);
1853
                    }
1854
 
1855
                    if(!$topic || $capsule->topic_id != $topic->id) {
1856
                        return new JsonModel([
1857
                            'success' => false,
1858
                            'data' => [
1859
                                'sync_id' => $sync_id,
1860
                                'message' => 'ERROR_INVALID_PARAMETERS_CAPSULE_TOPIC',
1861
                            ]
1862
                        ]);
1863
                    }
1864
                } else {
1865
                    $capsule = null;
1866
                }
1867
 
1868
                if($capsule) {
1869
 
1870
                    $capsuleActive = true;
1871
                    $capsuleMapper = CompanyMicrolearningCapsuleUserMapper::getInstance($this->adapter);
1872
                    $capsuleUser = $capsuleMapper->fetchOneByUserIdAndCapsuleId($user->id, $capsule->id);
1873
 
1874
 
1875
                    $now = date('Y-m-d H:i:s');
1876
                    if($capsuleUser && in_array($capsuleUser->access, [CompanyMicrolearningCapsuleUser::ACCESS_UNLIMITED,CompanyMicrolearningCapsuleUser::ACCESS_PAY_PERIOD ])) {
1877
 
1878
 
1879
                        if($capsuleUser->access == CompanyMicrolearningCapsuleUser::ACCESS_PAY_PERIOD) {
1880
 
1881
                            if($now < $capsuleUser->paid_from || $now > $capsuleUser->paid_to) {
1882
                                $capsuleActive = false;;
1883
                            }
1884
                        }
1885
 
1886
                    } else {
1887
                        $capsuleActive = false;
1888
                    }
1889
 
1890
                    if(!$capsuleActive) {
1891
                        return new JsonModel([
1892
                            'success' => false,
1893
                            'data' => [
1894
                                'sync_id' => $sync_id,
1895
                                'message' => 'ERROR_YOU_DO_NOT_HAVE_ACCESS_TO_THIS_CAPSULE',
1896
                            ]
1897
                        ]);
1898
                    }
1899
                }
1900
 
1901
 
1902
 
1903
                $slideMapper = CompanyMicrolearningSlideMapper::getInstance($this->adapter);
1904
                $slide_uuid      = isset($data['slide_uuid']) ? Functions::sanitizeFilterString($data['slide_uuid']) :  '';
1905
 
1906
 
1907
                if($slide_uuid) {
1908
 
1909
                    $slide = $slideMapper->fetchOneByUuid($slide_uuid);
1910
                    if(!$slide) {
1911
                        return new JsonModel([
1912
                            'success' => false,
1913
                            'data' => [
1914
                                'sync_id' => $sync_id,
1915
                                'message' => 'ERROR_SLIDE_NOT_FOUND',
1916
                            ]
1917
                        ]);
1918
                    }
1919
 
1920
                    if(!$capsule || $slide->capsule_id != $capsule->id) {
1921
                        return new JsonModel([
1922
                            'success' => false,
1923
                            'data' => [
1924
                                'sync_id' => $sync_id,
1925
                                'message' => 'ERROR_INVALID_PARAMETERS_SLIDE_CAPSULE',
1926
                            ]
1927
                        ]);
1928
                    }
1929
                } else {
1930
                    $slide = null;
1931
                }
1932
 
1933
 
1934
 
1935
 
1936
                if($sync_type == 'microlearning-quiz') {
1937
                    $ok = true;
1938
 
1939
                    $quiz_uuid = isset($data['quiz_uuid']) ? $data['quiz_uuid'] : '';
1940
                    $quizMapper = CompanyMicrolearningQuizMapper::getInstance($this->adapter);
1941
 
1942
                    $quiz = $quizMapper->fetchOneByUuid($quiz_uuid);
1943
                    if(!$quiz) {
1944
                        return new JsonModel([
1945
                            'success' => false,
1946
                            'data' => [
1947
                                'sync_id' => $sync_id,
1948
                                'message' => 'ERROR_SLIDE_NOT_FOUND',
1949
                            ]
1950
                        ]);
1951
                    }
1952
 
1953
                    if(!$capsule || $slide->capsule_id != $capsule->id) {
1954
                        return new JsonModel([
1955
                            'success' => false,
1956
                            'data' => [
1957
                                'sync_id' => $sync_id,
1958
                                'message' => 'ERROR_INVALID_PARAMETERS_QUIZ_SLIDE',
1959
                            ]
1960
                        ]);
1961
                    }
1962
 
1963
                    $added_on   = isset($data['added_on'])      ? Functions::sanitizeFilterString($data['added_on'])  :  '';
1964
 
1965
                    $dt = \DateTime::createFromFormat($serviceDatetimeFormat, $added_on);
1966
                    if(!$dt) {
1967
                        $ok = false;
1968
                    } else {
1969
                        $added_on = $dt->format('Y-m-d H:i:s');
1970
                    }
1971
 
1972
 
1973
                    if(isset($data['points'])) {
1974
                        $points = intval($data['points'], 10);
1975
                    } else {
1976
                        $ok = false;
1977
                    }
1978
 
1979
 
1980
                    if(isset($data['pass'])) {
1981
                        $status = $data['pass'] == 'yes' ? CompanyMicrolearningUserQuiz::STATUS_PASS : CompanyMicrolearningUserQuiz::STATUS_FAIL;
1982
                    } else {
1983
                        $ok = false;
1984
                    }
1985
 
1986
 
1987
                    if(!$ok) {
1988
                        return new JsonModel([
1989
                            'success' => false,
1990
                            'data' => [
1991
                                'sync_id' => $sync_id,
1992
                                'message' => 'ERROR_INVALID_PARAMETERS 1',
1993
                            ]
1994
                        ]);
1995
                    }
1996
 
1997
 
1998
                    $array_response = [];
1999
                    $response = isset($data['response']) ? intval($data['response'], 10) : 0;
2000
                    for($i = 0; $i < $response; $i++)
2001
                    {
2002
                        $question_uuid = isset($data["response_{$i}_question_uuid"]) ? $data["response_{$i}_question_uuid"] : '';
2003
                        $answer_uuid = isset($data["response_{$i}_answer_uuid"]) ? $data["response_{$i}_answer_uuid"] : '';
2004
                        $value = isset($data["response_{$i}_value"]) ?  intval($data["response_{$i}_value"], 10) : 0;
2005
                        $points = isset($data["response_{$i}_points"]) ?  intval($data["response_{$i}_points"], 10) : 0;
2006
 
2007
                        if($question_uuid && $answer_uuid)
2008
                        {
2009
                            array_push($array_response, [
2010
                                'question_uuid' => $question_uuid,
2011
                                'answer_uuid' => $answer_uuid,
2012
                                'value' => $value,
2013
                                'points' => $points
2014
 
2015
                            ]);
2016
                        }
2017
 
2018
 
2019
                    }
2020
 
2021
 
2022
                    $userQuiz = new CompanyMicrolearningUserQuiz();
2023
                    $userQuiz->company_id = $company->id;
2024
                    $userQuiz->topic_id = $topic->id;
2025
                    $userQuiz->capsule_id = $capsule->id;
2026
                    $userQuiz->slide_id = $slide->id;
2027
                    $userQuiz->quiz_id = $quiz->id;
2028
                    $userQuiz->user_id = $user->id;
2029
                    $userQuiz->added_on = $added_on;
2030
                    $userQuiz->points = $points;
2031
                    $userQuiz->status = $status;
2032
                    $userQuiz->response = json_encode($array_response);
2033
 
2034
                    $userQuizMapper = CompanyMicrolearningUserQuizMapper::getInstance($this->adapter);
2035
 
2036
                    if($userQuizMapper->insert($userQuiz)) {
2037
                        return new JsonModel([
2038
                            'success' => true,
2039
                            'data' => [
2040
                                'sync_id' => $sync_id
2041
                            ]
2042
                        ]);
2043
                    } else {
2044
                        return new JsonModel([
2045
                            'success' => false,
2046
                            'data' => [
2047
                                'sync_id' => $sync_id,
2048
                                'message' => $userQuizMapper->getError()
2049
                            ]
2050
                        ]);
2051
                    }
2052
 
2053
                }
2054
 
2055
 
2056
                if($sync_type == 'microlearning-progress') {
2057
                    $ok = true;
2058
 
2059
 
2060
                    $type = isset($data['type']) ? $data['type'] : '';
2061
                    switch($type)
2062
                    {
2063
                        case CompanyMicrolearningUserProgress::TYPE_TOPIC :
2064
                            if(!$topic) {
2065
                                $ok = false;
2066
                            }
2067
                            break;
2068
 
2069
                        case CompanyMicrolearningUserProgress::TYPE_CAPSULE :
2070
                            if(!$topic || !$capsule) {
2071
                                $ok = false;
2072
                            }
2073
                            break;
2074
 
2075
                        case CompanyMicrolearningUserProgress::TYPE_SLIDE :
2076
                            if(!$topic || !$capsule || !$slide) {
2077
                                $ok = false;
2078
                            }
2079
                            break;
2080
 
2081
                        default :
2082
                            $ok = false;
2083
                            break;
2084
 
2085
                    }
2086
 
2087
 
2088
                    $added_on   = isset($data['added_on'])      ? Functions::sanitizeFilterString($data['added_on'])  :  '';
2089
                    $updated_on = isset($data['updated_on'])    ? Functions::sanitizeFilterString($data['updated_on']) :  '';
2090
 
2091
                    $dt = \DateTime::createFromFormat($serviceDatetimeFormat, $added_on);
2092
                    if(!$dt) {
2093
                        $ok = false;
2094
                    } else {
2095
                        $added_on = $dt->format('Y-m-d H:i:s');
2096
                    }
2097
 
2098
                    $dt = \DateTime::createFromFormat($serviceDatetimeFormat, $updated_on );
2099
                    if(!$dt) {
2100
                        $ok = false;
2101
                    } else {
2102
                        $updated_on = $dt->format('Y-m-d H:i:s');
2103
                    }
2104
 
2105
                    if(!$ok) {
2106
                        return new JsonModel([
2107
                            'success' => false,
2108
                            'data' => [
2109
                                'sync_id' => $sync_id,
2110
                                'message' => 'ERROR_INVALID_PARAMETERS 2',
2111
                            ]
2112
                        ]);
2113
                    }
2114
 
2115
                           //$progress                   = isset($data['progress'])                  ? floatval($data['progress']) :  0;
2116
                    //$total_slides               = isset($data['total_slides'])              ? intval($data['total_slides'], 10) :  0;
2117
                    //$view_slides                = isset($data['view_slides'])               ? intval($data['view_slides'], 10) :  0;
2118
                    $returning                  = isset($data['returning'])                 ? intval($data['returning'], 10) :  0;
2119
                    $returning_after_completed  = isset($data['returning_after_completed']) ? intval($data['returning_after_completed'], 10) :  0;
2120
                    $completed                  = isset($data['completed'])                 ? intval($data['completed'], 10) :  0;
2121
 
2122
                    $progressMapper = CompanyMicrolearningUserProgressMapper::getInstance($this->adapter);
2123
                    $recordProgress = null;
2124
                    switch($type) {
2125
                        case CompanyMicrolearningUserProgress::TYPE_TOPIC  :
2126
                            $recordProgress = $progressMapper->fetchOneByUserIdAndTopicId($user->id, $topic->id);
2127
 
2128
                            break;
2129
 
2130
                        case CompanyMicrolearningUserProgress::TYPE_CAPSULE  :
2131
                            $recordProgress = $progressMapper->fetchOneByUseridAndCapsuleId($user->id, $capsule->id);
2132
                            break;
2133
 
2134
                        case CompanyMicrolearningUserProgress::TYPE_SLIDE  :
2135
                            $recordProgress = $progressMapper->fetchOneByUserIdAndSlideId($user->id, $slide->id);
2136
                            break;
2137
 
2138
                        default :
2139
                            $recordProgress= null;
2140
                    }
2141
 
2142
 
2143
                    if(!$recordProgress) {
2144
                        $recordProgress = new CompanyMicrolearningUserProgress();
2145
 
2146
                        $recordProgress->user_id    = $user->id;
2147
                        $recordProgress->type       = $type;
2148
                        $recordProgress->company_id = $topic->company_id;
2149
                        $recordProgress->topic_id   = $topic->id;
2150
                        $recordProgress->capsule_id = $capsule ? $capsule->id : null;
2151
                        $recordProgress->slide_id   = $slide ? $slide->id : null;
2152
                        $recordProgress->added_on   = $added_on;
2153
                    }
2154
                    $recordProgress->returning                  = $returning;
2155
                    $recordProgress->returning_after_completed  = $returning_after_completed;
2156
                    $recordProgress->completed                  = $completed;
2157
 
2158
                    if($type == CompanyMicrolearningUserProgress::TYPE_TOPIC ) {
2159
 
2160
                        $capsule_ids = [];
2161
                        $companyMicrolearningCapsuleUser = CompanyMicrolearningCapsuleUserMapper::getInstance($this->adapter);
2162
                        $records =  $companyMicrolearningCapsuleUser->fetchAllActiveByUserId($user->id);
2163
                        foreach($records as $record)
2164
                        {
2165
                            if($now >= $record->paid_from || $now <= $capsuleUser->paid_to) {
2166
                                if(!in_array($record->capsule_id, $capsule_ids)) {
2167
                                    array_push($capsule_ids, $record->capsule_id);
2168
                                }
2169
                            }
2170
                        }
2171
 
2172
                        $view_slides    = 0;
2173
                        $total_slides   = 0;
2174
                        foreach($capsule_ids as $capsule_id)
2175
                        {
2176
                            $view_slides    += $progressMapper->fetchCountAllSlideViewedByUserIdAndCapsuleId($user->id, $capsule_id);
2177
                            $total_slides   += $slideMapper->fetchTotalCountByCompanyIdAndTopicIdAndCapsuleId($topic->company_id, $topic->id, $capsule_id);
2178
 
2179
                        }
2180
 
2181
 
2182
                        $recordProgress->progress       = $total_slides > 0 ? (($view_slides * 100) / $total_slides) : 0;
2183
                        $recordProgress->total_slides   = $total_slides;
2184
                        $recordProgress->view_slides    = $view_slides;
2185
                    }
2186
                    else if($type == CompanyMicrolearningUserProgress::TYPE_CAPSULE ) {
2187
                        $view_slides    = $progressMapper->fetchCountAllSlideViewedByUserIdAndCapsuleId($user->id, $capsule->id);
2188
                        $total_slides   = $slideMapper->fetchTotalCountByCompanyIdAndTopicIdAndCapsuleId($topic->company_id, $capsule->topic_id, $capsule->id);
2189
 
2190
                        $recordProgress->progress       = $total_slides > 0 ? (($view_slides * 100) / $total_slides) : 0;
2191
                        $recordProgress->total_slides   = $total_slides;
2192
                        $recordProgress->view_slides    = $view_slides;
2193
                    }
2194
                    else {
2195
                        $recordProgress->progress       = 0;
2196
                        $recordProgress->total_slides   = 0;
2197
                        $recordProgress->view_slides    = 0;
2198
                    }
2199
 
2200
                    $recordProgress->updated_on = $updated_on;
2201
 
2202
 
2203
 
2204
                    if($recordProgress->id) {
2205
                        $result = $progressMapper->update($recordProgress);
2206
                    } else {
2207
                        $result = $progressMapper->insert($recordProgress);
2208
                    }
2209
 
2210
                    if($result) {
2211
                        return new JsonModel([
2212
                            'success' => true,
2213
                            'data' => [
2214
                                'sync_id' => $sync_id
2215
                            ]
2216
                        ]);
2217
                    } else {
2218
                        return new JsonModel([
2219
                            'success' => false,
2220
                            'data' => [
2221
                                'sync_id' => $sync_id,
2222
                                'message' => $progressMapper->getError()
2223
                            ]
2224
                        ]);
2225
                    }
2226
                }
2227
 
2228
 
2229
 
2230
                if($sync_type == 'microlearning-userlog') {
2231
                    $activity   = isset($data['activity'])      ? Functions::sanitizeFilterString($data['activity'])  :  '';
2232
                    $added_on   = isset($data['added_on'])      ? Functions::sanitizeFilterString($data['added_on'])  :  '';
2233
 
2234
 
2235
                    if(empty($activity)) {
2236
                        $ok = false;
2237
                    }
2238
 
2239
                    $dt = \DateTime::createFromFormat($serviceDatetimeFormat, $added_on);
2240
                    if(!$dt) {
2241
                        $ok = false;
2242
                    } else {
2243
                        $added_on = $dt->format('Y-m-d H:i:s');
2244
                    }
2245
 
2246
                    if(!$ok) {
2247
                        return new JsonModel([
2248
                            'success' => false,
2249
                            'data' => [
2250
                                'sync_id' => $sync_id,
2251
                                'message' => 'ERROR_INVALID_PARAMETERS 3',
2252
                            ]
2253
                        ]);
2254
                    }
2255
 
2256
                    $userLog = new CompanyMicrolearningUserLog();
2257
                    $userLog->activity      = $activity;
2258
                    $userLog->user_id       = $user->id;
2259
                    $userLog->company_id    = $topic->company_id;
2260
                    $userLog->topic_id      = $topic->id;
2261
                    $userLog->capsule_id    = $capsule ? $capsule->id : null;
2262
                    $userLog->slide_id      = $slide ? $slide->id : null;
2263
                    $userLog->added_on      = $added_on;
2264
 
2265
 
2266
 
2267
                    $userLogMapper = CompanyMicrolearningUserLogMapper::getInstance($this->adapter);
2268
                    if($userLogMapper->insert($userLog)) {
2269
                        return new JsonModel([
2270
                            'success' => true,
2271
                            'data' => [
2272
                                'sync_id' => $sync_id
2273
                            ]
2274
                        ]);
2275
                    } else {
2276
                        return new JsonModel([
2277
                            'success' => false,
2278
                            'data' => [
2279
                                'sync_id' => $sync_id,
2280
                                'message' => $userLogMapper->getError()
2281
                            ]
2282
                        ]);
2283
                    }
2284
                }
2285
 
2286
            }
2287
 
2288
 
2289
 
2290
 
2291
            if($user_uuid && $sync_type == 'userlog' && $device->application_id = Application::TWOGETSKILLS) {
2292
 
2293
                $userMapper = UserMapper::getInstance($this->adapter);
2294
                $user = $userMapper->fetchOneByUuid($user_uuid);
2295
 
2296
                if(!$user) {
2297
                    return new JsonModel([
2298
                        'success' => false,
2299
                        'data' => [
2300
                            'sync_id' => $sync_id,
2301
                            'message' => 'ERROR_USER_NOT_FOUND',
2302
                            'fatal' => true
2303
                        ]
2304
                    ]);
2305
                }
2306
 
2307
 
2308
                if($user->status != User::STATUS_ACTIVE) {
2309
                    return new JsonModel([
2310
                        'success' => false,
2311
                        'data' => [
2312
                            'sync_id' => $sync_id,
2313
                            'message' => 'ERROR_USER_IS_NOT_ACTIVE',
2314
                            'fatal' => true
2315
                        ]
2316
                    ]);
2317
                }
2318
 
2319
                $activity   = isset($data['activity'])      ? Functions::sanitizeFilterString($data['activity'])  :  '';
2320
                $added_on   = isset($data['added_on'])      ? Functions::sanitizeFilterString($data['added_on'])  :  '';
2321
 
2322
                if(empty($activity)) {
2323
                    $ok = false;
2324
                }
2325
 
2326
                $dt = \DateTime::createFromFormat($serviceDatetimeFormat, $added_on);
2327
                if(!$dt) {
2328
                    $ok = false;
2329
                } else {
2330
                    $added_on = $dt->format('Y-m-d H:i:s');
2331
                }
2332
 
2333
                if(!$ok) {
2334
                    return new JsonModel([
2335
                        'success' => false,
2336
                        'data' => [
2337
                            'sync_id' => $sync_id,
2338
                            'message' => 'ERROR_INVALID_PARAMETERS 4',
2339
                        ]
2340
                    ]);
2341
                }
2342
 
2343
                $userLog = new CompanyMicrolearningUserLog();
2344
                $userLog->company_id = null;
2345
                $userLog->user_id = $user->id;
2346
                $userLog->activity = $activity;
2347
                $userLog->added_on = $added_on;
2348
 
2349
 
2350
                $userLogMapper = CompanyMicrolearningUserLogMapper::getInstance($this->adapter);
2351
                if($userLogMapper->insert($userLog)) {
2352
                    return new JsonModel([
2353
                        'success' => true,
2354
                        'data' => [
2355
                            'sync_id' => $sync_id
2356
                        ]
2357
                    ]);
2358
                } else {
2359
                    return new JsonModel([
2360
                        'success' => false,
2361
                        'data' => [
2362
                            'sync_id' => $sync_id,
2363
                            'message' => $userLogMapper->getError()
2364
                        ]
2365
                    ]);
2366
                }
2367
            }
2368
 
2369
            return new JsonModel([
2370
                'success' => true,
2371
                'data' => [
2372
                    'sync_id' => $sync_id
2373
                ]
2374
            ]);
2375
 
2376
        }
2377
 
2378
        return new JsonModel([
2379
            'success' => false,
2380
            'data' => 'ERROR_METHOD_NOT_ALLOWED'
2381
        ]);
2382
    }
2383
 
2384
 
2385
    public function syncBatchAction()
2386
    {
2387
        $request = $this->getRequest();
2388
 
2389
        if($request->isPost()) {
2390
 
2391
            $rawdata = file_get_contents("php://input");
2392
            error_log('$rawdata = ' . $rawdata );
2393
            error_log(print_r($_POST, true));
2394
 
2395
            $serviceDatetimeFormat = $this->config['leaderslinked.services.datetime'];
2396
 
2397
            $device_uuid = Functions::sanitizeFilterString($this->params()->fromPost('device_uuid', ''));
2398
            $application_id = filter_var($this->params()->fromPost('application_id', 0), FILTER_SANITIZE_NUMBER_INT);
2399
            $variant_id     = filter_var($this->params()->fromPost('variant_id', 0), FILTER_SANITIZE_NUMBER_INT);
2400
            $max_records = filter_var($this->params()->fromPost('max_records', 0), FILTER_SANITIZE_NUMBER_INT);
2401
 
2402
 
2403
 
2404
 
2405
            $ok = $device_uuid && strlen($device_uuid) == 36 && $max_records;
2406
 
2407
            if(!$ok) {
2408
                return new JsonModel([
2409
                    'success' => false,
2410
                    'data' => 'ERROR_PARAMETERS_ARE_INVALID',
2411
                ]);
2412
            }
2413
 
2414
            $deviceMapper = DeviceMapper::getInstance($this->adapter);
2415
            $device = $deviceMapper->fetchOne($device_uuid);
2416
 
2417
 
2418
            if(!$device) {
2419
                return new JsonModel([
2420
                    'success' => false,
2421
                    'data' => 'ERROR_DEVICE_NOT_FOUND'
2422
                ]);
2423
            } else {
2424
 
2425
                if ($application_id && $variant_id) {
2426
                    $applicationMapper = ApplicationMapper::getInstance($this->adapter);
2427
                    $application = $applicationMapper->fetchOne($application_id);
2428
                    if(!$application) {
2429
                        return new JsonModel([
2430
                            'success' => false,
2431
                            'data' => 'ERROR_APPLICATION_NOT_FOUND',
2432
                        ]);
2433
                    }
2434
 
2435
                    if($application->status == Application::STATUS_INACTIVE) {
2436
                        return new JsonModel([
2437
                            'success' => false,
2438
                            'data' => 'ERROR_APPLICATION_IS_INACTIVE',
2439
                        ]);
2440
                    }
2441
 
2442
                    $applicationVariantMapper = ApplicationVariantMapper::getInstance($this->adapter);
2443
                    if ($variant_id) {
2444
                        $applicationVariant = $applicationVariantMapper->fetchOneByApplicationIdAndVariantId($application->id, $variant_id);
2445
                        if(!$applicationVariant) {
2446
 
2447
                            return new JsonModel([
2448
                                'success' => false,
2449
                                'data' => 'ERROR_APPLICATION_VARIANT_IS_INVALID',
2450
                            ]);
2451
                        }
2452
                    } else {
2453
                        $applicationVariant = $applicationVariantMapper->fetchOneByApplicationIdAndDefault($application->id);
2454
                    }
2455
 
2456
 
2457
                    $device->application_id = $application->id;
2458
                    $device->variant_id = $applicationVariant->variant_id;
2459
                }
2460
 
2461
 
2462
                $device->ip = Functions::getUserIP();
2463
                $deviceMapper->update($device);
2464
            }
2465
 
2466
 
2467
 
2468
 
2469
            $syncLogMapper = SyncLogMapper::getInstance($this->adapter);
2470
 
2471
 
2472
 
2473
            $result_sync_ids = [];
2474
 
2475
 
2476
 
2477
 
2478
            $users = [];
2479
            $companies = [];
2480
            $company_services = [];
2481
            $topics = [];
2482
            $capsules = [];
2483
            $capsule_users = [];
2484
            $slides = [];
2485
            $quizzes = [];
2486
            $questions = [];
2487
            $answers = [];
2488
 
2489
            $userMapper = UserMapper::getInstance($this->adapter);
2490
            $companyMapper = CompanyMapper::getInstance($this->adapter);
2491
            $companyServiceMapper = CompanyServiceMapper::getInstance($this->adapter);
2492
            $topicMapper = CompanyMicrolearningTopicMapper::getInstance($this->adapter);
2493
            $capsuleMapper = CompanyMicrolearningCapsuleMapper::getInstance($this->adapter);
2494
            $capsuleUserMapper = CompanyMicrolearningCapsuleUserMapper::getInstance($this->adapter);
2495
            $slideMapper = CompanyMicrolearningSlideMapper::getInstance($this->adapter);
2496
            $quizMapper = CompanyMicrolearningQuizMapper::getInstance($this->adapter);
2497
            $questionMapper = CompanyMicrolearningQuestionMapper::getInstance($this->adapter);
2498
            $answerMapper = CompanyMicrolearningAnswerMapper::getInstance($this->adapter);
2499
 
2500
 
2501
            $userProgressMapper = CompanyMicrolearningUserProgressMapper::getInstance($this->adapter);
2502
            $userLogMapper = CompanyMicrolearningUserLogMapper::getInstance($this->adapter);
2503
 
2504
 
2505
            for($i = 1; $i <= $max_records; $i++)
2506
            {
2507
                $sync_id        = filter_var($this->params()->fromPost('record_sync_id' . $i, ''), FILTER_SANITIZE_NUMBER_INT);
2508
                $record_data    = $this->params()->fromPost('record_data' . $i, '');
2509
 
2510
 
2511
 
2512
                if(empty($record_data) || empty($sync_id )) {
2513
                    continue;
2514
                }
2515
 
2516
 
2517
                $record         = json_decode($record_data, true);
2518
                $sync_type      = isset($record['sync_type']) ? Functions::sanitizeFilterString($record['sync_type']) : '';
2519
                $user_uuid      = isset($record['user_uuid']) ? Functions::sanitizeFilterString($record['user_uuid']) : '';
2520
                $company_uuid   = isset($record['company_uuid']) ? Functions::sanitizeFilterString($record['company_uuid']) : '';
2521
 
2522
 
2523
 
2524
 
2525
 
2526
 
2527
                if(!$sync_id) {
2528
                    continue;
2529
                }
2530
 
2531
                $syncLog = new SyncLog();
2532
                $syncLog->data = $record_data;
2533
                $syncLog->type = $sync_type;
2534
                $syncLog->device_uuid = $device->id;
2535
                $syncLog->ip = Functions::getUserIP();
2536
                $syncLogMapper->insert($syncLog);
2537
 
2538
                /***** INICIO MICROLEARNING *****/
2539
 
2540
                if($user_uuid && $device->application_id = Application::TWOGETSKILLS  && $company_uuid && in_array($sync_type, ['microlearning-progress', 'microlearning-userlog', 'microlearning-quiz'])) {
2541
 
2542
 
2543
                    if(isset($users[$user_uuid])) {
2544
                        $user = $users[$user_uuid];
2545
                    } else {
2546
 
2547
                        $user = $userMapper->fetchOneByUuid($user_uuid);
2548
                        if($user) {
2549
                            $users[$user_uuid] = $user;
2550
                        }
2551
                    }
2552
 
2553
 
2554
                    if(!$user) {
2555
                        array_push($result_sync_ids, [
2556
                            'success' => false,
2557
                            'sync_id' => $sync_id,
2558
                            'message' => 'ERROR_USER_NOT_FOUND',
2559
                            'fatal' => true
2560
                        ]);
2561
                        continue;
2562
                    }
2563
 
2564
 
2565
                    if($user->status != User::STATUS_ACTIVE) {
2566
                        array_push($result_sync_ids, [
2567
                            'success' => false,
2568
                            'sync_id' => $sync_id,
2569
                            'message' => 'ERROR_USER_IS_NOT_ACTIVE',
2570
                            'fatal' => true
2571
                        ]);
2572
                        continue;
2573
                    }
2574
 
2575
 
2576
                    if(isset($companies[$company_uuid])) {
2577
                        $company = $companies[$company_uuid];
2578
                    } else {
2579
                        $company = $companyMapper->fetchOneByUuid($company_uuid);
2580
                        if($company) {
2581
                            $companies[$company_uuid] = $company;
2582
                        }
2583
                    }
2584
 
2585
 
2586
 
2587
 
2588
                    if(!$company) {
2589
                        array_push($result_sync_ids, [
2590
                            'success' => false,
2591
                            'sync_id' => $sync_id,
2592
                            'message' => 'ERROR_COMPANY_NOT_FOUND',
2593
                            'fatal' => true
2594
                        ]);
2595
                        continue;
2596
                    }
2597
 
2598
                    if($company->status != Company::STATUS_ACTIVE) {
2599
                        array_push($result_sync_ids, [
2600
                            'success' => false,
2601
                            'sync_id' => $sync_id,
2602
                            'message' => 'ERROR_COMPANY_IS_NOT_FOUND',
2603
                            'fatal' => true
2604
                        ]);
2605
                        continue;
2606
                    }
2607
 
2608
 
2609
 
2610
                    $key = $company->id . '-' .  Service::MICRO_LEARNING;
2611
                    if(isset($company_services[$key])) {
2612
                        $companyService = $company_services[$key];
2613
                    } else {
2614
                        $companyService = $companyServiceMapper->fetchOneByCompanyIdAndServiceId($company->id, Service::MICRO_LEARNING);
2615
                        if($companyService) {
2616
                            $company_services[$key] = $companyService;
2617
                        }
2618
                    }
2619
 
2620
                    if(!$companyService) {
2621
                        array_push($result_sync_ids, [
2622
                            'success' => false,
2623
                            'sync_id' => $sync_id,
2624
                            'message' => 'ERROR_COMPANY_SERVICE_NOT_FOUND',
2625
                            'fatal' => true
2626
                        ]);
2627
                        continue;
2628
                    }
2629
 
2630
                    $serviceActive = true;
2631
                    $now = date('Y-m-d H:i:s');
2632
                    if($companyService->status == CompanyService::ACTIVE) {
2633
 
2634
                        if($now < $companyService->paid_from || $now > $companyService->paid_to) {
2635
                            $serviceActive = false;
2636
                        }
2637
 
2638
                    } else {
2639
                        $serviceActive = false;
2640
                    }
2641
 
2642
                    if( !$serviceActive) {
2643
                        array_push($result_sync_ids, [
2644
                            'success' => false,
2645
                            'sync_id' => $sync_id,
2646
                            'message' => 'ERROR_COMPANY_SERVICE_IS_NOT_ACTIVE',
2647
                            'fatal' => true
2648
                        ]);
2649
                        continue;
2650
                    }
2651
 
2652
 
2653
                    $topic_uuid = isset($record['topic_uuid']) ?   Functions::sanitizeFilterString($record['topic_uuid']) :  '';
2654
                    if($topic_uuid) {
2655
 
2656
                        if(isset($topics[$topic_uuid])) {
2657
                            $topic = $topics[$topic_uuid];
2658
                        } else {
2659
                            $topic = $topicMapper->fetchOneByUuid($topic_uuid);
2660
                            if($topic) {
2661
                                $topics[$topic_uuid] = $topic;
2662
                            }
2663
                        }
2664
 
2665
                        if(!$topic) {
2666
                            error_log(print_r($record, true));
2667
 
2668
                            array_push($result_sync_ids, [
2669
                                'success' => false,
2670
                                'sync_id' => $sync_id,
2671
                                'message' => 'ERROR_TOPIC_NOT_FOUND',
2672
                            ]);
2673
                            continue;
2674
                        }
2675
 
2676
                        if($topic->company_id != $company->id) {
2677
                            array_push($result_sync_ids, [
2678
                                'success' => false,
2679
                                'sync_id' => $sync_id,
2680
                                'message' => 'ERROR_INVALID_PARAMETERS_TOPIC_COMPANY',
2681
                            ]);
2682
                            continue;
2683
                        }
2684
 
2685
                    } else {
2686
                        $topic = null;
2687
                    }
2688
 
2689
                    $capsule_uuid     = isset($record['capsule_uuid']) ? Functions::sanitizeFilterString($record['capsule_uuid']) :  '';
2690
 
2691
                    if($capsule_uuid) {
2692
 
2693
                        if(isset($capsules[$capsule_uuid])) {
2694
                            $capsule = $capsules[$capsule_uuid];
2695
                        } else {
2696
                            $capsule = $capsuleMapper->fetchOneByUuid($capsule_uuid);
2697
                            if($capsule) {
2698
                                $capsules[$capsule_uuid] = $capsule;
2699
                            }
2700
                        }
2701
                        if(!$capsule) {
2702
                            error_log(print_r($record, true));
2703
 
2704
                            array_push($result_sync_ids, [
2705
                                'success' => false,
2706
                                'sync_id' => $sync_id,
2707
                                'message' => 'ERROR_CAPSULE_NOT_FOUND',
2708
                            ]);
2709
                            continue;
2710
                        }
2711
 
2712
                        if(!$topic || $capsule->topic_id != $topic->id) {
2713
                            array_push($result_sync_ids, [
2714
                                'success' => false,
2715
                                'sync_id' => $sync_id,
2716
                                'message' => 'ERROR_INVALID_PARAMETERS_CAPSULE_TOPIC',
2717
                            ]);
2718
                            continue;
2719
                        }
2720
                    } else {
2721
                        $capsule = null;
2722
                    }
2723
 
2724
                    if($capsule) {
2725
 
2726
                        $capsuleActive = true;
2727
 
2728
                        $key = $user->id . '-' . $capsule->id;
2729
 
2730
                        if(isset($capsule_users[$key])) {
2731
                            $capsuleUser = $capsule_users[$key];
2732
                        } else {
2733
 
2734
                            $capsuleUser = $capsuleUserMapper->fetchOneByUserIdAndCapsuleId($user->id, $capsule->id);
2735
                            if($capsuleUser) {
2736
                                $capsule_users[$key] = $capsuleUser;
2737
                            }
2738
 
2739
                        }
2740
 
2741
                        $now = date('Y-m-d H:i:s');
2742
                        if($capsuleUser && in_array($capsuleUser->access, [CompanyMicrolearningCapsuleUser::ACCESS_UNLIMITED,CompanyMicrolearningCapsuleUser::ACCESS_PAY_PERIOD ])) {
2743
 
2744
 
2745
                            if($capsuleUser->access == CompanyMicrolearningCapsuleUser::ACCESS_PAY_PERIOD) {
2746
 
2747
                                if($now < $capsuleUser->paid_from || $now > $capsuleUser->paid_to) {
2748
                                    $capsuleActive = false;;
2749
                                }
2750
                            }
2751
 
2752
                        } else {
2753
                            $capsuleActive = false;
2754
                        }
2755
 
2756
                        if(!$capsuleActive) {
2757
                            array_push($result_sync_ids, [
2758
                                'success' => false,
2759
                                'sync_id' => $sync_id,
2760
                                'message' => 'ERROR_YOU_DO_NOT_HAVE_ACCESS_TO_THIS_CAPSULE',
2761
                            ]);
2762
                            continue;
2763
                        }
2764
                    }
2765
 
2766
 
2767
                    $slide_uuid      = $record['slide_uuid'] ? Functions::sanitizeFilterString($record['slide_uuid']) :  '';
2768
                    if($slide_uuid) {
2769
 
2770
                        if(isset($slides[$slide_uuid])) {
2771
                            $slide = $slides[$slide_uuid];
2772
                        } else {
2773
 
2774
                            $slide = $slideMapper->fetchOneByUuid($slide_uuid);
2775
                            if($slide) {
2776
                                $slides[$slide_uuid] = $slide;
2777
                            }
2778
                        }
2779
                        if(!$slide) {
2780
                            error_log(print_r($record, true));
2781
 
2782
                            array_push($result_sync_ids, [
2783
                                'success' => false,
2784
                                'sync_id' => $sync_id,
2785
                                'message' => 'ERROR_SLIDE_NOT_FOUND',
2786
                            ]);
2787
                            continue;
2788
                        }
2789
 
2790
                        if(!$capsule || $slide->capsule_id != $capsule->id) {
2791
                            array_push($result_sync_ids, [
2792
                                'success' => false,
2793
                                'sync_id' => $sync_id,
2794
                                'message' => 'ERROR_INVALID_PARAMETERS_SLIDE_CAPSULE',
2795
                            ]);
2796
                            continue;
2797
                        }
2798
                    } else {
2799
                        $slide = null;
2800
                    }
2801
 
2802
                    if($sync_type == 'microlearning-quiz') {
2803
                        $ok = true;
2804
 
2805
                        $quiz_uuid = isset($record['quiz_uuid']) ? $record['quiz_uuid'] : '';
2806
 
2807
                        if(isset($quizzes[$quiz_uuid])) {
2808
                            $quiz = $quizzes[$quiz_uuid];
2809
                        } else {
2810
                            $quiz = $quizMapper->fetchOneByUuid($quiz_uuid);
2811
                            if($quiz) {
2812
                                $quizzes[$quiz_uuid] = $quiz;
2813
                            }
2814
                        }
2815
                        if(!$quiz) {
2816
                            array_push($result_sync_ids, [
2817
                                'success' => false,
2818
                                'sync_id' => $sync_id,
2819
                                'message' => 'ERROR_SLIDE_NOT_FOUND',
2820
                            ]);
2821
                            continue;
2822
                        }
2823
 
2824
                        if(!$capsule || $slide->capsule_id != $capsule->id) {
2825
                            array_push($result_sync_ids, [
2826
                                'success' => false,
2827
                                'sync_id' => $sync_id,
2828
                                'message' => 'ERROR_INVALID_PARAMETERS_QUIZ_SLIDE',
2829
                            ]);
2830
                            continue;
2831
                        }
2832
 
2833
                        $added_on   = isset($record['added_on'])      ? Functions::sanitizeFilterString($record['added_on'])  :  '';
2834
 
2835
                        $dt = \DateTime::createFromFormat($serviceDatetimeFormat, $added_on);
2836
                        if(!$dt) {
2837
                            $ok = false;
2838
                        } else {
2839
                            $added_on = $dt->format('Y-m-d H:i:s');
2840
                        }
2841
 
2842
                        if(isset($record['points'])) {
2843
                            $points = intval($record['points'], 10);
2844
                        } else {
2845
                            $ok = false;
2846
                        }
2847
 
2848
                        if(isset($record['pass'])) {
2849
                            $status = $record['pass'] == 'yes' ? CompanyMicrolearningUserQuiz::STATUS_PASS : CompanyMicrolearningUserQuiz::STATUS_FAIL;
2850
                        } else {
2851
                            $ok = false;
2852
                        }
2853
 
2854
                        if(!$ok) {
2855
                            array_push($result_sync_ids, [
2856
                                'success' => false,
2857
                                'sync_id' => $sync_id,
2858
                                'message' => 'ERROR_INVALID_PARAMETERS 9',
2859
                            ]);
2860
                            continue;
2861
                        }
2862
 
2863
                        $array_response = [];
2864
                        $response = isset($record['response']) ? intval($record['response'], 10) : 0;
2865
                        for($i = 0; $i < $response; $i++)
2866
                        {
2867
                            $question_uuid = isset($record["response_{$i}_question_uuid"]) ? $record["response_{$i}_question_uuid"] : '';
2868
                            $answer_uuid = isset($record["response_{$i}_answer_uuid"]) ? $record["response_{$i}_answer_uuid"] : '';
2869
                            $value = isset($record["response_{$i}_value"]) ?  intval($record["response_{$i}_value"], 10) : 0;
2870
                            $points = isset($record["response_{$i}_points"]) ?  intval($record["response_{$i}_points"], 10) : 0;
2871
 
2872
 
2873
                            if(isset($questions[$question_uuid])) {
2874
                                $question = $questions[$question_uuid];
2875
                            } else {
2876
                                $question = $questionMapper->fetchOneByUuid($question_uuid);
2877
                                if($question) {
2878
                                    $questions[$question_uuid] = $question;
2879
                                }
2880
                            }
2881
 
2882
                            if(!$question || $question->quiz_id != $quiz->id) {
2883
                                array_push($result_sync_ids, [
2884
                                    'success' => false,
2885
                                    'sync_id' => $sync_id,
2886
                                    'message' => 'ERROR_INVALID_PARAMETERS_QUIZ_QUESTION_SLIDE',
2887
                                ]);
2888
                                continue;
2889
                            }
2890
 
2891
                            if(isset($answers[$answer_uuid])) {
2892
                                $answer = $answers[$answer_uuid];
2893
                            } else {
2894
                                $answer = $answerMapper->fetchOneByUuid($answer_uuid);
2895
                                if($answer) {
2896
                                    $answers[$answer_uuid] = $answer;
2897
                                }
2898
                            }
2899
 
2900
                            if($answer && $answer->question_id != $question->id) {
2901
                                array_push($result_sync_ids, [
2902
                                    'success' => false,
2903
                                    'sync_id' => $sync_id,
2904
                                    'message' => 'ERROR_INVALID_PARAMETERS_QUIZ_ANSWER_SLIDE',
2905
                                ]);
2906
                                continue;
2907
                            }
2908
 
2909
                            array_push($array_response, [
2910
                                'question_uuid' => $question_uuid,
2911
                                'answer_uuid' => $answer_uuid,
2912
                                'value' => $value,
2913
                                'points' => $points
2914
                            ]);
2915
                        }
2916
 
2917
                        $userQuiz = new CompanyMicrolearningUserQuiz();
2918
                        $userQuiz->company_id = $company->id;
2919
                        $userQuiz->topic_id = $topic->id;
2920
                        $userQuiz->capsule_id = $capsule->id;
2921
                        $userQuiz->slide_id = $slide->id;
2922
                        $userQuiz->quiz_id = $quiz->id;
2923
                        $userQuiz->user_id = $user->id;
2924
                        $userQuiz->added_on = $added_on;
2925
                        $userQuiz->points = $points;
2926
                        $userQuiz->status = $status;
2927
                        $userQuiz->response = json_encode($array_response);
2928
 
2929
                        $userQuizMapper = CompanyMicrolearningUserQuizMapper::getInstance($this->adapter);
2930
 
2931
                        if($userQuizMapper->insert($userQuiz)) {
2932
                            array_push($result_sync_ids, [
2933
                                'success' => true,
2934
                                'sync_id' => $sync_id
2935
                            ]);
2936
                        } else {
2937
                            array_push($result_sync_ids, [
2938
                                'success' => false,
2939
                                'sync_id' => $sync_id,
2940
                                'message' => $userQuizMapper->getError()
2941
                            ]);
2942
                        }
2943
                        continue;
2944
                    }
2945
 
2946
                    if($sync_type == 'microlearning-progress') {
2947
                        $ok = true;
2948
 
2949
                        $type = isset($record['type']) ? $record['type'] : '';
2950
                        switch($type)
2951
                        {
2952
                            case CompanyMicrolearningUserProgress::TYPE_TOPIC :
2953
                                if(!$topic) {
2954
                                    $ok = false;
2955
                                }
2956
                                break;
2957
 
2958
                            case CompanyMicrolearningUserProgress::TYPE_CAPSULE :
2959
                                if(!$topic || !$capsule) {
2960
                                    $ok = false;
2961
                                }
2962
                                break;
2963
 
2964
                            case CompanyMicrolearningUserProgress::TYPE_SLIDE :
2965
                                if(!$topic || !$capsule || !$slide) {
2966
                                    $ok = false;
2967
                                }
2968
                                break;
2969
 
2970
                            default :
2971
                                $ok = false;
2972
                                break;
2973
                        }
2974
 
2975
                        $added_on   = isset($record['added_on'])      ? Functions::sanitizeFilterString($record['added_on'])  :  '';
2976
                        $updated_on = isset($record['updated_on'])    ? Functions::sanitizeFilterString($record['updated_on']) :  '';
2977
 
2978
                        $dt = \DateTime::createFromFormat($serviceDatetimeFormat, $added_on);
2979
                        if(!$dt) {
2980
                            $ok = false;
2981
                        } else {
2982
                            $added_on = $dt->format('Y-m-d H:i:s');
2983
                        }
2984
 
2985
                        $dt = \DateTime::createFromFormat($serviceDatetimeFormat, $updated_on );
2986
                        if(!$dt) {
2987
                            $ok = false;
2988
                        } else {
2989
                            $updated_on = $dt->format('Y-m-d H:i:s');
2990
                        }
2991
 
2992
                        if(!$ok) {
2993
                            array_push($result_sync_ids, [
2994
                                'success' => false,
2995
                                'sync_id' => $sync_id,
2996
                                'message' => 'ERROR_INVALID_PARAMETERS 10',
2997
                            ]);
2998
                            continue;
2999
                        }
3000
 
3001
                        $progress                   = isset($record['progress'])                  ? floatval($record['progress']) :  0;
3002
                        $total_slides               = isset($record['total_slides'])              ? intval($record['total_slides'], 10) :  0;
3003
                        $view_slides                = isset($record['view_slides'])               ? intval($record['view_slides'], 10) :  0;
3004
                        $returning                  = isset($record['returning'])                 ? intval($record['returning'], 10) :  0;
3005
                        $returning_after_completed  = isset($record['returning_after_completed']) ? intval($record['returning_after_completed'], 10) :  0;
3006
                        $completed                  = isset($record['completed'])                 ? intval($record['completed'], 10) :  0;
3007
 
3008
 
3009
                        $recordProgress = null;
3010
                        switch($type) {
3011
                            case CompanyMicrolearningUserProgress::TYPE_TOPIC  :
3012
                                $recordProgress = $userProgressMapper->fetchOneByUserIdAndTopicId($user->id, $topic->id);
3013
 
3014
                                break;
3015
 
3016
                            case CompanyMicrolearningUserProgress::TYPE_CAPSULE  :
3017
                                $recordProgress = $userProgressMapper->fetchOneByUseridAndCapsuleId($user->id, $capsule->id);
3018
                                break;
3019
 
3020
                            case CompanyMicrolearningUserProgress::TYPE_SLIDE  :
3021
                                $recordProgress = $userProgressMapper->fetchOneByUserIdAndSlideId($user->id, $slide->id);
3022
                                break;
3023
 
3024
                            default :
3025
                                $recordProgress= null;
3026
                        }
3027
 
3028
 
3029
                        if(!$recordProgress) {
3030
                            $recordProgress = new CompanyMicrolearningUserProgress();
3031
 
3032
                            $recordProgress->user_id    = $user->id;
3033
                            $recordProgress->type       = $type;
3034
                            $recordProgress->company_id = $topic->company_id;
3035
                            $recordProgress->topic_id   = $topic->id;
3036
                            $recordProgress->capsule_id = $capsule ? $capsule->id : null;
3037
                            $recordProgress->slide_id   = $slide ? $slide->id : null;
3038
                            $recordProgress->added_on   = $added_on;
3039
                        }
3040
                        /*
3041
                        else {
3042
 
3043
                            if($recordProgress->updated_on > $updated_on) {
3044
                                array_push($result_sync_ids, [
3045
                                    'success' => true,
3046
                                    'sync_id' => $sync_id,
3047
                                ]);
3048
                                continue;
3049
                            }
3050
 
3051
 
3052
 
3053
                        }*/
3054
                        $recordProgress->returning                  = $returning;
3055
                        $recordProgress->returning_after_completed  = $returning_after_completed;
3056
                        $recordProgress->completed                  = $completed;
3057
 
3058
                        if($type == CompanyMicrolearningUserProgress::TYPE_TOPIC ) {
3059
 
3060
                            $capsule_ids = [];
3061
                            $companyMicrolearningCapsuleUser = CompanyMicrolearningCapsuleUserMapper::getInstance($this->adapter);
3062
                            $records =  $companyMicrolearningCapsuleUser->fetchAllActiveByUserId($user->id);
3063
                            foreach($records as $record)
3064
                            {
3065
                                if($now >= $record->paid_from || $now <= $capsuleUser->paid_to) {
3066
                                    if(!in_array($record->capsule_id, $capsule_ids)) {
3067
                                        array_push($capsule_ids, $record->capsule_id);
3068
                                    }
3069
                                }
3070
                            }
3071
 
3072
                            $recordProgress->progress       = $progress;
3073
                            $recordProgress->total_slides   = $total_slides;
3074
                            $recordProgress->view_slides    = $view_slides;
3075
                        }
3076
                        else if($type == CompanyMicrolearningUserProgress::TYPE_CAPSULE ) {
3077
 
3078
                            $recordProgress->progress       = $progress;
3079
                            $recordProgress->total_slides   = $total_slides;
3080
                            $recordProgress->view_slides    = $view_slides;
3081
                        }
3082
                        else {
3083
                            $recordProgress->progress       = 0;
3084
                            $recordProgress->total_slides   = 0;
3085
                            $recordProgress->view_slides    = 0;
3086
                        }
3087
 
3088
                        $recordProgress->updated_on = $updated_on;
3089
 
3090
 
3091
 
3092
                        if($recordProgress->id) {
3093
                            $result = $userProgressMapper->update($recordProgress);
3094
                        } else {
3095
                            $result = $userProgressMapper->insert($recordProgress);
3096
                        }
3097
 
3098
                        if($result) {
3099
                            array_push($result_sync_ids, [
3100
                                'success' => true,
3101
                                'sync_id' => $sync_id
3102
                            ]);
3103
                        } else {
3104
                            array_push($result_sync_ids, [
3105
                                'success' => false,
3106
                                'sync_id' => $sync_id,
3107
                                'message' => $userProgressMapper->getError()
3108
                            ]);
3109
                        }
3110
                        continue;
3111
                    }
3112
 
3113
 
3114
 
3115
                    if($sync_type == 'microlearning-userlog') {
3116
                        $activity   = isset($record['activity'])      ? Functions::sanitizeFilterString($record['activity'])  :  '';
3117
                        $added_on   = isset($record['added_on'])      ? Functions::sanitizeFilterString($record['added_on'])  :  '';
3118
 
3119
                        if(empty($activity)) {
3120
                            $ok = false;
3121
                        }
3122
 
3123
                        $dt = \DateTime::createFromFormat($serviceDatetimeFormat, $added_on);
3124
                        if(!$dt) {
3125
                            $ok = false;
3126
                        } else {
3127
                            $added_on = $dt->format('Y-m-d H:i:s');
3128
                        }
3129
 
3130
                        if(!$ok) {
3131
                            array_push($result_sync_ids, [
3132
                                'success' => false,
3133
                                'sync_id' => $sync_id,
3134
                                'message' => 'ERROR_INVALID_PARAMETERS 11',
3135
                            ]);
3136
                            continue;
3137
                        }
3138
 
3139
 
3140
 
3141
 
3142
                        $userLog = $userLogMapper->fetchLastBy($user->id);
3143
                        if($userLog) {
3144
                            $insert = $userLog->added_on <= $added_on;
3145
                        } else {
3146
                            $insert = true;
3147
                        }
3148
 
3149
 
3150
                        if($insert) {
3151
 
3152
                            $userLog = new CompanyMicrolearningUserLog();
3153
                            $userLog->activity      = $activity;
3154
                            $userLog->user_id       = $user->id;
3155
                            $userLog->company_id    = $topic->company_id;
3156
                            $userLog->topic_id      = $topic->id;
3157
                            $userLog->capsule_id    = $capsule ? $capsule->id : null;
3158
                            $userLog->slide_id      = $slide ? $slide->id : null;
3159
                            $userLog->added_on      = $added_on;
3160
 
3161
 
3162
 
3163
 
3164
                            if($userLogMapper->insert($userLog)) {
3165
                                array_push($result_sync_ids, [
3166
                                    'success' => true,
3167
                                    'sync_id' => $sync_id
3168
                                ]);
3169
                            } else {
3170
                                array_push($result_sync_ids, [
3171
                                    'success' => false,
3172
                                    'sync_id' => $sync_id,
3173
                                    'message' => $userLogMapper->getError()
3174
                                ]);
3175
                            }
3176
                        } else {
3177
                            array_push($result_sync_ids, [
3178
                                'success' => true,
3179
                                'sync_id' => $sync_id
3180
                            ]);
3181
                        }
3182
                        continue;
3183
                    }
3184
 
3185
                }
3186
 
3187
                /***** FIN MICROLEARNING *****/
3188
 
3189
 
3190
                /***** INICIO LOG DE USUARIO GENERAL *****/
3191
 
3192
                if($user_uuid && $sync_type == 'userlog' && $device->application_id = Application::TWOGETSKILLS) {
3193
 
3194
 
3195
 
3196
                    if(isset($users[$user_uuid])) {
3197
                        $user = $users[$user_uuid];
3198
                    } else {
3199
                        $user = $userMapper->fetchOneByUuid($user_uuid);
3200
                        if($user) {
3201
                            $users[$user_uuid] = $user;
3202
                        }
3203
                    }
3204
 
3205
 
3206
 
3207
 
3208
                    if(!$user) {
3209
                        array_push($result_sync_ids, [
3210
                            'success' => false,
3211
                            'sync_id' => $sync_id,
3212
                            'message' => 'ERROR_USER_NOT_FOUND',
3213
                            'fatal' => true
3214
                        ]);
3215
                        continue;
3216
                    }
3217
 
3218
 
3219
                    if($user->status != User::STATUS_ACTIVE) {
3220
                        array_push($result_sync_ids, [
3221
                            'success' => false,
3222
                            'sync_id' => $sync_id,
3223
                            'message' => 'ERROR_USER_IS_NOT_ACTIVE',
3224
                            'fatal' => true
3225
                        ]);
3226
                        continue;
3227
                    }
3228
 
3229
                    $activity   = isset($record['activity'])      ? Functions::sanitizeFilterString($record['activity'])  :  '';
3230
                    $added_on   = isset($record['added_on'])      ? Functions::sanitizeFilterString($record['added_on'])  :  '';
3231
 
3232
                    if(empty($activity)) {
3233
                        $ok = false;
3234
                    }
3235
 
3236
                    $dt = \DateTime::createFromFormat($serviceDatetimeFormat, $added_on);
3237
                    if(!$dt) {
3238
                        $ok = false;
3239
                    } else {
3240
                        $added_on = $dt->format('Y-m-d H:i:s');
3241
                    }
3242
 
3243
                    if(!$ok) {
3244
                        array_push($result_sync_ids, [
3245
                            'success' => false,
3246
                            'sync_id' => $sync_id,
3247
                            'message' => 'ERROR_INVALID_PARAMETERS 12',
3248
                        ]);
3249
                        continue;
3250
                    }
3251
 
3252
 
3253
                    $userLog = $userLogMapper->fetchLastBy($user->id);
3254
                    if($userLog) {
3255
                        $insert = $userLog->added_on <= $added_on;
3256
                    } else {
3257
                        $insert = true;
3258
                    }
3259
 
3260
 
3261
                    if($insert) {
3262
                        $userLog = new CompanyMicrolearningUserLog();
3263
                        $userLog->company_id = null;
3264
                        $userLog->user_id = $user->id;
3265
                        $userLog->activity = $activity;
3266
                        $userLog->added_on = $added_on;
3267
 
3268
 
3269
                        $userLogMapper = CompanyMicrolearningUserLogMapper::getInstance($this->adapter);
3270
                        if($userLogMapper->insert($userLog)) {
3271
                            array_push($result_sync_ids, [
3272
                                'success' => true,
3273
                                'sync_id' => $sync_id
3274
                            ]);
3275
                        } else {
3276
                            array_push($result_sync_ids, [
3277
                                'success' => false,
3278
                                'sync_id' => $sync_id,
3279
                                'message' => $userLogMapper->getError()
3280
                            ]);
3281
                        }
3282
                    } else {
3283
                        array_push($result_sync_ids, [
3284
                            'success' => true,
3285
                            'sync_id' => $sync_id
3286
                        ]);
3287
                    }
3288
 
3289
 
3290
 
3291
                    continue;
3292
                }
3293
 
3294
                /***** FIN LOG DE USUARIO GENERAL ******/
3295
            }
3296
 
3297
            if( $result_sync_ids) {
3298
                return new JsonModel([
3299
                    'success' => true,
3300
                    'data' => $result_sync_ids
3301
                ]);
3302
            } else {
3303
                return new JsonModel([
3304
                    'success' => false,
3305
                    'data' => 'ERROR_INVALID_PARAMETERS 13'
3306
                ]);
3307
            }
3308
 
3309
 
3310
        }
3311
 
3312
        return new JsonModel([
3313
            'success' => false,
3314
            'data' => 'ERROR_METHOD_NOT_ALLOWED'
3315
        ]);
3316
    }
3317
 
3318
    public function deleteAccountAction()
3319
    {
3320
        $rawdata = file_get_contents("php://input");
3321
        error_log('url = ' . $_SERVER['REQUEST_URI']);
3322
        error_log('query = ' . $_SERVER['QUERY_STRING']);
3323
        error_log('$rawdata = ' . $rawdata );
3324
 
3325
 
3326
        $currentUserPlugin = $this->plugin('currentUserPlugin');
3327
        $user = $currentUserPlugin->getUser();
3328
 
3329
 
3330
 
3331
        $request = $this->getRequest();
3332
 
3333
        if($request->isGet()) {
3334
 
3335
            $this->sendEmailDeleteAccountKey($user);
3336
 
3337
 
3338
            return new JsonModel([
3339
                'success' => true,
3340
                'data' => [
3341
                    'message' => 'LABEL_DELETE_ACCOUNT_WE_HAVE_SENT_A_CONFIRMATION_CODE'
3342
                ]
3343
            ]);
3344
 
3345
        } else  if($request->isPost()) {
3346
 
3347
            $code = $this->params()->fromPost('code');
3348
            if(empty($code) || $code != $user->delete_account_key) {
3349
 
3350
                $this->sendEmailDeleteAccountKey($user);
3351
 
3352
                return new JsonModel([
3353
                    'success' => false,
3354
                    'data' => [
3355
                        'message' => 'ERROR_DELETE_ACCOUNT_CONFIRMATION_CODE_IS_WRONG'
3356
                    ]
3357
                ]);
3358
            }
3359
 
3360
            $delete_account_generated_on = strtotime($user->delete_account_generated_on);
3361
            $expiry_time = $delete_account_generated_on + $this->config['leaderslinked.security.delete_account_expired'];
3362
 
3363
 
3364
            if (time() > $expiry_time) {
3365
 
3366
                $this->sendEmailDeleteAccountKey($user) ;
3367
 
3368
                return new JsonModel([
3369
                    'success' => false,
3370
                    'data' => [
3371
                        'message' => 'ERROR_DELETE_ACCOUNT_CONFIRMATION_CODE_EXPIRED'
3372
                    ]
3373
                ]);
3374
 
3375
 
3376
            }
3377
 
3378
            $userDeleted  = new UserDeleted();
3379
            $userDeleted->user_id = $user->id;
3380
            $userDeleted->first_name = $user->first_name;
3381
            $userDeleted->last_name = $user->last_name;
3382
            $userDeleted->email = $user->email;
3383
            $userDeleted->image = $user->image;
3384
            $userDeleted->phone = $user->phone;
3385
            $userDeleted->pending = UserDeleted::PENDING_YES;
3386
 
3387
 
3388
            $userDeletedMapper = UserDeletedMapper::getInstance($this->adapter);
3389
            if ($userDeletedMapper->insert($userDeleted)) {
3390
 
3391
                $this->sendEmailDeleteAccountCompleted($user);
3392
 
3393
                $user->first_name = 'LABEL_DELETE_ACCOUNT_FIRST_NAME';
3394
                $user->last_name = 'LABEL_DELETE_ACCOUNT_LAST_NAME';
3395
                $user->email = 'user-deleted-' . uniqid() . '@leaderslinked.com';
3396
                $user->image = '';
3397
                $user->usertype_id = UserType::USER_DELETED;
3398
                $user->status = User::STATUS_DELETED;
3399
                $user->delete_account_key = '';
3400
                $user->delete_account_generated_on = '';
3401
 
3402
                $userMapper = UserMapper::getInstance($this->adapter);
3403
                if($userMapper->update($user)) {
3404
 
3405
 
3406
 
3407
                    return new JsonModel([
3408
                        'success' => true,
3409
                        'data' => [
3410
                            'message' => 'LABEL_DELETE_ACCOUNT_WE_HAVE_STARTED_DELETING_YOUR_DATA',
3411
                        ]
3412
                    ]);
3413
 
3414
 
3415
                } else {
3416
                    return new JsonModel([
3417
                        'success' => false,
3418
                        'data' => [
3419
                            'message' => $userDeletedMapper->getError()
3420
                        ]
3421
                    ]);
3422
                }
3423
 
3424
 
3425
 
3426
            } else {
3427
                return new JsonModel([
3428
                    'success' => false,
3429
                    'data' => [
3430
                        'message' => $userDeletedMapper->getError()
3431
                    ]
3432
                ]);
3433
            }
3434
 
3435
 
3436
 
3437
 
3438
 
3439
        }
3440
 
3441
 
3442
            return new JsonModel([
3443
                'success' => false,
3444
                'data' => 'ERROR_METHOD_NOT_ALLOWED'
3445
            ]);
3446
    }
3447
 
3448
 
3449
    private function sendEmailDeleteAccountKey($user)
3450
    {
3451
        $delete_account_key = Functions::generatePassword(8);
3452
 
3453
        $userMapper = UserMapper::getInstance($this->adapter);
3454
        $userMapper->updateDeleteAccountKey($user->id, $delete_account_key);
3455
 
3456
        $emailTemplateMapper = EmailTemplateMapper::getInstance($this->adapter);
3457
        $emailTemplate = $emailTemplateMapper->fetchOneByCodeAndNetworkId(EmailTemplate::CODE_DELETE_ACCOUNT_CODE, $user->network_id);
3458
        if($emailTemplate) {
3459
            $arrayCont = [
3460
                'firstname' => $user->first_name,
3461
                'lastname'  => $user->last_name,
3462
                'code'      => $delete_account_key,
3463
                'link'      => ''
3464
            ];
3465
 
3466
            $email = new QueueEmail($this->adapter);
3467
            $email->processEmailTemplate($emailTemplate, $arrayCont, $user->email, trim($user->first_name . ' ' . $user->last_name));
3468
        }
3469
    }
3470
 
3471
 
3472
    private function sendEmailDeleteAccountCompleted($user)
3473
    {
3474
 
3475
        $emailTemplateMapper = EmailTemplateMapper::getInstance($this->adapter);
3476
        $emailTemplate = $emailTemplateMapper->fetchOneByCodeAndNetworkId(EmailTemplate::CODE_DELETE_ACCOUNT_COMPLETED, $user->network_id);
3477
        if($emailTemplate) {
3478
            $arrayCont = [
3479
                'firstname' => $user->first_name,
3480
                'lastname'  => $user->last_name,
3481
                'code'      => '',
3482
                'link'      => ''
3483
            ];
3484
 
3485
            $email = new QueueEmail($this->adapter);
3486
            $email->processEmailTemplate($emailTemplate, $arrayCont, $user->email, trim($user->first_name . ' ' . $user->last_name));
3487
        }
3488
    }
3489
 
3490
 
3491
    /**
3492
     *
3493
     * @param User $user
3494
     * @param boolean $includeLogs
3495
     * @param boolean $includeProgress
3496
     * @return array[]
3497
     */
3498
    private function getSyncData($user, $includeLogs = true, $includeProgress = true)
3499
    {
3500
 
3501
        $serviceDatetimeFormat = $this->config['leaderslinked.services.datetime'];
3502
 
3503
        $data = [
3504
            'userlog'   => [],
3505
            'progress'  => [],
3506
            'topics'    => [],
3507
            'quizzes'   => [],
3508
            'extended'  => [],
3509
        ];
3510
 
3511
 
3512
        $companies = [];
3513
        $companyMapper = CompanyMapper::getInstance($this->adapter);
3514
 
3515
        $topics = [];
3516
        $topicMapper = CompanyMicrolearningTopicMapper::getInstance($this->adapter);
3517
 
3518
        $capsules = [];
3519
        $capsuleMapper = CompanyMicrolearningCapsuleMapper::getInstance($this->adapter);
3520
 
3521
        $slides = [];
3522
        $slideMapper = CompanyMicrolearningSlideMapper::getInstance($this->adapter);
3523
 
3524
        $quizzes = [];
3525
        $quizMapper = CompanyMicrolearningQuizMapper::getInstance($this->adapter);
3526
 
3527
        $questions = [];
3528
        $questionMapper = CompanyMicrolearningQuestionMapper::getInstance($this->adapter);
3529
 
3530
        $answers = [];
3531
        $answerMapper = CompanyMicrolearningAnswerMapper::getInstance($this->adapter);
3532
 
3533
 
3534
        $userLogMapper = CompanyMicrolearningUserLogMapper::getInstance($this->adapter);
3535
 
3536
        if($includeLogs) {
3537
 
3538
            //$records = $userLogMapper->fetchLast20ByUserId($user->id);
3539
            $records = $userLogMapper->fetchAllByUserId($user->id);
3540
            foreach($records as $record)
3541
            {
3542
                $dt = \DateTime::createFromFormat('Y-m-d H:i:s', $record->added_on);
3543
 
3544
                if($record->company_id) {
3545
 
3546
                   if(isset($companies[$record->company_id])) {
3547
                        $company = $companies[$record->company_id];
3548
                    } else {
3549
                        $company = $companyMapper->fetchOne($record->company_id);
3550
                        $companies[$record->company_id] = $company;
3551
                    }
3552
                } else {
3553
                    $company = null;
3554
                }
3555
 
3556
                if($record->topic_id) {
3557
 
3558
                    if(isset($topics[$record->topic_id])) {
3559
                        $topic = $topics[$record->topic_id];
3560
                    } else {
3561
                        $topic = $topicMapper->fetchOne($record->topic_id);
3562
                        $topics[$record->topic_id] = $topic;
3563
                    }
3564
                } else {
3565
                    $topic = null;
3566
                }
3567
 
3568
 
3569
                if($record->capsule_id) {
3570
 
3571
                    if(isset($capsules[$record->capsule_id])) {
3572
                        $capsule = $capsules[$record->capsule_id];
3573
                    } else {
3574
                        $capsule = $capsuleMapper->fetchOne($record->capsule_id);
3575
                        $capsules[$record->capsule_id] = $capsule;
3576
                    }
3577
                } else {
3578
                    $capsule = null;
3579
                }
3580
 
3581
 
3582
                if($record->slide_id) {
3583
 
3584
                    if(isset($slides[$record->slide_id])) {
3585
                        $slide = $slides[$record->slide_id];
3586
                    } else {
3587
                        $slide = $slideMapper->fetchOne($record->slide_id);
3588
                        $slides[$record->slide_id] = $slide;
3589
                    }
3590
                } else {
3591
                    $slide = null;
3592
                }
3593
 
3594
 
3595
                array_push($data['userlog'], [
3596
                    'user_uuid'     => $user->uuid,
3597
                    'company_uuid'  => $company ? $company->uuid : '',
3598
                    'topic_uuid'    => $topic ? $topic->uuid : '',
3599
                    'capsule_uuid'  => $capsule ? $capsule->uuid : '',
3600
                    'slide_uuid'    => $slide ? $slide->uuid : '',
3601
                    'activity'      => $record->activity,
3602
                    'added_on'      => $dt->format($serviceDatetimeFormat),
3603
                ]);
3604
 
3605
 
3606
            }
3607
        }
3608
 
3609
        if($includeProgress) {
3610
 
3611
            $userProgressMapper = CompanyMicrolearningUserProgressMapper::getInstance($this->adapter);
3612
            $records = $userProgressMapper->fetchAllByUserId($user->id);
3613
            foreach($records as $record)
3614
            {
3615
                if($record->company_id) {
3616
 
3617
                    if(isset($companies[$record->company_id])) {
3618
                        $company = $companies[$record->company_id];
3619
                    } else {
3620
                        $company = $companyMapper->fetchOne($record->company_id);
3621
                        $companies[$record->company_id] = $company;
3622
                    }
3623
                } else {
3624
                    $company = null;
3625
                }
3626
 
3627
                if($record->topic_id) {
3628
 
3629
                    if(isset($topics[$record->topic_id])) {
3630
                        $topic = $topics[$record->topic_id];
3631
                    } else {
3632
                        $topic = $topicMapper->fetchOne($record->topic_id);
3633
                        $topics[$record->topic_id] = $topic;
3634
                    }
3635
                } else {
3636
                    $topic = null;
3637
                }
3638
 
3639
 
3640
                if($record->capsule_id) {
3641
 
3642
                    if(isset($capsules[$record->capsule_id])) {
3643
                        $capsule = $capsules[$record->capsule_id];
3644
                    } else {
3645
                        $capsule = $capsuleMapper->fetchOne($record->capsule_id);
3646
                        $capsules[$record->capsule_id] = $capsule;
3647
                    }
3648
                } else {
3649
                    $capsule = null;
3650
                }
3651
 
3652
 
3653
                if($record->slide_id) {
3654
 
3655
                    if(isset($slides[$record->slide_id])) {
3656
                        $slide = $slides[$record->slide_id];
3657
                    } else {
3658
                        $slide = $slideMapper->fetchOne($record->slide_id);
3659
                        $slides[$record->slide_id] = $slide;
3660
                    }
3661
                } else {
3662
                    $slide = null;
3663
                }
3664
 
3665
 
3666
                $dtAddedOn = \DateTime::createFromFormat('Y-m-d H:i:s', $record->added_on);
3667
                $dtUpdatedOn = \DateTime::createFromFormat('Y-m-d H:i:s', $record->updated_on);
3668
 
3669
                array_push($data['progress'], [
3670
                    'user_uuid'                 => $user->uuid,
3671
                    'company_uuid'              => $company ? $company->uuid : '',
3672
                    'topic_uuid'                => $topic ? $topic->uuid : '',
3673
                    'capsule_uuid'              => $capsule ? $capsule->uuid : '',
3674
                    'slide_uuid'                => $slide ? $slide->uuid : '',
3675
                    'progress'                  => $record->progress ? $record->progress : 0,
3676
                    'total_slides'              => $record->total_slides ? $record->total_slides : 0,
3677
                    'view_slides'               => $record->view_slides ? $record->view_slides : 0,
3678
                    'type'                      => $record->type,
3679
                    'returning'                 => $record->returning ? $record->returning : 0,
3680
                    'returning_after_completed' => $record->returning_after_completed ? $record->returning_after_completed : 0,
3681
                    'completed'                 => $record->completed ? $record->completed : 0,
3682
                    'added_on'                  => $dtAddedOn->format($serviceDatetimeFormat),
3683
                    'updated_on'                => $dtUpdatedOn->format($serviceDatetimeFormat),
3684
                ]);
3685
            }
3686
        }
3687
 
3688
 
3689
        $now = date('Y-m-d H:i:s');
3690
        $companies_with_access  = [];
3691
        $topics_with_access     = [];
3692
        $capsules_with_access   = [];
3693
        $quizzes_with_access    = [];
3694
        $quizzes                = [];
3695
 
3696
 
3697
        $capsuleCommentMapper = CompanyMicrolearningCapsuleCommentMapper::getInstance($this->adapter);
3698
        $capsuleUserMapper = CompanyMicrolearningCapsuleUserMapper::getInstance($this->adapter);
3699
        $records = $capsuleUserMapper->fetchAllActiveByUserId($user->id);
3700
 
3701
 
3702
        foreach($records as $record)
3703
        {
3704
            if($record->access != CompanyMicrolearningCapsuleUser::ACCESS_UNLIMITED && $record->access != CompanyMicrolearningCapsuleUser::ACCESS_PAY_PERIOD) {
3705
                continue;
3706
            }
3707
            if($record->access == CompanyMicrolearningCapsuleUser::ACCESS_PAY_PERIOD) {
3708
                if($now < $record->paid_from || $now > $record->paid_to) {
3709
                    continue;
3710
                }
3711
            }
3712
 
3713
 
3714
            if(!in_array($record->company_id,$companies_with_access)) {
3715
                array_push($companies_with_access, $record->company_id);
3716
            }
3717
 
3718
            if(!in_array($record->topic_id,$topics_with_access)) {
3719
                array_push($topics_with_access, $record->topic_id);
3720
            }
3721
 
3722
            if(!in_array($record->capsule_id,$capsules_with_access)) {
3723
                array_push($capsules_with_access, $record->capsule_id);
3724
            }
3725
        }
3726
 
3727
 /*
3728
        echo '$companies_with_access ' . PHP_EOL;
3729
        print_r($companies_with_access);
3730
 
3731
        echo '$topics_with_access ' . PHP_EOL;
3732
        print_r($topics_with_access);
3733
 
3734
        echo '$capsules_with_access' . PHP_EOL;
3735
        print_r($capsules_with_access);
3736
        */
3737
 
3738
        $companyServiceMapper = CompanyServiceMapper::getInstance($this->adapter);
3739
        foreach($companies_with_access as $company_id)
3740
        {
3741
            $companyService =  $companyServiceMapper->fetchOneActiveByCompanyIdAndServiceId($company_id, Service::MICRO_LEARNING);
3742
 
3743
            //print_r($companyService); exit;
3744
 
3745
            if(!$companyService) {
3746
                continue;
3747
            }
3748
 
3749
 
3750
            if(isset($companies[$companyService->company_id])) {
3751
                $company = $companies[$companyService->company_id];
3752
            } else {
3753
                $company = $companyMapper->fetchOne($companyService->company_id);
3754
                $companies[$companyService->company_id] = $company;
3755
            }
3756
 
3757
            $topics = $topicMapper->fetchAllActiveByCompanyId($company_id);
3758
            foreach($topics as $topic)
3759
            {
3760
                if(!in_array($topic->id, $topics_with_access)) {
3761
                    continue;
3762
                }
3763
 
3764
                $record_capsules = [];
3765
                $capsules = $capsuleMapper->fetchAllActiveByCompanyIdAndTopicId($topic->company_id, $topic->id);
3766
                foreach($capsules as $capsule)
3767
                {
3768
                    if(!in_array($capsule->id, $capsules_with_access)) {
3769
                        continue;
3770
                    }
3771
 
3772
 
3773
                    $record_slides = [];
3774
                    $slides = $slideMapper->fetchAllByCompanyIdAndTopicIdAndCapsuleId($capsule->company_id, $capsule->topic_id, $capsule->id);
3775
                    foreach($slides as $slide)
3776
                    {
3777
                        if($slide->type == CompanyMicrolearningSlide::TYPE_QUIZ) {
3778
                            if(!in_array($slide->quiz_id, $quizzes_with_access)) {
3779
                                array_push($quizzes_with_access, $slide->quiz_id);
3780
                            }
3781
 
3782
                            if(isset($quizzes[$slide->quiz_id])) {
3783
                                $quiz = $quizzes[$slide->quiz_id];
3784
 
3785
                            } else {
3786
                                $quiz = $quizMapper->fetchOne($slide->quiz_id);
3787
                                $quizzes[$slide->quiz_id] =  $quiz;
3788
                            }
3789
                        } else {
3790
                            $quiz = null;
3791
                        }
3792
 
3793
 
3794
                        $dtAddedOn = \DateTime::createFromFormat('Y-m-d H:i:s', $slide->added_on);
3795
                        $dtUpdatedOn = \DateTime::createFromFormat('Y-m-d H:i:s', $slide->updated_on);
3796
 
3797
                        array_push($record_slides, [
3798
                            'uuid' => $slide->uuid,
3799
                            'quiz_uuid' => $quiz ? $quiz->uuid : '',
3800
                            'name' => $slide->name ? $slide->name : '',
3801
                            'description' => $slide->description ? $slide->description : '',
3802
                            'position' => $slide->order,
3803
                            'type' => $slide->type,
3804
                            'background' => $slide->background ? $this->url()->fromRoute('services/storage',['type' => 'microlearning-slide', 'code' => $slide->uuid, 'filename' => $slide->background], ['force_canonical' => true]) : '',
3805
                            'file' => $slide->file ? $this->url()->fromRoute('services/storage',['type' => 'microlearning-slide', 'code' => $slide->uuid, 'filename' => $slide->file], ['force_canonical' => true]) : '',
3806
                            'added_on'  => $dtAddedOn->format($serviceDatetimeFormat),
3807
                            'updated_on'    => $dtUpdatedOn->format($serviceDatetimeFormat),
3808
                        ]);
3809
                    }
3810
 
3811
                    $dtAddedOn = \DateTime::createFromFormat('Y-m-d H:i:s', $capsule->added_on);
3812
                    $dtUpdatedOn = \DateTime::createFromFormat('Y-m-d H:i:s', $capsule->updated_on);
3813
 
3814
                    $dataCountrAndRatingAverage = $capsuleCommentMapper->fetchCountAndRatingAverage($capsule->company_id, $capsule->topic_id, $capsule->id);
3815
 
3816
 
3817
 
3818
                    array_push($record_capsules, [
3819
                        'uuid' => $capsule->uuid,
3820
                        'name' => $capsule->name ? $capsule->name : '',
3821
                        'description' => $capsule->description ? $capsule->description : '',
3822
                        'image' => $capsule->image ? $this->url()->fromRoute('services/storage',['type' => 'microlearning-capsule', 'code' => $capsule->uuid, 'filename' => $capsule->image ], ['force_canonical' => true])  : '',
3823
                        'position' => $capsule->order,
3824
                        'slides' => $record_slides,
3825
                        'link_comments' => $this->url()->fromRoute('services/microlearning/capsules/comments', ['capsule_id' => $capsule->uuid], ['force_canonical' => true]),
3826
                        'link_comment_add' => $this->url()->fromRoute('services/microlearning/capsules/comments/add', ['capsule_id' => $capsule->uuid],['force_canonical' => true]),
3827
                        'total_comments' => strval($dataCountrAndRatingAverage['total_comments']),
3828
                        'total_rating' => strval($dataCountrAndRatingAverage['total_rating']),
3829
                        'added_on'  => $dtAddedOn->format($serviceDatetimeFormat),
3830
                        'updated_on'    => $dtUpdatedOn->format($serviceDatetimeFormat),
3831
                    ]);
3832
                }
3833
 
3834
                $dtAddedOn = \DateTime::createFromFormat('Y-m-d H:i:s', $topic->added_on);
3835
                $dtUpdatedOn = \DateTime::createFromFormat('Y-m-d H:i:s', $topic->updated_on);
3836
 
3837
                array_push($data['topics'], [
3838
                    'uuid' => $topic->uuid,
3839
                    'name' => $topic->name ? $topic->name : '',
3840
                    'description' => $topic->description ? $topic->description : '',
3841
                    'image' => $topic->image ? $this->url()->fromRoute('services/storage',['type' => 'microlearning-topic', 'code' => $topic->uuid, 'filename' => $topic->image ], ['force_canonical' => true]) : '',
3842
                    'position' => $topic->order,
3843
                    'company_uuid' => $company->uuid,
3844
                    'company_name' => $company->name,
3845
                    'company_image' => $this->url()->fromRoute('services/storage',['type' => 'company', 'code' => $company->uuid, 'filename' => $company->image], ['force_canonical' => true]),
3846
                    'capsules' => $record_capsules,
3847
                    'added_on'  => $dtAddedOn->format($serviceDatetimeFormat),
3848
                    'updated_on'    => $dtUpdatedOn->format($serviceDatetimeFormat),
3849
 
3850
                ]);
3851
 
3852
 
3853
 
3854
 
3855
            }
3856
        }
3857
 
3858
 
3859
 
3860
        foreach($quizzes_with_access as $quiz_id)
3861
        {
3862
            if(isset($quizzes[$quiz_id])) {
3863
                $quiz = $quizzes[$quiz_id];
3864
            } else {
3865
                $quiz = $quizMapper->fetchOne($quiz_id);
3866
                array_push($quizzes, $quiz);
3867
            }
3868
 
3869
            if(isset($companies[$quiz->company_id])) {
3870
                $company = $companies[$quiz->company_id];
3871
            } else {
3872
                $company = $companyMapper->fetchOne($quiz->company_id);
3873
                $companies[$quiz->company_id] = $company;
3874
            }
3875
 
3876
 
3877
            $record_questions = [];
3878
            $questions = $questionMapper->fetchAllByQuizId($quiz->id);
3879
            foreach($questions as $question)
3880
            {
3881
                $record_answers = [];
3882
 
3883
                $answers = $answerMapper->fetchAllByQuizIdAndQuestionId($question->quiz_id, $question->id);
3884
                foreach($answers as $answer)
3885
                {
3886
 
3887
                    $dtAddedOn = \DateTime::createFromFormat('Y-m-d H:i:s', $answer->added_on);
3888
                    $dtUpdatedOn = \DateTime::createFromFormat('Y-m-d H:i:s', $answer->updated_on);
3889
 
3890
                    array_push($record_answers, [
3891
                        'uuid' => $answer->uuid,
3892
                        'text' => trim($answer->text),
3893
                        'correct' => $answer->correct ? $answer->correct  : 0 ,
3894
                        'points' => strval(intval($answer->points, 10)),
3895
                        'added_on'  => $dtAddedOn->format($serviceDatetimeFormat),
3896
                        'updated_on'    => $dtUpdatedOn->format($serviceDatetimeFormat),
3897
                    ]);
3898
                }
3899
 
3900
                $dtAddedOn = \DateTime::createFromFormat('Y-m-d H:i:s', $question->added_on);
3901
                $dtUpdatedOn = \DateTime::createFromFormat('Y-m-d H:i:s', $question->updated_on);
3902
 
3903
                array_push($record_questions, [
3904
                    'uuid'          => $question->uuid,
3905
                    'text'          => trim($question->text),
3906
                    'type'          => $question->type,
3907
                    'maxlength'     => strval($question->maxlength),
3908
                    'points'        => strval($question->points),
3909
                    'answers'       => $record_answers,
3910
                    'added_on'      => $dtAddedOn->format($serviceDatetimeFormat),
3911
                    'updated_on'    => $dtUpdatedOn->format($serviceDatetimeFormat),
3912
                ]);
3913
            }
3914
 
3915
            $dtAddedOn = \DateTime::createFromFormat('Y-m-d H:i:s', $quiz->added_on);
3916
            $dtUpdatedOn = \DateTime::createFromFormat('Y-m-d H:i:s', $quiz->updated_on);
3917
 
3918
 
3919
            array_push($data['quizzes'], [
3920
                'uuid' => $quiz->uuid,
3921
                'name' => $quiz->name,
3922
                'text' => trim($quiz->text ? $quiz->text : ''),
3923
                'failed' => trim($quiz->failed ? $quiz->failed : ''),
3924
                'points' => strval($quiz->points),
3925
                'minimum_points_required' => strval($quiz->minimum_points_required),
3926
                'max_time' => $quiz->max_time ? $quiz->max_time : 5,
3927
                'company_uuid' => $company->uuid,
3928
                'company_name' => $company->name,
3929
                'company_image' => $this->url()->fromRoute('services/storage',['type' => 'company', 'code' => $company->uuid, 'filename' => $company->image], ['force_canonical' => true]),
3930
                'questions'     => $record_questions,
3931
                'added_on'      => $dtAddedOn->format($serviceDatetimeFormat),
3932
                'updated_on'    => $dtUpdatedOn->format($serviceDatetimeFormat),
3933
            ]);
3934
        }
3935
 
3936
        $companyExtendUserMapper = CompanyMicrolearningExtendUserMapper::getInstance($this->adapter);
3937
        $companyExtendUserCompanyMapper = CompanyMicrolearningExtendUserCompanyMapper::getInstance($this->adapter);
3938
        $companyExtendUserFunctionMapper = CompanyMicrolearningExtendUserFunctionMapper::getInstance($this->adapter);
3939
        $companyExtendUserGroupMapper = CompanyMicrolearningExtendUserGroupMapper::getInstance($this->adapter);
3940
        $companyExtendUserInstitutionMapper = CompanyMicrolearningExtendUserInstitutionMapper::getInstance($this->adapter);
3941
        $companyExtendUserPartnerMapper = CompanyMicrolearningExtendUserPartnerMapper::getInstance($this->adapter);
3942
        $companyExtendUserProgramMapper = CompanyMicrolearningExtendUserProgramMapper::getInstance($this->adapter);
3943
        $companyExtendUserStudentTypeMapper = CompanyMicrolearningExtendUserStudentTypeMapper::getInstance($this->adapter);
3944
        $companyExtendUserSectorMapper = CompanyMicrolearningExtendUserSectorMapper::getInstance($this->adapter);
3945
 
3946
        $companyServiceMapper = CompanyServiceMapper::getInstance($this->adapter);
3947
        foreach($companies_with_access as $company_id)
3948
        {
3949
            $companyService =  $companyServiceMapper->fetchOneActiveByCompanyIdAndServiceId($company_id, Service::MICRO_LEARNING);
3950
 
3951
            //print_r($companyService); exit;
3952
 
3953
            if(!$companyService) {
3954
                continue;
3955
            }
3956
 
3957
 
3958
            if(isset($companies[$companyService->company_id])) {
3959
                $company = $companies[$companyService->company_id];
3960
            } else {
3961
                $company = $companyMapper->fetchOne($companyService->company_id);
3962
                $companies[$companyService->company_id] = $company;
3963
            }
3964
 
3965
            if(!$company) {
3966
                continue;
3967
            }
3968
 
3969
            $record = [
3970
                'company_uuid' => $company->uuid,
3971
                'company_name' => $company->name,
3972
                'company_image' => $this->url()->fromRoute('services/storage',['type' => 'company', 'code' => $company->uuid, 'filename' => $company->image], ['force_canonical' => true]),
3973
                'details' => [],
3974
            ];
3975
 
3976
            $companyExtendUser = $companyExtendUserMapper->fetchOneByCompanyIdAndUserId($company->id, $user->id);
3977
            if(!$companyExtendUser) {
3978
                continue;
3979
            }
3980
 
3981
            if($companyExtendUser->extend_company_id) {
3982
 
3983
                $extendedCompany = $companyExtendUserCompanyMapper->fetchOne($companyExtendUser->company_id);
3984
                if($extendedCompany) {
3985
                    array_push($record['details'],[
3986
                        'uuid' => $extendedCompany->uuid,
3987
                        'label' => 'LABEL_COMPANY',
3988
                        'value' => $extendedCompany->name
3989
                    ]);
3990
                }
3991
            }
3992
 
3993
            if($companyExtendUser->extend_function_id) {
3994
                $extendedFunction = $companyExtendUserFunctionMapper->fetchOne($companyExtendUser->extend_function_id);
3995
                if($extendedFunction) {
3996
                    array_push($record['details'],[
3997
                        'uuid' => $extendedFunction->uuid,
3998
                        'label' => 'LABEL_FUNCTION',
3999
                        'value' => $extendedFunction->name
4000
                    ]);
4001
                }
4002
            }
4003
 
4004
            if($companyExtendUser->extend_group_id) {
4005
                $extendedGroup = $companyExtendUserGroupMapper->fetchOne($companyExtendUser->extend_group_id);
4006
                if($extendedGroup) {
4007
                    array_push($record['details'],[
4008
                        'uuid' => $extendedGroup->uuid,
4009
                        'label' => 'LABEL_GROUP',
4010
                        'value' => $extendedGroup->name
4011
                    ]);
4012
                }
4013
            }
4014
 
4015
            if($companyExtendUser->extend_institution_id) {
4016
                $extendedInstitution= $companyExtendUserInstitutionMapper->fetchOne($companyExtendUser->extend_institution_id);
4017
                if($extendedInstitution) {
4018
                    array_push($record['details'],[
4019
                        'uuid' => $extendedInstitution->uuid,
4020
                        'label' => 'LABEL_INSTITUTION',
4021
                        'value' => $extendedInstitution->name
4022
                    ]);
4023
                }
4024
            }
4025
 
4026
            if($companyExtendUser->extend_program_id) {
4027
                $extendedProgram = $companyExtendUserProgramMapper->fetchOne($companyExtendUser->extend_program_id);
4028
                if($extendedProgram) {
4029
                    array_push($record['details'],[
4030
                        'uuid' => $extendedProgram->uuid,
4031
                        'label' => 'LABEL_PROGRAM',
4032
                        'value' => $extendedProgram->name
4033
                    ]);
4034
 
4035
                }
4036
            }
4037
 
4038
            if($companyExtendUser->extend_sector_id) {
4039
                $extendedSector = $companyExtendUserSectorMapper->fetchOne($companyExtendUser->extend_sector_id);
4040
                if($extendedSector) {
4041
                    array_push($record['details'],[
4042
                        'uuid' => $extendedSector->uuid,
4043
                        'label' => 'LABEL_SECTOR',
4044
                        'value' => $extendedSector->name
4045
                    ]);
4046
                }
4047
            }
4048
 
4049
            if($companyExtendUser->extend_partner_id) {
4050
                $extendedPartner = $companyExtendUserPartnerMapper->fetchOne($companyExtendUser->extend_partner_id);
4051
                if($extendedPartner) {
4052
                    array_push($record['details'],[
4053
                        'uuid' => $extendedPartner->uuid,
4054
                        'label' => 'LABEL_PARTNER',
4055
                        'value' => $extendedPartner->name
4056
                    ]);
4057
                }
4058
            }
4059
 
4060
            if($companyExtendUser->extend_student_type_id) {
4061
                $extendedStudentType = $companyExtendUserStudentTypeMapper->fetchOne($companyExtendUser->extend_student_type_id);
4062
                if($extendedStudentType) {
4063
                    array_push($record['details'],[
4064
                        'uuid' => $extendedStudentType->uuid,
4065
                        'label' => 'LABEL_TYPE',
4066
                        'value' => $extendedStudentType->name
4067
                    ]);
4068
                }
4069
            }
4070
 
4071
            array_push($data['extended'], $record);
4072
        }
4073
 
4074
        return $data;
4075
    }
4076
 
4077
 
4078
    /**
4079
     *
4080
     * @param string $filename
4081
     * @param boolean $retbytes
4082
     * @return boolean|number
4083
     */
4084
    private function readfile_chunked($filename, $retbytes = true) {
4085
        $buffer = '';
4086
        $cnt =0;;
4087
        $handle = fopen($filename,'rb');
4088
        if ($handle === false) {
4089
            return false;
4090
        }
4091
        while (!feof($handle)) {
4092
            $buffer = fread($handle, self::CHUNK_SIZE);
4093
            echo $buffer;
4094
            ob_flush();
4095
            flush();
4096
            if ($retbytes) {
4097
                $cnt += strlen($buffer);
4098
            }
4099
        }
4100
        $status = fclose($handle);
4101
        if ($retbytes && $status) {
4102
            return $cnt; // return num. bytes delivered like readfile() does.
4103
        }
4104
        return $status;
4105
    }
4106
}
4107
 
4108