Passed
Push — 1.11.x ( 319ffb...2a5a23 )
by Julito
09:48
created

AppPlugin::getInstalledPluginListName()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 3
nc 2
nop 0
dl 0
loc 7
rs 10
c 0
b 0
f 0
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))) {
0 ignored issues
show
Bug introduced by
It seems like $handle can also be of type false; however, parameter $dir_handle of readdir() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

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

66
        while (false !== ($file = readdir(/** @scrutinizer ignore-type */ $handle))) {
Loading history...
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...
Bug introduced by
It seems like $handle can also be of type false; however, parameter $dir_handle of closedir() does only seem to accept resource, maybe add an additional type check? ( Ignorable by Annotation )

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

71
        @closedir(/** @scrutinizer ignore-type */ $handle);
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
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
            'clockworksms',
222
            'courseblock',
223
            'coursehomenotify',
224
            'courselegal',
225
            'createdrupaluser',
226
            'customcertificate',
227
            'customfooter',
228
            'dashboard',
229
            'date',
230
            'dictionary',
231
            'embedregistry',
232
            'ext_auth_chamilo_logout_button_behaviour',
233
            'follow_buttons',
234
            'formLogin_hide_unhide',
235
            'google_maps',
236
            'grading_electronic',
237
            'hello_world',
238
            'ims_lti',
239
            'jcapture',
240
            'justification',
241
            'kannelsms',
242
            'keycloak',
243
            'learning_calendar',
244
            'maintenancemode',
245
            'migrationmoodle',
246
            'nosearchindex',
247
            'notebookteacher',
248
            'olpc_peru_filter',
249
            'openmeetings',
250
            'pens',
251
            'questionoptionsevaluation',
252
            'redirection',
253
            'reports',
254
            'resubscription',
255
            'rss',
256
            'search_course',
257
            'sepe',
258
            'share_buttons',
259
            'show_regions',
260
            'show_user_info',
261
            'static',
262
            'studentfollowup',
263
            'surveyexportcsv',
264
            'surveyexporttxt',
265
            'test2pdf',
266
            'tour',
267
            'vchamilo',
268
            'whispeakauth',
269
        ];
270
271
        return $officialPlugins;
272
    }
273
274
    /**
275
     * @param string $pluginName
276
     * @param int    $urlId
277
     */
278
    public function install($pluginName, $urlId = null)
279
    {
280
        $urlId = (int) $urlId;
281
        if (empty($urlId)) {
282
            $urlId = api_get_current_access_url_id();
283
        }
284
285
        api_add_setting(
286
            'installed',
287
            'status',
288
            $pluginName,
289
            'setting',
290
            'Plugins',
291
            $pluginName,
292
            '',
293
            '',
294
            '',
295
            $urlId,
296
            1
297
        );
298
299
        $pluginPath = api_get_path(SYS_PLUGIN_PATH).$pluginName.'/install.php';
300
301
        if (is_file($pluginPath) && is_readable($pluginPath)) {
302
            // Execute the install procedure.
303
304
            require $pluginPath;
305
        }
306
    }
307
308
    /**
309
     * @param string $pluginName
310
     * @param int    $urlId
311
     */
312
    public function uninstall($pluginName, $urlId = null)
313
    {
314
        $urlId = (int) $urlId;
315
        if (empty($urlId)) {
316
            $urlId = api_get_current_access_url_id();
317
        }
318
319
        // First call the custom uninstall to allow full access to global settings
320
        $pluginPath = api_get_path(SYS_PLUGIN_PATH).$pluginName.'/uninstall.php';
321
        if (is_file($pluginPath) && is_readable($pluginPath)) {
322
            // Execute the uninstall procedure.
323
324
            require $pluginPath;
325
        }
326
327
        // Second remove all remaining global settings
328
        api_delete_settings_params(
329
            ['category = ? AND access_url = ? AND subkey = ? ' => ['Plugins', $urlId, $pluginName]]
330
        );
331
    }
332
333
    /**
334
     * @param string $pluginName
335
     *
336
     * @return array
337
     */
338
    public function get_areas_by_plugin($pluginName)
339
    {
340
        $result = api_get_settings('Plugins');
341
        $areas = [];
342
        foreach ($result as $row) {
343
            if ($pluginName == $row['selected_value']) {
344
                $areas[] = $row['variable'];
345
            }
346
        }
347
348
        return $areas;
349
    }
