Passed
Push — ofaj ( 0f9380...ade756 )
by
unknown
12:01 queued 12s
created

AppPlugin::getOfficialPlugins()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 81
Code Lines 76

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 76
nc 1
nop 0
dl 0
loc 81
rs 8.5236
c 0
b 0
f 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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);
0 ignored issues
show
Bug introduced by
Are you sure the usage of closedir($handle) is correct as it seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
Security Best Practice introduced by
It seems like you do not handle an error condition for closedir(). This can introduce security issues, and is generally not recommended. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unhandled  annotation

71
        /** @scrutinizer ignore-unhandled */ @closedir($handle);

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
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);
0 ignored issues
show
Bug Best Practice introduced by
The method AppPlugin::getInstalledPlugins() is not static, but was called statically. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

123
        /** @scrutinizer ignore-call */ 
124
        $list = self::getInstalledPlugins(false);
Loading history...
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
            $plugins = api_get_settings_params(
148
                [
149
                    'variable = ? AND selected_value = ? AND category = ? ' => ['status', 'installed', 'Plugins'],
150
                ]
151
            );
152
153
            if (!empty($plugins)) {
154
                foreach ($plugins as $row) {
155
                    $installedPlugins[$row['subkey']] = true;
156
                }
157
                $installedPlugins = array_keys($installedPlugins);
158
            }
159
        }
160
161
        return $installedPlugins;
162
    }
163
164
    public function getInstalledPluginsInCurrentUrl()
165
    {
166
        $installedPlugins = [];
167
        $urlId = api_get_current_access_url_id();
168
        $plugins = api_get_settings_params(
169
            [
170
                'variable = ? AND selected_value = ? AND category = ? AND access_url = ?' => ['status', 'installed', 'Plugins', $urlId],
171
            ]
172
        );
173
174
        if (!empty($plugins)) {
175
            foreach ($plugins as $row) {
176
                $installedPlugins[$row['subkey']] = true;
177
            }
178
            $installedPlugins = array_keys($installedPlugins);
179
        }
180
181
        return $installedPlugins;
182
    }
183
184
    /**
185
     * Returns a list of all official (delivered with the Chamilo package)
186
     * plugins. This list is maintained manually and updated with every new
187
     * release to avoid hacking.
188
     *
189
     * @return array
190
     */
191
    public function getOfficialPlugins()
192
    {
193
        static $officialPlugins = null;
194
        // Please keep this list alphabetically sorted
195
        $officialPlugins = [
196
            'add_cas_login_button',
197
            'add_cas_logout_button',
198
            'add_facebook_login_button',
199
            'add_shibboleth_login_button',
200
            'advanced_subscription',
201
            'azure_active_directory',
202
            'bbb',
203
            'before_login',
204
            'buycourses',
205
            'card_game',
206
            'check_extra_field_author_company',
207
            'cleandeletedfiles',
208
            'clockworksms',
209
            'courseblock',
210
            'coursehomenotify',
211
            'courselegal',
212
            'createdrupaluser',
213
            'customcertificate',
214
            'customfooter',
215
            'dashboard',
216
            'date',
217
            'dictionary',
218
            'embedregistry',
219
            'exercise_signature',
220
            'ext_auth_chamilo_logout_button_behaviour',
221
            'follow_buttons',
222
            'formLogin_hide_unhide',
223
            'google_maps',
224
            'google_meet',
225
            'grading_electronic',
226
            'h5p',
227
            'hello_world',
228
            'ims_lti',
229
            'jcapture',
230
            'justification',
231
            'kannelsms',
232
            'keycloak',
233
            'learning_calendar',
234
            'maintenancemode',
235
            'migrationmoodle',
236
            'mindmap',
237
            'nosearchindex',
238
            'notebookteacher',
239
            'oauth2',
240
            'olpc_peru_filter',
241
            'openmeetings',
242
            'pausetraining',
243
            'pens',
244
            'positioning',
245
            'questionoptionsevaluation',
246
            'redirection',
247
            'remedial_course',
248
            'reports',
249
            'resubscription',
250
            'rss',
251
            'search_course',
252
            'send_notification_new_lp',
253
            'sepe',
254
            'share_buttons',
255
            'show_regions',
256
            'show_user_info',
257
            'static',
258
            'studentfollowup',
259
            'surveyexportcsv',
260
            'surveyexporttxt',
261
            'test2pdf',
262
            'toplinks',
263
            'tour',
264
            'userremoteservice',
265
            'vchamilo',
266
            'whispeakauth',
267
            'zoom',
268
            'xapi',
269
        ];
270
271
        return $officialPlugins;
272
    }
