Proyectos de Subversion LeadersLinked - Antes de SPA

Rev

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

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