Completed
Push — master ( 4fc9f8...d0e06e )
by Julito
12:04
created

Certificate   F

Complexity

Total Complexity 119

Size/Duplication

Total Lines 931
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 475
dl 0
loc 931
rs 2
c 0
b 0
f 0
wmc 119

17 Methods

Rating   Name   Duplication   Size   Complexity  
A check_certificate_path() 0 17 5
B show() 0 40 6
A isHtmlFileGenerated() 0 13 5
C generateUserSkills() 0 47 15
C generateCustomCertificate() 0 147 14
A updateUserCertificateInfo() 0 19 3
F generate() 0 167 21
A generatePdfFromCustomCertificate() 0 22 3
A notificationTags() 0 14 1
A sendNotification() 0 50 4
A isAvailable() 0 13 3
A parseCertificateVariables() 0 43 3
A getCertificateByUser() 0 13 2
A generateQRImage() 0 15 3
B delete() 0 27 10
A isVisible() 0 33 6
C __construct() 0 78 15

How to fix   Complexity   

Complex Class

Complex classes like Certificate often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Certificate, and based on these observations, apply Extract Interface, too.

1
<?php
2
/* For licensing terms, see /license.txt */
3
4
use Endroid\QrCode\QrCode;
5
6
/**
7
 * Certificate Class
8
 * Generate certificates based in the gradebook tool.
9
 */