273
    /**
274
     * @param string $pluginName
275
     * @param int    $urlId
276
     */
277
    public function install($pluginName, $urlId = null)
278
    {
279
        $urlId = (int) $urlId;
280
        if (empty($urlId)) {
281
            $urlId = api_get_current_access_url_id();
282
        }
283
284
        api_add_setting(
285
            'installed',
286
            'status',
287
            $pluginName,
288
            'setting',
289
            'Plugins',
290
            $pluginName,
291
            '',
292
            '',
293
            '',
294
            $urlId,
295
            1
296
        );
297
298
        $pluginPath = api_get_path(SYS_PLUGIN_PATH).$pluginName.'/install.php';
299
300
        if (is_file($pluginPath) && is_readable($pluginPath)) {
301
            // Execute the install procedure.
302
303
            require $pluginPath;
304
        }
305
    }
306
307
    /**
308
     * @param string $pluginName
309
     * @param int    $urlId
310
     */
311
    public function uninstall($pluginName, $urlId = null)
312
    {
313
        $urlId = (int) $urlId;
314
        if (empty($urlId)) {
315
            $urlId = api_get_current_access_url_id();
316
        }
317
318
        // First call the custom uninstall to allow full access to global settings
319
        $pluginPath = api_get_path(SYS_PLUGIN_PATH).$pluginName.'/uninstall.php';
320
        if (is_file($pluginPath) && is_readable($pluginPath)) {
321
            // Execute the uninstall procedure.
322
323
            require $pluginPath;
324
        }
325
326
        // Second remove all remaining global settings
327
        api_delete_settings_params(
328
            ['category = ? AND access_url = ? AND subkey = ? ' => ['Plugins', $urlId, $pluginName]]
329
        );
330
    }
331
332
    /**
333
     * @param string $pluginName
334
     *
335
     * @return array
336
     */
337
    public function get_areas_by_plugin($pluginName)
338
    {
339
        $result = api_get_settings('Plugins');
340
        $areas = [];
341
        foreach ($result as $row) {
342
            if ($pluginName == $row['selected_value']) {
343
                $areas[] = $row['variable'];
344
            }
345
        }
346
347
        return $areas;
348
    }
349
350
    /**
351
     * @param string $pluginName
352
     *
353
     * @return bool
354
     */
355
    public function is_valid_plugin($pluginName)
356
    {
357
        if (is_dir(api_get_path(SYS_PLUGIN_PATH).$pluginName)) {
358
            if (is_file(api_get_path(SYS_PLUGIN_PATH).$pluginName.'/index.php')) {
359
                return true;
360
            }
361
        }
362
363
        return false;
364
    }
365
366
    /**
367
     * @return array
368
     */
369
    public function get_plugin_regions()
370
    {
371
        sort($this->plugin_regions);
372
373
        return $this->plugin_regions;
374
    }
375
376
    /**
377
     * @param string   $region
378
     * @param Template $template
379
     * @param bool     $forced
380
     *
381
     * @return string|null
382
     */
383
    public function load_region($region, $template, $forced = false)
