Passed
Push — 1.11.x ( bce6cd...c146d9 )
by Angel Fernando Quiroz
12:25
created

main/inc/lib/plugin.lib.php (1 issue)

1
<?php
2
/* See license terms in /license.txt */
3
4
use ChamiloSession as Session;
5
6
/**
7
 * Class AppPlugin.
8
 */
9
class AppPlugin
10
{
11
    public $plugin_regions = [
12
        'main_top',
13
        'main_bottom',
14
        'login_top',
15
        'login_bottom',
16
        'menu_top',
17
        'menu_bottom',
18
        'content_top',
19
        'content_bottom',
20
        'header_main',
21
        'header_center',
22
        'header_left',
23
        'header_right',
24
        'pre_footer',
25
        'footer_left',
26
        'footer_center',
27
        'footer_right',
28
        'menu_administrator',
29
        'course_tool_plugin',
30
    ];
31
32
    public $installedPluginListName = [];
33
    public $installedPluginListObject = [];
34
    private static $instance;
35
36
    /**
37
     * Constructor.
38
     */
39
    public function __construct()
40
    {
41
    }
42
43
    /**
44
     * @return AppPlugin
45
     */
46
    public static function getInstance()
47
    {
48
        if (!isset(self::$instance)) {
49
            self::$instance = new self();
50
        }
51
52
        return self::$instance;
53
    }
54
55
    /**
56
     * Read plugin from path.
57
     *
58
     * @return array
59
     */
60
    public function read_plugins_from_path()
61
    {
62
        /* We scan the plugin directory. Each folder is a potential plugin. */
63
        $pluginPath = api_get_path(SYS_PLUGIN_PATH);
64
        $plugins = [];
65
        $handle = @opendir($pluginPath);
66
        while (false !== ($file = readdir($handle))) {
67
            if ($file != '.' && $file != '..' && is_dir(api_get_path(SYS_PLUGIN_PATH).$file)) {
68
                $plugins[] = $file;
69
            }
70
        }
71
        @closedir($handle);
72
        sort($plugins);
73
74
        return $plugins;
75
    }
76
77
    /**
78
     * @return array
79
     */
80
    public function getInstalledPluginListName()
81
    {
82
        if (empty($this->installedPluginListName)) {
83
            $this->installedPluginListName = $this->getInstalledPlugins();
84
        }
85
86
        return $this->installedPluginListName;
87
    }
88
89
    /**
90
     * @return array List of Plugin
91
     */
92
    public function getInstalledPluginListObject()
93
    {
94
        if (empty($this->installedPluginListObject)) {
95
            $this->setInstalledPluginListObject();
96
        }
97
98
        return $this->installedPluginListObject;
99
    }
100
101
    public function setInstalledPluginListObject()
102
    {
103
        $pluginListName = $this->getInstalledPluginListName();
104
        $pluginList = [];
105
        if (!empty($pluginListName)) {
106
            foreach ($pluginListName as $pluginName) {
107
                $pluginInfo = $this->getPluginInfo($pluginName, true);
108
                if (isset($pluginInfo['plugin_class'])) {
109
                    $pluginList[] = $pluginInfo['plugin_class']::create();
110
                }
111
            }
112
        }
113
        $this->installedPluginListObject = $pluginList;
114
    }
115
116
    /**
117
     * @param string $plugin
118
     *
119
     * @return bool
120
     */
121
    public function isInstalled($plugin)
122
    {
123
        $list = self::getInstalledPlugins(false);
124
125
        return in_array($plugin, $list);
126
    }
127
128
    /**
129
     * Returns a list of all installed plugins.
130
     *
131
     * @param bool $fromDatabase
132
     *
133
     * @return array
134
     */
135
    public function getInstalledPlugins($fromDatabase = true)
136
    {
137
        static $installedPlugins = null;
138
139
        if ($fromDatabase === false) {
140
            if (is_array($installedPlugins)) {
141
                return $installedPlugins;
142
            }
143
        }
144
145
        if ($fromDatabase || $installedPlugins === null) {
146
            $installedPlugins = [];
147
148
            /*if (api_is_multiple_url_enabled()) {
149
                $urlId = api_get_current_access_url_id();
150
                $plugins = api_get_settings_params(
151
                    [
152
                        'variable = ? AND selected_value = ? AND category = ? AND access_url = ? ' => [
153
                            'status',
154
                            'installed',
155
                            'Plugins',
156
                            $urlId,
157
                        ],
158
                    ]
159
                );
160
            } else {*/
161
            $plugins = api_get_settings_params(
162
                    [
163
                        'variable = ? AND selected_value = ? AND category = ? ' => ['status', 'installed', 'Plugins'],
164
                    ]
165
                );
166
            //}
167
168
            if (!empty($plugins)) {
169
                foreach ($plugins as $row) {
170
                    $installedPlugins[$row['subkey']] = true;
171
                }
172
                $installedPlugins = array_keys($installedPlugins);
173
            }
174
        }
175
176
        return $installedPlugins;
177
    }
178
179
    public function getInstalledPluginsInCurrentUrl()
180
    {
181
        $installedPlugins = [];
182
        $urlId = api_get_current_access_url_id();
183
        $plugins = api_get_settings_params(
184
            [
185
                'variable = ? AND selected_value = ? AND category = ? AND access_url = ?' => ['status', 'installed', 'Plugins', $urlId],
186
            ]
187
        );
188
189
        if (!empty($plugins)) {
190
            foreach ($plugins as $row) {
191
                $installedPlugins[$row['subkey']] = true;
192
            }
193
            $installedPlugins = array_keys($installedPlugins);
194
        }
195
196
        return $installedPlugins;
197
    }
198
199
    /**
200
     * Returns a list of all official (delivered with the Chamilo package)
201
     * plugins. This list is maintained manually and updated with every new
202
     * release to avoid hacking.
203
     *
204
     * @return array
205
     */
206
    public function getOfficialPlugins()
207
    {
208
        static $officialPlugins = null;
209
        // Please keep this list alphabetically sorted
210
        $officialPlugins = [
211
            'add_cas_login_button',
212
            'add_cas_logout_button',
213
            'add_facebook_login_button',
214
            'add_shibboleth_login_button',
215
            'advanced_subscription',
216
            'azure_active_directory',
217
            'bbb',
218
            'before_login',
219
            'buycourses',
220
            'card_game',
221
            'check_extra_field_author_company',
222
            'cleandeletedfiles',
223
            'clockworksms',
224
            'courseblock',
225
            'coursehomenotify',
226
            'courselegal',
227
            'createdrupaluser',
228
            'customcertificate',
229
            'customfooter',
230
            'dashboard',
231
            'date',
232
            'dictionary',
233
            'embedregistry',
234
            'exercise_signature',
235
            'ext_auth_chamilo_logout_button_behaviour',
236
            'follow_buttons',
237
            'formLogin_hide_unhide',
238
            'google_maps',
239
            'google_meet',
240
            'grading_electronic',
241
            'h5p',
242
            'hello_world',
243
            'ims_lti',
244
            'jcapture',
245
            'justification',
246
            'kannelsms',
247
            'keycloak',
248
            'learning_calendar',
249
            'lti_provider',
250
            'maintenancemode',
251
            'migrationmoodle',
252
            'mindmap',
253
            'nosearchindex',
254
            'notebookteacher',
255
            'oauth2',
256
            'olpc_peru_filter',
257
            'onlyoffice',
258
            'openmeetings',
259
            'pausetraining',
260
            'pens',
261
            'positioning',
262
            'questionoptionsevaluation',
263
            'redirection',
264
            'remedial_course',
265
            'reports',
266
            'resubscription',
267
            'rss',
268
            'search_course',
269
            'send_notification_new_lp',
270
            'sepe',
271
            'share_buttons',
272
            'show_regions',
273
            'show_user_info',
274
            'static',
275
            'studentfollowup',
276
            'surveyexportcsv',
277
            'surveyexporttxt',
278
            'test2pdf',
279
            'toplinks',
280
            'tour',
281
            'userremoteservice',
282
            'vchamilo',
283
            'whispeakauth',
284
            'zoom',
285
            'xapi',
286
        ];
287
288
        return $officialPlugins;
289
    }
290
291
    /**
292
     * @param string $pluginName
293
     * @param int    $urlId
294
     */
295
    public function install($pluginName, $urlId = null)
296
    {
297
        $urlId = (int) $urlId;
298
        if (empty($urlId)) {
299
            $urlId = api_get_current_access_url_id();
300
        }
301
302
        api_add_setting(
303
            'installed',
304
            'status',
305
            $pluginName,
306
            'setting',
307
            'Plugins',
308
            $pluginName,
309
            '',
310
            '',
311
            '',
312
            $urlId,
313
            1
314
        );
315
316
        $pluginPath = api_get_path(SYS_PLUGIN_PATH).$pluginName.'/install.php';
317
318
        if (is_file($pluginPath) && is_readable($pluginPath)) {
319
            // Execute the install procedure.
320
321
            require $pluginPath;
322
        }
323
    }
324
325
    /**
326
     * @param string $pluginName
327
     * @param int    $urlId
328
     */
329
    public function uninstall($pluginName, $urlId = null)
330
    {
331
        $urlId = (int) $urlId;
332
        if (empty($urlId)) {
333
            $urlId = api_get_current_access_url_id();
334
        }
335
336
        // First call the custom uninstall to allow full access to global settings
337
        $pluginPath = api_get_path(SYS_PLUGIN_PATH).$pluginName.'/uninstall.php';
338
        if (is_file($pluginPath) && is_readable($pluginPath)) {
339
            // Execute the uninstall procedure.
340
341
            require $pluginPath;
342
        }
343
344
        // Second remove all remaining global settings
345
        api_delete_settings_params(
346
            ['category = ? AND access_url = ? AND subkey = ? ' => ['Plugins', $urlId, $pluginName]]
347
        );
348
    }
349
350
    /**
351
     * @param string $pluginName
352
     *
353
     * @return array
354
     */
355
    public function get_areas_by_plugin($pluginName)
356
    {
357
        $result = api_get_settings('Plugins');
358
        $areas = [];
359
        foreach ($result as $row) {
360
            if ($pluginName == $row['selected_value']) {
361
                $areas[] = $row['variable'];
362
            }
363
        }
364
365
        return $areas;
366
    }
367
368
    /**
369
     * @param string $pluginName
370
     *
371
     * @return bool
372
     */
373
    public function is_valid_plugin($pluginName)
374
    {
375
        if (is_dir(api_get_path(SYS_PLUGIN_PATH).$pluginName)) {
376
            if (is_file(api_get_path(SYS_PLUGIN_PATH).$pluginName.'/index.php')) {
377
                return true;
378
            }
379
        }
380
381
        return false;
382
    }
383
384
    /**
385
     * @return array
386
     */
387
    public function get_plugin_regions()
388
    {
389
        sort($this->plugin_regions);
390
391
        return $this->plugin_regions;
392
    }
393
394
    /**
395
     * @param string   $region
396
     * @param Template $template
397
     * @param bool     $forced
398
     *
399
     * @return string|null
400
     */
401
    public function load_region($region, $template, $forced = false)
402
    {
403
        if ($region == 'course_tool_plugin') {
404
            return '';
405
        }
406
407
        ob_start();
408
        $this->get_all_plugin_contents_by_region($region, $template, $forced);
409
        $content = ob_get_contents();
410
        ob_end_clean();
411
412
        return $content;
413
    }
414
415
    /**
416
     * Loads the translation files inside a plugin if exists.
417
     * It loads by default english see the hello world plugin.
418
     *
419
     * @param string $plugin_name
420
     *
421
     * @todo add caching
422
     */
423
    public function load_plugin_lang_variables($plugin_name)
424
    {
425
        global $language_interface;
426
        $root = api_get_path(SYS_PLUGIN_PATH);
427
        $strings = null;
428
429
        // 1. Loading english if exists
430
        $english_path = $root.$plugin_name."/lang/english.php";
431
432
        if (is_readable($english_path)) {
433
            include $english_path;
434
435
            foreach ($strings as $key => $string) {
436
                $GLOBALS[$key] = $string;
437
            }
438
        }
439
440
        // 2. Loading the system language
441
        if ($language_interface != 'english') {
442
            $path = $root.$plugin_name."/lang/$language_interface.php";
443
444
            if (is_readable($path)) {
445
                include $path;
446
                if (!empty($strings)) {
447
                    foreach ($strings as $key => $string) {
448
                        $GLOBALS[$key] = $string;
449
                    }
450
                }
451
            } else {
452
                $interfaceLanguageId = api_get_language_id($language_interface);
453
                $interfaceLanguageInfo = api_get_language_info($interfaceLanguageId);
454
                $languageParentId = intval($interfaceLanguageInfo['parent_id']);
455
456
                if ($languageParentId > 0) {
457
                    $languageParentInfo = api_get_language_info($languageParentId);
458
                    $languageParentFolder = $languageParentInfo['dokeos_folder'];
459
460
                    $parentPath = "{$root}{$plugin_name}/lang/{$languageParentFolder}.php";
461
                    if (is_readable($parentPath)) {
462
                        include $parentPath;
463
                        if (!empty($strings)) {
464
                            foreach ($strings as $key => $string) {
465
                                $this->strings[$key] = $string;
466
                            }
467
                        }
468
                    }
469
                }
470
            }
471
        }
472
    }
473
474
    /**
475
     * @param string   $region
476
     * @param Template $template
477
     * @param bool     $forced
478
     *
479
     * @return bool
480
     *
481
     * @todo improve this function
482
     */
483
    public function get_all_plugin_contents_by_region($region, $template, $forced = false)
484
    {
485
        global $_plugins;
486
        if (isset($_plugins[$region]) && is_array($_plugins[$region])) {
487
            // Load the plugin information
488
            foreach ($_plugins[$region] as $plugin_name) {
489
                // The plugin_info variable is available inside the plugin index
490
                $plugin_info = $this->getPluginInfo($plugin_name, $forced);
491
492
                // We also know where the plugin is
493
                $plugin_info['current_region'] = $region;
494
495
                // Loading the plugin/XXX/index.php file
496
                $plugin_file = api_get_path(SYS_PLUGIN_PATH)."$plugin_name/index.php";
497
498
                if (file_exists($plugin_file)) {
499
                    //Loading the lang variables of the plugin if exists
500
                    self::load_plugin_lang_variables($plugin_name);
501
502
                    // Printing the plugin index.php file
503
                    require $plugin_file;
504
505
                    // If the variable $_template is set we assign those values to be accessible in Twig
506
                    if (isset($_template)) {
507
                        $_template['plugin_info'] = $plugin_info;
508
                    } else {
509
                        $_template = [];
510
                        $_template['plugin_info'] = $plugin_info;
511
                    }
512
513
                    // Setting the plugin info available in the template if exists.
514
                    $template->assign($plugin_name, $_template);
515
516
                    // Loading the Twig template plugin files if exists
517
                    $template_list = [];
518
                    if (isset($plugin_info) && isset($plugin_info['templates'])) {
519
                        $template_list = $plugin_info['templates'];
520
                    }
521
522
                    if (!empty($template_list)) {
523
                        foreach ($template_list as $plugin_tpl) {
524
                            if (!empty($plugin_tpl)) {
525
                                $template_plugin_file = "$plugin_name/$plugin_tpl"; // for twig
526
                                $template->display($template_plugin_file, false);
527
                            }
528
                        }
529
                    }
530
                }
531
            }
532
        }
533
534
        return true;
535
    }
536
537
    /**
538
     * Loads plugin info.
539
     *
540
     * @staticvar array $plugin_data
541
     *
542
     * @param string $plugin_name
543
     * @param bool   $forced      load from DB or from the static array
544
     *
545
     * @return array
546
     *
547
     * @todo filter setting_form
548
     */
549
    public function getPluginInfo($plugin_name, $forced = false)
550
    {
551
        $pluginData = Session::read('plugin_data');
552
        if (isset($pluginData[$plugin_name]) && $forced == false) {
553
            return $pluginData[$plugin_name];
554
        } else {
555
            $plugin_file = api_get_path(SYS_PLUGIN_PATH)."$plugin_name/plugin.php";
556
557
            $plugin_info = [];
558
            if (file_exists($plugin_file)) {
559
                require $plugin_file;
560
            }
561
562
            // @todo check if settings are already added
563
            // Extra options
564
            $plugin_settings = api_get_settings_params(
565
                [
566
                    "subkey = ? AND category = ? AND type = ? AND access_url = ?" => [
567
                        $plugin_name,
568
                        'Plugins',
569
                        'setting',
570
                        api_get_current_access_url_id(),
571
                    ],
572
                ]
573
            );
574
575
            $settings_filtered = [];
576
            foreach ($plugin_settings as $item) {
577
                if (!empty($item['selected_value'])) {
578
                    $unserialized = UnserializeApi::unserialize('not_allowed_classes', $item['selected_value'], true);
579
                    if (false !== $unserialized) {
580
                        $item['selected_value'] = $unserialized;
581
                    }
582
                }
583
                $settings_filtered[$item['variable']] = $item['selected_value'];
584
            }
585
            $plugin_info['settings'] = $settings_filtered;
586
            $pluginData[$plugin_name] = $plugin_info;
587
            Session::write('plugin_data', $pluginData);
588
589
            return $plugin_info;
590
        }
591
    }
592
593
    /**
594
     * Get the template list.
595
     *
596
     * @param string $pluginName
597
     *
598
     * @return bool
599
     */
600
    public function get_templates_list($pluginName)
601
    {
602
        $plugin_info = $this->getPluginInfo($pluginName);
603
        if (isset($plugin_info) && isset($plugin_info['templates'])) {
604
            return $plugin_info['templates'];
605
        }
606
607
        return false;
608
    }
609
610
    /**
611
     * Remove all regions of an specific plugin.
612
     *
613
     * @param string $plugin
614
     */
615
    public function remove_all_regions($plugin)
616
    {
617
        $access_url_id = api_get_current_access_url_id();
618
        if (!empty($plugin)) {
619
            api_delete_settings_params(
620
                [
621
                    'category = ? AND type = ? AND access_url = ? AND subkey = ? ' => [
622
                        'Plugins',
623
                        'region',
624
                        $access_url_id,
625
                        $plugin,
626
                    ],
627
                ]
628
            );
629
        }
630
    }
631
632
    /**
633
     * Add a plugin to a region.
634
     *
635
     * @param string $plugin
636
     * @param string $region
637
     */
638
    public function add_to_region($plugin, $region)
639
    {
640
        api_add_setting(
641
            $plugin,
642
            $region,
643
            $plugin,
644
            'region',
645
            'Plugins',
646
            $plugin,
647
            '',
648
            '',
649
            '',
650
            api_get_current_access_url_id(),
651
            1
652
        );
653
    }
654
655
    /**
656
     * @param int $courseId
657
     */
658
    public function install_course_plugins($courseId)
659
    {
660
        $pluginList = $this->getInstalledPluginListObject();
661
662
        if (!empty($pluginList)) {
663
            /** @var Plugin $obj */
664
            foreach ($pluginList as $obj) {
665
                $pluginName = $obj->get_name();
666
                $plugin_path = api_get_path(SYS_PLUGIN_PATH).$pluginName.'/plugin.php';
667
668
                if (file_exists($plugin_path)) {
669
                    require $plugin_path;
670
                    if (isset($plugin_info) && isset($plugin_info['plugin_class']) && $obj->isCoursePlugin) {
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $plugin_info does not exist. Did you maybe mean $plugin_path?
Loading history...
671
                        $obj->course_install($courseId);
672
                    }
673
                }
674
            }
675
        }
676
    }
677
678
    /**
679
     * Trigger for Plugin::doWhenDeleting[Item] functions.
680
     *
681
     * @param string $itemType
682
     * @param int    $itemId
683
     */
684
    public function performActionsWhenDeletingItem($itemType, $itemId)
685
    {
686
        $pluginList = $this->getInstalledPluginListObject();
687
688
        if (empty($pluginList)) {
689
            return;
690
        }
691
692
        /** @var Plugin $pluginObj */
693
        foreach ($pluginList as $pluginObj) {
694
            switch ($itemType) {
695
                case 'course':
696
                    $pluginObj->doWhenDeletingCourse($itemId);
697
                    break;
698
                case 'session':
699
                    $pluginObj->doWhenDeletingSession($itemId);
700
                    break;
701
                case 'user':
702
                    $pluginObj->doWhenDeletingUser($itemId);
703
                    break;
704
            }
705
        }
706
    }
707
708
    /**
709
     * Add the course settings to the course settings form.
710
     *
711
     * @param FormValidator $form
712
     */
713
    public function add_course_settings_form($form)
714
    {
715
        $pluginList = $this->getInstalledPluginListObject();
716
        /** @var Plugin $obj */
717
        foreach ($pluginList as $obj) {
718
            $plugin_name = $obj->get_name();
719
            $pluginTitle = $obj->get_title();
720
            if (!empty($obj->course_settings)) {
721
                if (is_file(api_get_path(SYS_CODE_PATH).'img/icons/'.ICON_SIZE_SMALL.'/'.$plugin_name.'.png')) {
722
                    $icon = Display::return_icon(
723
                        $plugin_name.'.png',
724
                        Security::remove_XSS($pluginTitle),
725
                        '',
726
                        ICON_SIZE_SMALL
727
                    );
728
                } else {
729
                    $icon = Display::return_icon(
730
                        'plugins.png',
731
                        Security::remove_XSS($pluginTitle),
732
                        '',
733
                        ICON_SIZE_SMALL
734
                    );
735
                }
736
737
                $form->addHtml('<div class="panel panel-default">');
738
                $form->addHtml('
739
                    <div class="panel-heading" role="tab" id="heading-'.$plugin_name.'-settings">
740
                        <h4 class="panel-title">
741
                            <a class="collapsed"
742
                                role="button" data-toggle="collapse" data-parent="#accordion"
743
                                href="#collapse-'.$plugin_name.'-settings" aria-expanded="false"
744
                                aria-controls="collapse-'.$plugin_name.'-settings">
745
                ');
746
                $form->addHtml($icon.' '.$pluginTitle);
747
                $form->addHtml('
748
                            </a>
749
                        </h4>
750
                    </div>
751
                ');
752
                $form->addHtml('
753
                    <div
754
                        id="collapse-'.$plugin_name.'-settings"
755
                        class="panel-collapse collapse" role="tabpanel"
756
                        aria-labelledby="heading-'.$plugin_name.'-settings">
757
                        <div class="panel-body">
758
                ');
759
760
                $groups = [];
761
                foreach ($obj->course_settings as $setting) {
762
                    if ($obj->validateCourseSetting($setting['name']) === false) {
763
                        continue;
764
                    }
765
                    if ($setting['type'] !== 'checkbox') {
766
                        $form->addElement($setting['type'], $setting['name'], $obj->get_lang($setting['name']));
767
                    } else {
768
                        $element = &$form->createElement(
769
                            $setting['type'],
770
                            $setting['name'],
771
                            '',
772
                            $obj->get_lang($setting['name'])
773
                        );
774
775
                        // Check global settings
776
                        $courseSetting = api_get_course_setting($setting['name']);
777
                        if (-1 === $courseSetting) {
778
                            $defaultValue = api_get_plugin_setting($plugin_name, $setting['name']);
779
                            if (!empty($defaultValue)) {
780
                                if ('true' === $defaultValue) {
781
                                    $element->setChecked(true);
782
                                }
783
                            }
784
                        }
785
786
                        if (isset($setting['init_value']) && $setting['init_value'] == 1) {
787
                            $element->setChecked(true);
788
                        }
789
790
                        $form->addElement($element);
791
                        if (isset($setting['group'])) {
792
                            $groups[$setting['group']][] = $element;
793
                        }
794
                    }
795
                }
796
                foreach ($groups as $k => $v) {
797
                    $form->addGroup($groups[$k], $k, [$obj->get_lang($k)]);
798
                }
799
                $form->addButtonSave(get_lang('SaveSettings'));
800
                $form->addHtml('
801
                        </div>
802
                    </div>
803
                ');
804
                $form->addHtml('</div>');
805
            }
806
        }
807
    }
808
809
    /**
810
     * Get all course settings from all installed plugins.
811
     *
812
     * @return array
813
     */
814
    public function getAllPluginCourseSettings()
815
    {
816
        $pluginList = $this->getInstalledPluginListObject();
817
        /** @var Plugin $obj */
818
        $courseSettings = [];
819
        if (!empty($pluginList)) {
820
            foreach ($pluginList as $obj) {
821
                $pluginCourseSetting = $obj->getCourseSettings();
822
                $courseSettings = array_merge($courseSettings, $pluginCourseSetting);
823
            }
824
        }
825
826
        return $courseSettings;
827
    }
828
829
    /**
830
     * When saving the plugin values in the course settings, check whether
831
     * a callback method should be called and send it the updated settings.
832
     *
833
     * @param array $values The new settings the user just saved
834
     */
835
    public function saveCourseSettingsHook($values)
836
    {
837
        $pluginList = $this->getInstalledPluginListObject();
838
839
        /** @var Plugin $obj */
840
        foreach ($pluginList as $obj) {
841
            $settings = $obj->getCourseSettings();
842
            $subValues = [];
843
            if (!empty($settings)) {
844
                foreach ($settings as $v) {
845
                    if (isset($values[$v])) {
846
                        $subValues[$v] = $values[$v];
847
                    }
848
                }
849
            }
850
851
            if (!empty($subValues)) {
852
                $obj->course_settings_updated($subValues);
853
            }
854
        }
855
    }
856
857
    /**
858
     * Get first SMS plugin name.
859
     *
860
     * @return string|bool
861
     */
862
    public function getSMSPluginName()
863
    {
864
        $installedPluginsList = $this->getInstalledPluginListObject();
865
        foreach ($installedPluginsList as $installedPlugin) {
866
            if ($installedPlugin->isMailPlugin) {
867
                return get_class($installedPlugin);
868
            }
869
        }
870
871
        return false;
872
    }
873
874
    /**
875
     * @return SmsPluginLibraryInterface
876
     */
877
    public function getSMSPluginLibrary()
878
    {
879
        $className = $this->getSMSPluginName();
880
        $className = str_replace('Plugin', '', $className);
881
882
        if (class_exists($className)) {
883
            return new $className();
884
        }
885
886
        return false;
887
    }
888
}
889