10
class Certificate extends Model
11
{
12
    public $table;
13
    public $columns = [
14
        'id',
15
        'cat_id',
16
        'score_certificate',
17
        'created_at',
18
        'path_certificate',
19
    ];
20
    /**
21
     * Certification data.
22
     */
23
    public $certificate_data = [];
24
25
    /**
26
     * Student's certification path.
27
     */
28
    public $certification_user_path = null;
29
    public $certification_web_user_path = null;
30
    public $html_file = null;
31
    public $qr_file = null;
32
    public $user_id;
33
34
    /** If true every time we enter to the certificate URL
35
     * we would generate a new certificate (good thing because we can edit the
36
     * certificate and all users will have the latest certificate bad because we.
37
     * load the certificate every time */
38
    public $force_certificate_generation = true;
39
40
    /**
41
     * Constructor.
42
     *
43
     * @param int  $certificate_id        ID of the certificate
44
     * @param int  $userId
45
     * @param bool $sendNotification      send message to student
46
     * @param bool $updateCertificateData
47
     *
48
     * If no ID given, take user_id and try to generate one
49
     */
50
    public function __construct(
51
        $certificate_id = 0,
52
        $userId = 0,
53
        $sendNotification = false,
54
        $updateCertificateData = true
55
    ) {
56
        $this->table = Database::get_main_table(TABLE_MAIN_GRADEBOOK_CERTIFICATE);
57
        $this->user_id = !empty($userId) ? $userId : api_get_user_id();
58
59
        if (!empty($certificate_id)) {
60
            $certificate = $this->get($certificate_id);
61
            if (!empty($certificate) && is_array($certificate)) {
62
                $this->certificate_data = $certificate;
63
                $this->user_id = $this->certificate_data['user_id'];
64
            }
65
        }
66
67
        if ($this->user_id) {
68
            // Need to be called before any operation
69
            $this->check_certificate_path();
70
            // To force certification generation
71
            if ($this->force_certificate_generation) {
72
                $this->generate([], $sendNotification);
73
            }
74
            if (isset($this->certificate_data) && $this->certificate_data) {
75
                if (empty($this->certificate_data['path_certificate'])) {
76
                    $this->generate([], $sendNotification);
77
                }
78
            }
79
        }
80
81
        // Setting the qr and html variables
82
        if (isset($certificate_id) &&
83
            !empty($this->certification_user_path) &&
84
            isset($this->certificate_data['path_certificate'])
85
        ) {
86
            $pathinfo = pathinfo($this->certificate_data['path_certificate']);
87
            $this->html_file = $this->certification_user_path.basename($this->certificate_data['path_certificate']);
88
            $this->qr_file = $this->certification_user_path.$pathinfo['filename'].'_qr.png';
89
        } else {
90
            $this->check_certificate_path();
91
            if (api_get_configuration_value('allow_general_certificate')) {
92
                // General certificate
93
                $name = md5($this->user_id).'.html';
94
                $my_path_certificate = $this->certification_user_path.$name;
95
                $path_certificate = '/'.$name;
96
97
                // Getting QR filename
98
                $file_info = pathinfo($path_certificate);
99
                $content = $this->generateCustomCertificate();
100
101
                $my_new_content_html = str_replace(
102
                    '((certificate_barcode))',
103
                    Display::img(
104
                        $this->certification_web_user_path.$file_info['filename'].'_qr.png',
105
                        'QR'
106
                    ),
107
                    $content
108
                );
109
110
                $my_new_content_html = mb_convert_encoding(
111
                    $my_new_content_html,
112
                    'UTF-8',
113
                    api_get_system_encoding()
114
                );
115
116
                $this->html_file = $my_path_certificate;
117
                $result = @file_put_contents($my_path_certificate, $my_new_content_html);
118
119
                if ($result) {
120
                    // Updating the path
121
                    self::updateUserCertificateInfo(
122
                        0,
123
                        $this->user_id,
124
                        $path_certificate,
125
                        $updateCertificateData
126
                    );
127
                    $this->certificate_data['path_certificate'] = $path_certificate;
128
                }
129
            }
130
        }
131
    }
132
133
    /**
134
     * Checks if the certificate user path directory is created.
135
     */
136
    public function check_certificate_path()
137
    {
138
        $this->certification_user_path = null;
139
140
        // Setting certification path
141
        $path_info = UserManager::getUserPathById($this->user_id, 'system');
142
        $web_path_info = UserManager::getUserPathById($this->user_id, 'web');
143
144
        if (!empty($path_info) && isset($path_info)) {
145
            $this->certification_user_path = $path_info.'certificate/';
146
            $this->certification_web_user_path = $web_path_info.'certificate/';
147
            $mode = api_get_permissions_for_new_directories();
148
            if (!is_dir($path_info)) {
149
                mkdir($path_info, $mode, true);
150
            }
151
            if (!is_dir($this->certification_user_path)) {
152
                mkdir($this->certification_user_path, $mode);
153
            }
154
        }
155
    }
156
157
    /**
158
     * Deletes the current certificate object. This is generally triggered by
159
     * the teacher from the gradebook tool to re-generate the certificate because
160
     * the original version wa flawed.
161
     *
162
     * @param bool $force_delete
163
     *
164
     * @return bool
165
     */
166
    public function delete($force_delete = false)
167
    {
168
        $delete_db = false;
169
        if (!empty($this->certificate_data)) {
170
            if (!is_null($this->html_file) || '' != $this->html_file || strlen($this->html_file)) {
171
                // Deleting HTML file
172
                if (is_file($this->html_file)) {
173
                    @unlink($this->html_file);
174
                    if (false === is_file($this->html_file)) {
175
                        $delete_db = true;
176
                    } else {
177
                        $delete_db = false;
178
                    }
179
                }
180
                // Deleting QR code PNG image file
181
                if (is_file($this->qr_file)) {
182
                    @unlink($this->qr_file);
183
                }
184
                if ($delete_db || $force_delete) {
185
                    return parent::delete($this->certificate_data['id']);
186
                }
187
            } else {
188
                return parent::delete($this->certificate_data['id']);
189
            }
190
        }
191
192
        return false;
193
    }
194
195
    /**
196
     *  Generates an HTML Certificate and fills the path_certificate field in the DB.
197
     *
198
     * @param array $params
199
     * @param bool  $sendNotification
200
     *
201
     * @return bool|int
202
     */
203
    public function generate($params = [], $sendNotification = false)
204
    {
205
        // The user directory should be set
206
        if (empty($this->certification_user_path) &&
207
            false === $this->force_certificate_generation
208
        ) {
209
            return false;
210
        }
211
212
        $params['hide_print_button'] = isset($params['hide_print_button']) ? true : false;
213
        $categoryId = 0;
214
        $my_category = [];
215
        if (isset($this->certificate_data) && isset($this->certificate_data['cat_id'])) {
216
            $categoryId = $this->certificate_data['cat_id'];
217
            $my_category = Category::load($categoryId);
218
        }
219
220
        if (isset($my_category[0]) && !empty($categoryId) &&
221
            $my_category[0]->is_certificate_available($this->user_id)
222
        ) {
223
            /** @var Category $category */
224
            $category = $my_category[0];
225
226
            $courseInfo = api_get_course_info($category->get_course_code());
227
            $courseId = $courseInfo['real_id'];
228
            $sessionId = $category->get_session_id();
229
230
            $skill = new Skill();
231
            $skill->addSkillToUser(
232
                $this->user_id,
233
                $category,
234
                $courseId,
235
                $sessionId
236
            );
237
238
            if (is_dir($this->certification_user_path)) {
239
                if (!empty($this->certificate_data)) {
240
                    $new_content_html = GradebookUtils::get_user_certificate_content(
241
                        $this->user_id,
242
                        $category->get_course_code(),
243
                        $category->get_session_id(),
244
                        false,
245
                        $params['hide_print_button']
246
                    );
247
248
                    if ($category->get_id() == $categoryId) {
249
                        $name = $this->certificate_data['path_certificate'];
250
                        $myPathCertificate = $this->certification_user_path.basename($name);
251
252
                        if (file_exists($myPathCertificate) &&
253
                            !empty($name) &&
254
                            !is_dir($myPathCertificate) &&
255
                            false == $this->force_certificate_generation
256
                        ) {
257
                            // Seems that the file was already generated
258
                            return true;
259
                        } else {
260
                            // Creating new name
261
                            $name = md5($this->user_id.$this->certificate_data['cat_id']).'.html';
262
                            $myPathCertificate = $this->certification_user_path.$name;
263
                            $path_certificate = '/'.$name;
264
265
                            // Getting QR filename
266
                            $file_info = pathinfo($path_certificate);
267
                            $qr_code_filename = $this->certification_user_path.$file_info['filename'].'_qr.png';
268
269
                            $newContent = str_replace(
270
                                '((certificate_barcode))',
271
                                Display::img(
272
                                    $this->certification_web_user_path.$file_info['filename'].'_qr.png',
273
                                    'QR'
274
                                ),
275
                                $new_content_html['content']
276
                            );
277
278
                            $newContent = api_convert_encoding(
279
                                $newContent,
280
                                'UTF-8',
281
                                api_get_system_encoding()
282
                            );
283
284
                            $result = @file_put_contents($myPathCertificate, $newContent);
285
                            if ($result) {
286
                                // Updating the path
287
                                $this->updateUserCertificateInfo(
288
                                    $this->certificate_data['cat_id'],
289
                                    $this->user_id,
290
                                    $path_certificate
291
                                );
292
                                $this->certificate_data['path_certificate'] = $path_certificate;
293
294
                                if ($this->isHtmlFileGenerated()) {
295
                                    if (!empty($file_info)) {
296
                                        $text = $this->parseCertificateVariables(
297
                                            $new_content_html['variables']
298
                                        );
299
                                        $this->generateQRImage(
300
                                            $text,
301
                                            $qr_code_filename
302
                                        );
303
304
                                        if ($sendNotification) {
305
                                            $subject = get_lang('Certificate notification');
306
                                            $message = nl2br(get_lang('((user_first_name)),'));
307
                                            $score = $this->certificate_data['score_certificate'];
308
                                            self::sendNotification(
309
                                                $subject,
310
                                                $message,
311
                                                api_get_user_info($this->user_id),
312
                                                $courseInfo,
313
                                                [
314
                                                    'score_certificate' => $score,
315
                                                ]
316
                                            );
317
                                        }
318
                                    }
319
                                }
320
                            }
321
322
                            return $result;
323
                        }
324
                    }
325
                }
326
            }
327
        } else {
328
            $this->check_certificate_path();
329
330
            // General certificate
331
            $name = md5($this->user_id).'.html';
332
            $my_path_certificate = $this->certification_user_path.$name;
333
            $path_certificate = '/'.$name;
334
335
            // Getting QR filename
336
            $file_info = pathinfo($path_certificate);
337
            $content = $this->generateCustomCertificate();
338
339
            $my_new_content_html = str_replace(
340
                '((certificate_barcode))',
341
                Display::img(
342
                    $this->certification_web_user_path.$file_info['filename'].'_qr.png',
343
                    'QR'
344
                ),
345
                $content
346
            );
347
348
            $my_new_content_html = mb_convert_encoding(
349
                $my_new_content_html,
350
                'UTF-8',
351
                api_get_system_encoding()
352
            );
353
354
            $result = @file_put_contents($my_path_certificate, $my_new_content_html);
355
356
            if ($result) {
357
                // Updating the path
358
                self::updateUserCertificateInfo(
359
                    0,
360
                    $this->user_id,
361
                    $path_certificate
362
                );
363
                $this->certificate_data['path_certificate'] = $path_certificate;
364
            }
365
366
            return $result;
367
        }
368
369
        return false;
370
    }
371
372
    /**
373
     * @return array
374
     */
375
    public static function notificationTags()
376
    {
377
        $tags = [
378
            '((course_title))',
379
            '((user_first_name))',
380
            '((user_last_name))',
381
            '((author_first_name))',
382
            '((author_last_name))',
383
            '((score))',
384
            '((portal_name))',
385
            '((certificate_link))',
386
        ];
387
388
        return $tags;
389
    }
390
391
    /**
392
     * @param string $subject
393
     * @param string $message
394
     * @param array  $userInfo
395
     * @param array  $courseInfo
396
     * @param array  $certificateInfo
397
     *
398
     * @return bool
399
     */
400
    public static function sendNotification(
401
        $subject,
402
        $message,
403
        $userInfo,
404
        $courseInfo,
405
        $certificateInfo
406
    ) {
407
        if (empty($userInfo) || empty($courseInfo)) {
408
            return false;
409
        }
410
411
        $currentUserInfo = api_get_user_info();
412
        $url = api_get_path(WEB_PATH).
413
            'certificates/index.php?id='.$certificateInfo['id'].'&user_id='.$certificateInfo['user_id'];
414
        $link = Display::url($url, $url);
415
416
        $replace = [
417
            $courseInfo['title'],
418
            $userInfo['firstname'],
419
            $userInfo['lastname'],
420
            $currentUserInfo['firstname'],
421
            $currentUserInfo['lastname'],
422
            $certificateInfo['score_certificate'],
423
            api_get_setting('Institution'),
424
            $link,
425
        ];
426
427
        $message = str_replace(self::notificationTags(), $replace, $message);
428
        MessageManager::send_message(
429
            $userInfo['id'],
430
            $subject,
431
            $message,
432
            [],
433
            [],
434
            0,
435
            0,
436
            0,
437
            0,
438
            $currentUserInfo['id']
439
        );
440
441
        $plugin = new AppPlugin();
442
        $smsPlugin = $plugin->getSMSPluginLibrary();
443
        if ($smsPlugin) {
0 ignored issues
show
introduced by
$smsPlugin is of type SmsPluginLibraryInterface, thus it always evaluated to true.
Loading history...
444
            $additionalParameters = [
445
                'smsType' => SmsPlugin::CERTIFICATE_NOTIFICATION,
446
                'userId' => $userInfo['id'],
447
                'direct_message' => $message,
448
            ];
449
            $smsPlugin->send($additionalParameters);
450
        }
451
    }
452
453
    /**
454
     * Update user info about certificate.
455
     *
456
     * @param int    $categoryId            category id
457
     * @param int    $user_id               user id
458
     * @param string $path_certificate      the path name of the certificate
459
     * @param bool   $updateCertificateData
460
     */
461
    public function updateUserCertificateInfo(
462
        $categoryId,
463
        $user_id,
464
        $path_certificate,
465
        $updateCertificateData = true
466
    ) {
467
        $categoryId = (int) $categoryId;
468
        $user_id = (int) $user_id;
469
470
        if ($updateCertificateData &&
471
            !UserManager::is_user_certified($categoryId, $user_id)
472
        ) {
473
            $table = Database::get_main_table(TABLE_MAIN_GRADEBOOK_CERTIFICATE);
474
            $now = api_get_utc_datetime();
475
            $sql = 'UPDATE '.$table.' SET 
476
                        path_certificate="'.Database::escape_string($path_certificate).'",
477
                        created_at = "'.$now.'"
478
                    WHERE cat_id = "'.$categoryId.'" AND user_id="'.$user_id.'" ';
479
            Database::query($sql);
480
        }
481
    }
482
483
    /**
484
     * Check if the file was generated.
485
     *
486
     * @return bool
487
     */
488
    public function isHtmlFileGenerated()
489
    {
490
        if (empty($this->certification_user_path)) {
491
            return false;
492
        }
493
        if (!empty($this->certificate_data) &&
494
            isset($this->certificate_data['path_certificate']) &&
495
            !empty($this->certificate_data['path_certificate'])
496
        ) {
497
            return true;
498
        }
499
500
        return false;
501
    }
502
503
    /**
504
     * Generates a QR code for the certificate. The QR code embeds the text given.
505
     *
506
     * @param string $text Text to be added in the QR code
507
     * @param string $path file path of the image
508
     *
509
     * @return bool
510
     */
511
    public function generateQRImage($text, $path)
512
    {
513
        // Make sure HTML certificate is generated
514
        if (!empty($text) && !empty($path)) {
515
            $qrCode = new QrCode($text);
516
            $qrCode->setWriterByName('png');
517
            $qrCode->writeFile($path);
518
519
            //L low, M - Medium, L large error correction
520
            //return QrCode::png($text, $path, 'M', 2, 2);
521
522
            return file_exists($path);
523
        }
524
525
        return false;
526
    }
527
528
    /**
529
     * Transforms certificate tags into text values. This function is very static
530
     * (it doesn't allow for much flexibility in terms of what tags are printed).
531
     *
532
     * @param array $array Contains two array entries: first are the headers,
533
     *                     second is an array of contents
534
     *
535
     * @return string The translated string
536
     */
537
    public function parseCertificateVariables($array)
538
    {
539
        $headers = $array[0];
540
        $content = $array[1];
541
        $final_content = [];
542
543
        if (!empty($content)) {
544
            foreach ($content as $key => $value) {
545
                $my_header = str_replace(['((', '))'], '', $headers[$key]);
546
                $final_content[$my_header] = $value;
547
            }
548
        }
549
550
        /* Certificate tags
551
         *
552
          0 => string '((user_firstname))' (length=18)
553
          1 => string '((user_lastname))' (length=17)
554
          2 => string '((gradebook_institution))' (length=25)
555
          3 => string '((gradebook_sitename))' (length=22)
556
          4 => string '((teacher_firstname))' (length=21)
557
          5 => string '((teacher_lastname))' (length=20)
558
          6 => string '((official_code))' (length=17)
559
          7 => string '((date_certificate))' (length=20)
560
          8 => string '((course_code))' (length=15)
561
          9 => string '((course_title))' (length=16)
562
          10 => string '((gradebook_grade))' (length=19)
563
          11 => string '((certificate_link))' (length=20)
564
          12 => string '((certificate_link_html))' (length=25)
565
          13 => string '((certificate_barcode))' (length=23)
566
         */
567
568
        $break_space = " \n\r ";
569
        $text =
570
            $final_content['gradebook_institution'].' - '.
571
            $final_content['gradebook_sitename'].' - '.
572
            get_lang('Certification').$break_space.
573
            get_lang('Learner').': '.$final_content['user_firstname'].' '.$final_content['user_lastname'].$break_space.
574
            get_lang('Trainer').': '.$final_content['teacher_firstname'].' '.$final_content['teacher_lastname'].$break_space.
575
            get_lang('Date').': '.$final_content['date_certificate'].$break_space.
576
            get_lang('Score').': '.$final_content['gradebook_grade'].$break_space.
577
            'URL'.': '.$final_content['certificate_link'];
578
579
        return $text;
580
    }
581
582
    /**
583
     * Check if the certificate is visible for the current user
584
     * If the global setting allow_public_certificates is set to 'false', no certificate can be printed.
585
     * If the global allow_public_certificates is set to 'true' and the course setting allow_public_certificates
586
     * is set to 0, no certificate *in this course* can be printed (for anonymous users).
587
     * Connected users can always print them.
588
     *
589
     * @return bool
590
     */
591
    public function isVisible()
592
    {
593
        if (!api_is_anonymous()) {
594
            return true;
595
        }
596
597
        if ('true' != api_get_setting('allow_public_certificates')) {
598
            // The "non-public" setting is set, so do not print
599
            return false;
600
        }
601
602
        if (!isset($this->certificate_data, $this->certificate_data['cat_id'])) {
603
            return false;
604
        }
605
606
        $gradeBook = new Gradebook();
607
        $gradeBookInfo = $gradeBook->get($this->certificate_data['cat_id']);
608
609
        if (empty($gradeBookInfo['course_code'])) {
610
            return false;
611
        }
612
613
        $setting = api_get_course_setting(
614
            'allow_public_certificates',
615
            api_get_course_info($gradeBookInfo['course_code'])
616
        );
617
618
        if (0 == $setting) {
619
            // Printing not allowed
620
            return false;
621
        }
622
623
        return true;
624
    }
625
626
    /**
627
     * Check if the certificate is available.
628
     *
629
     * @return bool
630
     */
631
    public function isAvailable()
632
    {
633
        if (empty($this->certificate_data['path_certificate'])) {
634
            return false;
635
        }
636
637
        $userCertificate = $this->certification_user_path.basename($this->certificate_data['path_certificate']);
638
639
        if (!file_exists($userCertificate)) {
640
            return false;
641
        }
642
643
        return true;
644
    }
645
646
    /**
647
     * Shows the student's certificate (HTML file).
648
     */
649
    public function show()
650
    {
651
        $user_certificate = $this->certification_user_path.basename($this->certificate_data['path_certificate']);
652
        if (file_exists($user_certificate)) {
653
            // Needed in order to browsers don't add custom CSS
654
            $certificateContent = '<!DOCTYPE html>';
655
            $certificateContent .= (string) file_get_contents($user_certificate);
656
657
            // Remove media=screen to be available when printing a document
658
            $certificateContent = str_replace(
659
                ' media="screen"',
660
                '',
661
                $certificateContent
662
            );
663
664
            if ($this->user_id == api_get_user_id() &&
665
                !empty($this->certificate_data) &&
666
                isset($this->certificate_data['id'])
667
            ) {
668
                $certificateId = $this->certificate_data['id'];
669
                $extraFieldValue = new ExtraFieldValue('user_certificate');
670
                $value = $extraFieldValue->get_values_by_handler_and_field_variable(
671
                    $certificateId,
672
                    'downloaded_at'
673
                );
674
                if (empty($value)) {
675
                    $params = [
676
                        'item_id' => $this->certificate_data['id'],
677
                        'extra_downloaded_at' => api_get_utc_datetime(),
678
                    ];
679
                    $extraFieldValue->saveFieldValues($params);
680
                }
681
            }
682
683
            header('Content-Type: text/html; charset='.api_get_system_encoding());
684
            echo $certificateContent;
685
686
            return;
687
        }
688
        api_not_allowed(true);
689
    }
690
691
    /**
692
     * @return string
693
     */
694
    public function generateCustomCertificate()
695
    {
696
        $myCertificate = GradebookUtils::get_certificate_by_user_id(
697
            0,
698
            $this->user_id
699
        );
700
        if (empty($myCertificate)) {
701
            GradebookUtils::registerUserInfoAboutCertificate(
702
                0,
703
                $this->user_id,
704
                100,
705
                api_get_utc_datetime()
706
            );
707
        }
708
709
        $userInfo = api_get_user_info($this->user_id);
710
        $extraFieldValue = new ExtraFieldValue('user');
711
        $value = $extraFieldValue->get_values_by_handler_and_field_variable($this->user_id, 'legal_accept');
712
        $termsValidationDate = '';
713
        if (isset($value) && !empty($value['value'])) {
714
            list($id, $id2, $termsValidationDate) = explode(':', $value['value']);
715
        }
716
717
        $sessions = SessionManager::get_sessions_by_user($this->user_id, false, true);
718
        $totalTimeInLearningPaths = 0;
719
        $sessionsApproved = [];
720
        $coursesApproved = [];
721
        $courseList = [];
722
723
        if ($sessions) {
724
            foreach ($sessions as $session) {
725
                $allCoursesApproved = [];
726
                foreach ($session['courses'] as $course) {
727
                    $courseInfo = api_get_course_info_by_id($course['real_id']);
728
                    $courseCode = $courseInfo['code'];
729
                    $gradebookCategories = Category::load(
730
                        null,
731
                        null,
732
                        $courseCode,
733
                        null,
734
                        false,
735
                        $session['session_id']
736
                    );
737
738
                    if (isset($gradebookCategories[0])) {
739
                        /** @var Category $category */
740
                        $category = $gradebookCategories[0];
741
                        $result = Category::userFinishedCourse(
742
                            $this->user_id,
743
                            $category,
744
                            true
745
                        );
746
747
                        // Find time spent in LP
748
                        $timeSpent = Tracking::get_time_spent_in_lp(
749
                            $this->user_id,
750
                            $courseCode,
751
                            [],
752
                            $session['session_id']
753
                        );
754
755
                        if (!isset($courseList[$course['real_id']])) {
756
                            $courseList[$course['real_id']]['approved'] = false;
757
                            $courseList[$course['real_id']]['time_spent'] = 0;
758
                        }
759
760
                        if ($result) {
761
                            $courseList[$course['real_id']]['approved'] = true;
762
                            $coursesApproved[$course['real_id']] = $courseInfo['title'];
763
764
                            // Find time spent in LP
765
                            //$totalTimeInLearningPaths += $timeSpent;
766
                            $allCoursesApproved[] = true;
767
                        }
768
                        $courseList[$course['real_id']]['time_spent'] += $timeSpent;
769
                    }
770
                }
771
772
                if (count($allCoursesApproved) == count($session['courses'])) {
773
                    $sessionsApproved[] = $session;
774
                }
775
            }
776
        }
777
778
        $totalTimeInLearningPaths = 0;
779
        foreach ($courseList as $courseId => $courseData) {
780
            if (true === $courseData['approved']) {
781
                $totalTimeInLearningPaths += $courseData['time_spent'];
782
            }
783
        }
784
785
        $skill = new Skill();
786
        // Ofaj
787
        $skills = $skill->getStudentSkills($this->user_id, 2);
788
        $timeInSeconds = Tracking::get_time_spent_on_the_platform(
789
            $this->user_id,
790
            'ever'
791
        );
792
        $time = api_time_to_hms($timeInSeconds);
793
794
        $tplContent = new Template(null, false, false, false, false, false);
795
796
        // variables for the default template
797
        $tplContent->assign('complete_name', $userInfo['complete_name']);
798
        $tplContent->assign('time_in_platform', $time);
799
        $tplContent->assign('certificate_generated_date', api_get_local_time($myCertificate['created_at']));
800
        if (!empty($termsValidationDate)) {
801
            $termsValidationDate = api_get_local_time($termsValidationDate);
802
        }
803
        $tplContent->assign('terms_validation_date', $termsValidationDate);
804
805
        // Ofaj
806
        $tplContent->assign('time_in_platform_in_hours', round($timeInSeconds / 3600, 1));
807
        $tplContent->assign(
808
            'certificate_generated_date_no_time',
809
            api_get_local_time(
810
                $myCertificate['created_at'],
811
                null,
812
                null,
813
                false,
814
                false,
815
                false,
816
                'd-m-Y'
817
            )
818
        );
819
        $tplContent->assign(
820
            'terms_validation_date_no_time',
821
            api_get_local_time(
822
                $termsValidationDate,
823
                null,
824
                null,
825
                false,
826
                false,
827
                false,
828
                'd-m-Y'
829
            )
830
        );
831
        $tplContent->assign('skills', $skills);
832
        $tplContent->assign('sessions', $sessionsApproved);
833
        $tplContent->assign('courses', $coursesApproved);
834
        $tplContent->assign('time_spent_in_lps', api_time_to_hms($totalTimeInLearningPaths));
835
        $tplContent->assign('time_spent_in_lps_in_hours', round($totalTimeInLearningPaths / 3600, 1));
836
837
        $layoutContent = $tplContent->get_template('gradebook/custom_certificate.tpl');
838
        $content = $tplContent->fetch($layoutContent);
839
840
        return $content;
841
    }
842
843
    /**
844
     * Ofaj.
845
     */
846
    public function generatePdfFromCustomCertificate()
847
    {
848
        $orientation = api_get_configuration_value('certificate_pdf_orientation');
849
850
        $params['orientation'] = 'landscape';
851
        if (!empty($orientation)) {
852
            $params['orientation'] = $orientation;
853
        }
854
855
        $params['left'] = 0;
856
        $params['right'] = 0;
857
        $params['top'] = 0;
858
        $params['bottom'] = 0;
859
        $page_format = 'landscape' == $params['orientation'] ? 'A4-L' : 'A4';
860
        $pdf = new PDF($page_format, $params['orientation'], $params);
861
862
        $pdf->html_to_pdf(
863
            $this->html_file,
864
            get_lang('Certificates'),
865
            null,
866
            false,
867
            false
868
        );
869
    }
870
871
    /**
872
     * @param int $userId
873
     *
874
     * @return array
875
     */
876
    public static function getCertificateByUser($userId)
877
    {
878
        $userId = (int) $userId;
879
        if (empty($userId)) {
880
            return [];
881
        }
882
883
        $table = Database::get_main_table(TABLE_MAIN_GRADEBOOK_CERTIFICATE);
884
        $sql = "SELECT * FROM $table
885
                WHERE user_id= $userId";
886
        $rs = Database::query($sql);
887
888
        return Database::store_result($rs, 'ASSOC');
889
    }
890
891
    /**
892
     * @param int $userId
893
     */
894
    public static function generateUserSkills($userId)
895
    {
896
        $controller = new IndexManager(get_lang('My courses'));
897
        $courseAndSessions = $controller->returnCoursesAndSessions($userId, true, null, true, false);
898
899
        if (isset($courseAndSessions['courses']) && !empty($courseAndSessions['courses'])) {
900
            foreach ($courseAndSessions['courses'] as $course) {
901
                $cats = Category::load(
902
                    null,
903
                    null,
904
                    $course['code'],
905
                    null,
906
                    null,
907
                    null,
908
                    false
909
                );
910
911
                if (isset($cats[0]) && !empty($cats[0])) {
912
                    Category::generateUserCertificate(
913
                        $cats[0]->get_id(),
914
                        $userId
915
                    );
916
                }
917
            }
918
        }
919
920
        if (isset($courseAndSessions['sessions']) && !empty($courseAndSessions['sessions'])) {
921
            foreach ($courseAndSessions['sessions'] as $sessionCategory) {
922
                if (isset($sessionCategory['sessions'])) {
923
                    foreach ($sessionCategory['sessions'] as $sessionData) {
924
                        if (!empty($sessionData['courses'])) {
925
                            $sessionId = $sessionData['session_id'];
926
                            foreach ($sessionData['courses'] as $courseData) {
927
                                $cats = Category:: load(
928
                                    null,
929
                                    null,
930
                                    $courseData['course_code'],
931
                                    null,
932
                                    null,
933
                                    $sessionId,
934
                                    false
935
                                );
936
937
                                if (isset($cats[0]) && !empty($cats[0])) {
938
                                    Category::generateUserCertificate(
939
                                        $cats[0]->get_id(),
940
                                        $userId
941
                                    );
942
                                }
943
                            }
944
                        }
945
                    }
946
                }
947
            }
948
        }
949
    }
950
}
951