384
    {
385
        if ($region == 'course_tool_plugin') {
386
            return '';
387
        }
388
389
        ob_start();
390
        $this->get_all_plugin_contents_by_region($region, $template, $forced);
391
        $content = ob_get_contents();
392
        ob_end_clean();
393
394
        return $content;
395
    }
396
397
    /**
398
     * Loads the translation files inside a plugin if exists.
399
     * It loads by default english see the hello world plugin.
400
     *
401
     * @param string $plugin_name
402
     *
403
     * @todo add caching
404
     */
405
    public function load_plugin_lang_variables($plugin_name)
406
    {
407
        global $language_interface;
408
        $root = api_get_path(SYS_PLUGIN_PATH);
409
        $strings = null;
410
411
        // 1. Loading english if exists
412
        $english_path = $root.$plugin_name."/lang/english.php";
413
414
        if (is_readable($english_path)) {
415
            include $english_path;
416
417
            foreach ($strings as $key => $string) {
0 ignored issues
show
Bug introduced by
The expression $strings of type null is not traversable.
Loading history...
418
                $GLOBALS[$key] = $string;
419
            }
420
        }
421
422
        // 2. Loading the system language
423
        if ($language_interface != 'english') {
424
            $path = $root.$plugin_name."/lang/$language_interface.php";
425
426
            if (is_readable($path)) {
427
                include $path;
428
                if (!empty($strings)) {
429
                    foreach ($strings as $key => $string) {
430
                        $GLOBALS[$key] = $string;
431
                    }
432
                }
433
            } else {
434
                $interfaceLanguageId = api_get_language_id($language_interface);
435
                $interfaceLanguageInfo = api_get_language_info($interfaceLanguageId);
436
                $languageParentId = intval($interfaceLanguageInfo['parent_id']);
437
438
                if ($languageParentId > 0) {
439
                    $languageParentInfo = api_get_language_info($languageParentId);
440
                    $languageParentFolder = $languageParentInfo['dokeos_folder'];
441
442
                    $parentPath = "{$root}{$plugin_name}/lang/{$languageParentFolder}.php";
443
                    if (is_readable($parentPath)) {
444
                        include $parentPath;
445
                        if (!empty($strings)) {
446
                            foreach ($strings as $key => $string) {
447
                                $this->strings[$key] = $string;
448
                            }
449
                        }
450
                    }
451
                }
452
            }
453
        }
454
    }
455
456
    /**
457
     * @param string   $region
458
     * @param Template $template
459
     * @param bool     $forced
460
     *
461
     * @return bool
462
     *
463
     * @todo improve this function
464
     */
465
    public function get_all_plugin_contents_by_region($region, $template, $forced = false)
466
    {
467
        global $_plugins;
468
        if (isset($_plugins[$region]) && is_array($_plugins[$region])) {
469
            // Load the plugin information
470
            foreach ($_plugins[$region] as $plugin_name) {
471
                // The plugin_info variable is available inside the plugin index
472
                $plugin_info = $this->getPluginInfo($plugin_name, $forced);
473
474
                // We also know where the plugin is
475
                $plugin_info['current_region'] = $region;
476
477
                // Loading the plugin/XXX/index.php file
478
                $plugin_file = api_get_path(SYS_PLUGIN_PATH)."$plugin_name/index.php";
479
480
                if (file_exists($plugin_file)) {
481
                    //Loading the lang variables of the plugin if exists
482
                    self::load_plugin_lang_variables($plugin_name);
0 ignored issues
show
Bug Best Practice introduced by
The method AppPlugin::load_plugin_lang_variables() is not static, but was called statically. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

482
                    self::/** @scrutinizer ignore-call */ 
483
                          load_plugin_lang_variables($plugin_name);
Loading history...
483
484
                    // Printing the plugin index.php file
485
                    require $plugin_file;
486
487
                    // If the variable $_template is set we assign those values to be accessible in Twig
488
                    if (isset($_template)) {
489
                        $_template['plugin_info'] = $plugin_info;
490
                    } else {
491
                        $_template = [];
492
                        $_template['plugin_info'] = $plugin_info;
493
                    }
494
495
                    // Setting the plugin info available in the template if exists.
496
                    $template->assign($plugin_name, $_template);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $_template does not seem to be defined for all execution paths leading up to this point.
Loading history...
497
498
                    // Loading the Twig template plugin files if exists
499
                    $template_list = [];
500
                    if (isset($plugin_info) && isset($plugin_info['templates'])) {
501
                        $template_list = $plugin_info['templates'];
502
                    }
503
504
                    if (!empty($template_list)) {
505
                        foreach ($template_list as $plugin_tpl) {
506
                            if (!empty($plugin_tpl)) {
507
                                $template_plugin_file = "$plugin_name/$plugin_tpl"; // for twig
508
                                $template->display($template_plugin_file, false);
509
                            }
510
                        }
511
                    }
512
                }
513
            }
514
        }
515
516
        return true;
517
    }