350
351
    /**
352
     * @param string $pluginName
353
     *
354
     * @return bool
355
     */
356
    public function is_valid_plugin($pluginName)
357
    {
358
        if (is_dir(api_get_path(SYS_PLUGIN_PATH).$pluginName)) {
359
            if (is_file(api_get_path(SYS_PLUGIN_PATH).$pluginName.'/index.php')) {
360
                return true;
361
            }
362
        }
363
364
        return false;
365
    }
366
367
    /**
368
     * @return array
369
     */
370
    public function get_plugin_regions()
371
    {
372
        sort($this->plugin_regions);
373
374
        return $this->plugin_regions;
375
    }
376
377
    /**
378
     * @param string   $region
379
     * @param Template $template
380
     * @param bool     $forced
381
     *
382
     * @return string|null
383
     */
384
    public function load_region($region, $template, $forced = false)
385
    {
386
        if ($region == 'course_tool_plugin') {
387
            return '';
388
        }
389
390
        ob_start();
391
        $this->get_all_plugin_contents_by_region($region, $template, $forced);
392
        $content = ob_get_contents();
393
        ob_end_clean();
394
395
        return $content;
396
    }
397
398
    /**
399
     * Loads the translation files inside a plugin if exists.
400
     * It loads by default english see the hello world plugin.
401
     *
402
     * @param string $plugin_name
403
     *
404
     * @todo add caching
405
     */
406
    public function load_plugin_lang_variables($plugin_name)
407
    {
408
        global $language_interface;
409
        $root = api_get_path(SYS_PLUGIN_PATH);
410
        $strings = null;
411
412
        // 1. Loading english if exists
413
        $english_path = $root.$plugin_name."/lang/english.php";
414
415
        if (is_readable($english_path)) {
416
            include $english_path;
417
418
            foreach ($strings as $key => $string) {
0 ignored issues
show
Bug introduced by
The expression $strings of type null is not traversable.
Loading history...
419
                $GLOBALS[$key] = $string;
420
            }
421
        }
422
423
        // 2. Loading the system language
424
        if ($language_interface != 'english') {
425
            $path = $root.$plugin_name."/lang/$language_interface.php";
426
427
            if (is_readable($path)) {
428
                include $path;
429
                if (!empty($strings)) {
430
                    foreach ($strings as $key => $string) {
431
                        $GLOBALS[$key] = $string;
432
                    }
433
                }
434
            } else {
435
                $interfaceLanguageId = api_get_language_id($language_interface);
436
                $interfaceLanguageInfo = api_get_language_info($interfaceLanguageId);
437
                $languageParentId = intval($interfaceLanguageInfo['parent_id']);
438
439
                if ($languageParentId > 0) {
440
                    $languageParentInfo = api_get_language_info($languageParentId);
441
                    $languageParentFolder = $languageParentInfo['dokeos_folder'];
442
443
                    $parentPath = "{$root}{$plugin_name}/lang/{$languageParentFolder}.php";
444
                    if (is_readable($parentPath)) {
445
                        include $parentPath;
446
                        if (!empty($strings)) {
447
                            foreach ($strings as $key => $string) {
448
                                $this->strings[$key] = $string;
0 ignored issues
show
Bug Best Practice introduced by
The property strings does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
449
                            }
450
                        }
451
                    }
452
                }
453
            }
454
        }
455
    }
456
457
    /**
458
     * @param string   $region
459
     * @param Template $template
460
     * @param bool     $forced
461
     *
462
     * @return bool
463
     *
464
     * @todo improve this function
465
     */
466
    public function get_all_plugin_contents_by_region($region, $template, $forced = false)
467
    {
468
        global $_plugins;
469
        if (isset($_plugins[$region]) && is_array($_plugins[$region])) {
470
            // Load the plugin information
471
            foreach ($_plugins[$region] as $plugin_name) {
472
                // The plugin_info variable is available inside the plugin index
473
                $plugin_info = $this->getPluginInfo($plugin_name, $forced);
474
475
                // We also know where the plugin is
476
                $plugin_info['current_region'] = $region;
477
478
                // Loading the plugin/XXX/index.php file
479
                $plugin_file = api_get_path(SYS_PLUGIN_PATH)."$plugin_name/index.php";
480
481
                if (file_exists($plugin_file)) {
482
                    //Loading the lang variables of the plugin if exists
483
                    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

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