518
519
    /**
520
     * Loads plugin info.
521
     *
522
     * @staticvar array $plugin_data
523
     *
524
     * @param string $plugin_name
525
     * @param bool   $forced      load from DB or from the static array
526
     *
527
     * @return array
528
     *
529
     * @todo filter setting_form
530
     */
531
    public function getPluginInfo($plugin_name, $forced = false)
532
    {
533
        $pluginData = Session::read('plugin_data');
534
        if (isset($pluginData[$plugin_name]) && $forced == false) {
0 ignored issues
show
Coding Style Best Practice introduced by
It seems like you are loosely comparing two booleans. Considering using the strict comparison === instead.

When comparing two booleans, it is generally considered safer to use the strict comparison operator.

Loading history...
535
            return $pluginData[$plugin_name];
536
        } else {
537
            $plugin_file = api_get_path(SYS_PLUGIN_PATH)."$plugin_name/plugin.php";
538
539
            $plugin_info = [];
540
            if (file_exists($plugin_file)) {
541
                require $plugin_file;
542
            }
543
544
            // @todo check if settings are already added
545
            // Extra options
546
            $plugin_settings = api_get_settings_params(
547
                [
548
                    "subkey = ? AND category = ? AND type = ? AND access_url = ?" => [
549
                        $plugin_name,
550
                        'Plugins',
551
                        'setting',
552
                        api_get_current_access_url_id(),
553
                    ],
554
                ]
555
            );
556
557
            $settings_filtered = [];
558
            foreach ($plugin_settings as $item) {
559
                if (!empty($item['selected_value'])) {
560
                    $unserialized = UnserializeApi::unserialize('not_allowed_classes', $item['selected_value'], true);
561
                    if (false !== $unserialized) {
562
                        $item['selected_value'] = $unserialized;
563
                    }
564
                }
565
                $settings_filtered[$item['variable']] = $item['selected_value'];
566
            }
567
            $plugin_info['settings'] = $settings_filtered;
568
            $pluginData[$plugin_name] = $plugin_info;
569
            Session::write('plugin_data', $pluginData);
570
571
            return $plugin_info;
572
        }
573
    }
574
575
    /**
576
     * Get the template list.
577
     *
578
     * @param string $pluginName
579
     *
580
     * @return bool
581
     */
582
    public function get_templates_list($pluginName)
583
    {
584
        $plugin_info = $this->getPluginInfo($pluginName);
585
        if (isset($plugin_info) && isset($plugin_info['templates'])) {
586
            return $plugin_info['templates'];
587
        }
588
589
        return false;
590
    }
591
592
    /**
593
     * Remove all regions of an specific plugin.
594
     *
595
     * @param string $plugin
596
     */
597
    public function remove_all_regions($plugin)
598
    {
599
        $access_url_id = api_get_current_access_url_id();
600
        if (!empty($plugin)) {
601
            api_delete_settings_params(
602
                [
603
                    'category = ? AND type = ? AND access_url = ? AND subkey = ? ' => [
604
                        'Plugins',
605
                        'region',
606
                        $access_url_id,
607
                        $plugin,
608
                    ],
609
                ]
610
            );
611
        }
612
    }
613
614
    /**
615
     * Add a plugin to a region.
616
     *
617
     * @param string $plugin
618
     * @param string $region
619
     */
620
    public function add_to_region($plugin, $region)
621
    {
622
        api_add_setting(
623
            $plugin,
624
            $region,
625
            $plugin,
626
            'region',
627
            'Plugins',
628
            $plugin,
629
            '',
630
            '',
631
            '',
632
            api_get_current_access_url_id(),
633
            1
634
        );
635
    }
636
637
    /**
638
     * @param int $courseId
639
     */
640
    public function install_course_plugins($courseId)
641
    {
642
        $pluginList = $this->getInstalledPluginListObject();
643
644
        if (!empty($pluginList)) {
645
            /** @var Plugin $obj */
646
            foreach ($pluginList as $obj) {
647
                $pluginName = $obj->get_name();
648
                $plugin_path = api_get_path(SYS_PLUGIN_PATH).$pluginName.'/plugin.php';
649
650
                if (file_exists($plugin_path)) {
651
                    require $plugin_path;
652
                    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...
653
                        $obj->course_install($courseId);
654
                    }
655
                }
656
            }
657
        }
658
    }
659
660
    /**
661
     * Trigger for Plugin::doWhenDeleting[Item] functions.
662
     *
663
     * @param string $itemType
664
     * @param int    $itemId
665
     */
666
    public function performActionsWhenDeletingItem($itemType, $itemId)
667
    {
668
        $pluginList = $this->getInstalledPluginListObject();
669
670
        if (empty($pluginList)) {
671
            return;
672
        }
673
674
        /** @var Plugin $pluginObj */
675
        foreach ($pluginList as $pluginObj) {
676
            switch ($itemType) {
677
                case 'course':
678
                    $pluginObj->doWhenDeletingCourse($itemId);
679
                    break;
680
                case 'session':
681
                    $pluginObj->doWhenDeletingSession($itemId);
682
                    break;
683
                case 'user':
684
                    $pluginObj->doWhenDeletingUser($itemId);
685
                    break;
686
            }
687
        }
688
    }
689
690
    /**
691
     * Add the course settings to the course settings form.
692
     *
693
     * @param FormValidator $form
694
     */
695
    public function add_course_settings_form($form)
696
    {
697
        $pluginList = $this->getInstalledPluginListObject();
698
        /** @var Plugin $obj */
699
        foreach ($pluginList as $obj) {
700
            $plugin_name = $obj->get_name();
701
            $pluginTitle = $obj->get_title();
702
            if (!empty($obj->course_settings)) {
703
                if (is_file(api_get_path(SYS_CODE_PATH).'img/icons/'.ICON_SIZE_SMALL.'/'.$plugin_name.'.png')) {
704
                    $icon = Display::return_icon(
705
                        $plugin_name.'.png',
706
                        Security::remove_XSS($pluginTitle),
707
                        '',
708
                        ICON_SIZE_SMALL
709
                    );
710
                } else {
711
                    $icon = Display::return_icon(
712
                        'plugins.png',
713
                        Security::remove_XSS($pluginTitle),
714
                        '',
715
                        ICON_SIZE_SMALL
716
                    );
717
                }
718
719
                $form->addHtml('<div class="panel panel-default">');
720
                $form->addHtml('
721
                    <div class="panel-heading" role="tab" id="heading-'.$plugin_name.'-settings">
722
                        <h4 class="panel-title">
723
                            <a class="collapsed" role="button" data-toggle="collapse" data-parent="#accordion" href="#collapse-'.$plugin_name.'-settings" aria-expanded="false" aria-controls="collapse-'.$plugin_name.'-settings">
724
                ');
725
                $form->addHtml($icon.' '.$pluginTitle);
726
                $form->addHtml('
727
                            </a>
728
                        </h4>
729
                    </div>
730
                ');
731
                $form->addHtml('
732
                    <div id="collapse-'.$plugin_name.'-settings" class="panel-collapse collapse" role="tabpanel" aria-labelledby="heading-'.$plugin_name.'-settings">
733
                        <div class="panel-body">
734
                ');
735
736
                $groups = [];
737
                foreach ($obj->course_settings as $setting) {
738
                    if ($obj->validateCourseSetting($setting['name']) === false) {
739
                        continue;
740
                    }
741
                    if ($setting['type'] != 'checkbox') {
742
                        $form->addElement($setting['type'], $setting['name'], $obj->get_lang($setting['name']));
743
                    } else {
744
                        $element = &$form->createElement(
745
                            $setting['type'],
746
                            $setting['name'],
747
                            '',
748
                            $obj->get_lang($setting['name'])
749
                        );
750
                        if (isset($setting['init_value']) && $setting['init_value'] == 1) {
751
                            $element->setChecked(true);
752
                        }
753
                        $form->addElement($element);
754
755
                        if (isset($setting['group'])) {
756
                            $groups[$setting['group']][] = $element;
757
                        }
758
                    }
759
                }
760
                foreach ($groups as $k => $v) {
761
                    $form->addGroup($groups[$k], $k, [$obj->get_lang($k)]);
762
                }
763
                $form->addButtonSave(get_lang('SaveSettings'));
764
                $form->addHtml('
765
                        </div>
766
                    </div>
767
                ');
768
                $form->addHtml('</div>');
769
            }
770
        }
771
    }
772
773
    /**
774
     * Get all course settings from all installed plugins.
775
     *
776
     * @return array
777
     */
778
    public function getAllPluginCourseSettings()
779
    {
780
        $pluginList = $this->getInstalledPluginListObject();
781
        /** @var Plugin $obj */
782
        $courseSettings = [];
783
        if (!empty($pluginList)) {
784
            foreach ($pluginList as $obj) {
785
                $pluginCourseSetting = $obj->getCourseSettings();
786
                $courseSettings = array_merge($courseSettings, $pluginCourseSetting);
787
            }
788
        }
789
790
        return $courseSettings;
791
    }
792
793
    /**
794
     * When saving the plugin values in the course settings, check whether
795
     * a callback method should be called and send it the updated settings.
796
     *
797
     * @param array $values The new settings the user just saved
798
     */
799
    public function saveCourseSettingsHook($values)
800
    {
801
        $pluginList = $this->getInstalledPluginListObject();
802
803
        /** @var Plugin $obj */
804
        foreach ($pluginList as $obj) {
805
            $settings = $obj->getCourseSettings();
806
            $subValues = [];
807
            if (!empty($settings)) {
808
                foreach ($settings as $v) {
809
                    if (isset($values[$v])) {
810
                        $subValues[$v] = $values[$v];
811
                    }
812
                }
813
            }
814
815
            if (!empty($subValues)) {
816
                $obj->course_settings_updated($subValues);
817
            }
818
        }
819
    }
820
821
    /**
822
     * Get first SMS plugin name.
823
     *
824
     * @return string|bool
825
     */
826
    public function getSMSPluginName()
827
    {
828
        $installedPluginsList = $this->getInstalledPluginListObject();
829
        foreach ($installedPluginsList as $installedPlugin) {
830
            if ($installedPlugin->isMailPlugin) {
831
                return get_class($installedPlugin);
832
            }
833
        }
834
835
        return false;
836
    }
837
838
    /**
839
     * @return SmsPluginLibraryInterface
840
     */
841
    public function getSMSPluginLibrary()
842
    {
843
        $className = $this->getSMSPluginName();
844
        $className = str_replace('Plugin', '', $className);
845
846
        if (class_exists($className)) {
847
            return new $className();
848
        }
849
850
        return false;
851
    }
852
}
853