Passed
Push — 1.11.x ( 57356f...e797ca )
by Yannick
10:01
created

Plugin   F

Complexity

Total Complexity 150

Size/Duplication

Total Lines 1127
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 150
eloc 479
c 0
b 0
f 0
dl 0
loc 1127
rs 2

40 Methods

Rating   Name   Duplication   Size   Complexity  
A setCourseToolDefaultVisibility() 0 3 1
A get_lang_plugin_exists() 0 3 1
B addTab() 0 68 5
A uninstall_course_fields_in_all_courses() 0 9 2
A doWhenDeletingUser() 0 2 1
A getCamelCaseName() 0 5 1
A get_comment() 0 3 1
A updateTab() 0 8 1
F getSettingsForm() 0 136 30
A setHasPersonalEvents() 0 3 1
A getAdminUrl() 0 19 4
A doWhenDeletingSession() 0 2 1
A getCourseSettings() 0 20 6
A course_install() 0 3 1
A disableSettings() 0 8 3
B get() 0 28 9
B deleteTab() 0 40 7
A performActionsAfterConfigure() 0 3 1
A get_info() 0 27 4
A manageTab() 0 25 4
A renderRegion() 0 3 1
A getCourseToolDefaultVisibility() 0 3 1
A install_course_fields_in_all_courses() 0 8 2
A getLangFromFile() 0 23 4
A get_version() 0 3 1
C get_lang() 0 55 13
A get_name() 0 7 1
A validateCourseSetting() 0 3 1
A course_settings_updated() 0 2 1
B uninstall_course_fields() 0 36 6
C install_course_fields() 0 78 12
A __construct() 0 8 1
B isEnabled() 0 35 8
A createLinkToCourseTool() 0 55 5
A doWhenDeletingCourse() 0 2 1
A get_settings() 0 17 3
A get_author() 0 3 1
A get_title() 0 3 1
A getToolIconVisibilityPerUserStatus() 0 3 1
A get_css() 0 12 2

How to fix   Complexity   

Complex Class

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

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

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

1
<?php
2
3
/* For licensing terms, see /license.txt */
4
5
use Chamilo\CourseBundle\Entity\CTool;
6
7
/**
8
 * Class Plugin
9
 * Base class for plugins.
10
 *
11
 * This class has to be extended by every plugin. It defines basic methods
12
 * to install/uninstall and get information about a plugin
13
 *
14
 * @author    Julio Montoya <[email protected]>
15
 * @author    Yannick Warnier <[email protected]>
16
 * @author    Laurent Opprecht    <[email protected]>
17
 * @copyright 2012 University of Geneva
18
 * @license   GNU General Public License - http://www.gnu.org/copyleft/gpl.html
19
 */
20
class Plugin
21
{
22
    public const TAB_FILTER_NO_STUDENT = '::no-student';
23
    public const TAB_FILTER_ONLY_STUDENT = '::only-student';
24
    public $isCoursePlugin = false;
25
    public $isAdminPlugin = false;
26
    public $isMailPlugin = false;
27
    // Adds icon in the course home
28
    public $addCourseTool = true;
29
    public $hasPersonalEvents = false;
30
    // Whether the tool created should be visible immediately or disabled first (defaults to visible)
31
    public bool $courseToolDefaultVisibility = true;
32
33
    /**
34
     * When creating a new course, these settings are added to the course, in
35
     * the course_info/infocours.php
36
     * To show the plugin course icons you need to add these icons:
37
     * main/img/icons/22/plugin_name.png
38
     * main/img/icons/64/plugin_name.png
39
     * main/img/icons/64/plugin_name_na.png.
40
     *
41
     * @example
42
     * $course_settings = array(
43
    array('name' => 'big_blue_button_welcome_message',  'type' => 'text'),
44
    array('name' => 'big_blue_button_record_and_store', 'type' => 'checkbox')
45
    );
46
     */
47
    public $course_settings = [];
48
    /**
49
     * This indicates whether changing the setting should execute the callback
50
     * function.
51
     */
52
    public $course_settings_callback = false;
53
54
    protected $version = '';
55
    protected $author = '';
56
    protected $fields = [];
57
    private $settings = [];
58
    // Translation strings.
59
    private $strings = null;
60
61
    /**
62
     * Default constructor for the plugin class. By default, it only sets
63
     * a few attributes of the object.
64
     *
65
     * @param string $version  of this plugin
66
     * @param string $author   of this plugin
67
     * @param array  $settings settings to be proposed to configure the plugin
68
     */
69
    protected function __construct($version, $author, $settings = [])
70
    {
71
        $this->version = $version;
72
        $this->author = $author;
73
        $this->fields = $settings;
74
75
        global $language_files;
76
        $language_files[] = 'plugin_'.$this->get_name();
77
    }
78
79
    /**
80
     * Gets an array of information about this plugin (name, version, ...).
81
     *
82
     * @return array Array of information elements about this plugin
83
     */
84
    public function get_info()
85
    {
86
        $result = [];
87
        $result['obj'] = $this;
88
        $result['title'] = $this->get_title();
89
        $result['comment'] = $this->get_comment();
90
        $result['version'] = $this->get_version();
91
        $result['author'] = $this->get_author();
92
        $result['plugin_class'] = get_class($this);
93
        $result['is_course_plugin'] = $this->isCoursePlugin;
94
        $result['is_admin_plugin'] = $this->isAdminPlugin;
95
        $result['is_mail_plugin'] = $this->isMailPlugin;
96
97
        if ($form = $this->getSettingsForm()) {
98
            $result['settings_form'] = $form;
99
100
            foreach ($this->fields as $name => $type) {
101
                $value = $this->get($name);
102
103
                if (is_array($type)) {
104
                    $value = $type['options'];
105
                }
106
                $result[$name] = $value;
107
            }
108
        }
109
110
        return $result;
111
    }
112
113
    /**
114
     * Returns the "system" name of the plugin in lowercase letters.
115
     *
116
     * @return string
117
     */
118
    public function get_name()
119
    {
120
        $result = get_class($this);
121
        $result = str_replace('Plugin', '', $result);
122
        $result = strtolower($result);
123
124
        return $result;
125
    }
126
127
    /**
128
     * @return string
129
     */
130
    public function getCamelCaseName()
131
    {
132
        $result = get_class($this);
133
134
        return str_replace('Plugin', '', $result);
135
    }
136
137
    /**
138
     * Returns the title of the plugin.
139
     *
140
     * @return string
141
     */
142
    public function get_title()
143
    {
144
        return $this->get_lang('plugin_title');
145
    }
146
147
    /**
148
     * Returns the description of the plugin.
149
     *
150
     * @return string
151
     */
152
    public function get_comment()
153
    {
154
        return $this->get_lang('plugin_comment');
155
    }
156
157
    /**
158
     * Returns the version of the plugin.
159
     *
160
     * @return string
161
     */
162
    public function get_version()
163
    {
164
        return $this->version;
165
    }
166
167
    /**
168
     * Returns the author of the plugin.
169
     *
170
     * @return string
171
     */
172
    public function get_author()
173
    {
174
        return $this->author;
175
    }
176
177
    /**
178
     * Returns the contents of the CSS defined by the plugin.
179
     *
180
     * @return string
181
     */
182
    public function get_css()
183
    {
184
        $name = $this->get_name();
185
        $path = api_get_path(SYS_PLUGIN_PATH)."$name/resources/$name.css";
186
        if (!is_readable($path)) {
187
            return '';
188
        }
189
        $css = [];
190
        $css[] = file_get_contents($path);
191
        $result = implode($css);
192
193
        return $result;
194
    }
195
196
    /**
197
     * Returns an HTML form (generated by FormValidator) of the plugin settings.
198
     *
199
     * @return FormValidator FormValidator-generated form
200
     */
201
    public function getSettingsForm()
202
    {
203
        $result = new FormValidator($this->get_name());
204
        $defaults = [];
205
        $checkboxGroup = [];
206
        $checkboxCollection = [];
207
208
        if ($checkboxNames = array_keys($this->fields, 'checkbox')) {
209
            $pluginInfoCollection = api_get_settings('Plugins');
210
            foreach ($pluginInfoCollection as $pluginInfo) {
211
                if (array_search($pluginInfo['title'], $checkboxNames) !== false) {
212
                    $checkboxCollection[$pluginInfo['title']] = $pluginInfo;
213
                }
214
            }
215
        }
216
217
        $disableSettings = $this->disableSettings();
218
219
        foreach ($this->fields as $name => $type) {
220
            $options = null;
221
            if (is_array($type) && isset($type['type']) && $type['type'] === 'select') {
222
                $attributes = isset($type['attributes']) ? $type['attributes'] : [];
223
                if (!empty($type['options']) && isset($type['translate_options']) && $type['translate_options']) {
224
                    foreach ($type['options'] as $key => &$optionName) {
225
                        $optionName = $this->get_lang($optionName);
226
                    }
227
                }
228
                $options = $type['options'];
229
                $type = $type['type'];
230
            }
231
232
            if (!empty($disableSettings)) {
233
                if (in_array($name, $disableSettings)) {
234
                    continue;
235
                }
236
            }
237
238
            $value = $this->get($name);
239
            $defaults[$name] = $value;
240
            $type = isset($type) ? $type : 'text';
241
242
            $help = null;
243
            if ($this->get_lang_plugin_exists($name.'_help')) {
244
                $help = $this->get_lang($name.'_help');
245
                if ($name === 'show_main_menu_tab') {
246
                    $pluginName = strtolower(str_replace('Plugin', '', get_class($this)));
247
                    $pluginUrl = api_get_path(WEB_PATH)."plugin/$pluginName/index.php";
248
                    $pluginUrl = "<a href=$pluginUrl>$pluginUrl</a>";
249
                    $help = sprintf($help, $pluginUrl);
250
                }
251
            }
252
253
            switch ($type) {
254
                case 'html':
255
                    $result->addHtml($this->get_lang($name));
256
                    break;
257
                case 'wysiwyg':
258
                    $result->addHtmlEditor($name, $this->get_lang($name), false);
259
                    break;
260
                case 'text':
261
                    $result->addElement($type, $name, [$this->get_lang($name), $help]);
262
                    break;
263
                case 'boolean':
264
                    $group = [];
265
                    $group[] = $result->createElement(
266
                        'radio',
267
                        $name,
268
                        '',
269
                        get_lang('Yes'),
270
                        'true'
271
                    );
272
                    $group[] = $result->createElement(
273
                        'radio',
274
                        $name,
275
                        '',
276
                        get_lang('No'),
277
                        'false'
278
                    );
279
                    $result->addGroup($group, null, [$this->get_lang($name), $help]);
280
                    break;
281
                case 'checkbox':
282
                    $selectedValue = null;
283
                    if (isset($checkboxCollection[$name])) {
284
                        if ($checkboxCollection[$name]['selected_value'] === 'true') {
285
                            $selectedValue = 'checked';
286
                        }
287
                    }
288
289
                    $element = $result->createElement(
290
                        $type,
291
                        $name,
292
                        '',
293
                        $this->get_lang($name),
294
                        $selectedValue
295
                    );
296
                    $element->_attributes['value'] = 'true';
297
                    $checkboxGroup[] = $element;
298
                    break;
299
                case 'select':
300
                    $result->addElement(
301
                        $type,
302
                        $name,
303
                        [$this->get_lang($name), $help],
304
                        $options,
305
                        $attributes
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $attributes does not seem to be defined for all execution paths leading up to this point.
Loading history...
306
                    );
307
                    break;
308
                case 'user':
309
                    $options = [];
310
                    if (!empty($value)) {
311
                        $userInfo = api_get_user_info($value);
312
                        if ($userInfo) {
313
                            $options[$value] = $userInfo['complete_name'];
314
                        }
315
                    }
316
                    $result->addSelectAjax(
317
                        $name,
318
                        [$this->get_lang($name), $help],
319
                        $options,
320
                        ['url' => api_get_path(WEB_AJAX_PATH).'user_manager.ajax.php?a=get_user_like']
321
                    );
322
                    break;
323
            }
324
        }
325
326
        if (!empty($checkboxGroup)) {
327
            $result->addGroup(
328
                $checkboxGroup,
329
                null,
330
                ['', $help]
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $help does not seem to be defined for all execution paths leading up to this point.
Loading history...
331
            );
332
        }
333
        $result->setDefaults($defaults);
334
        $result->addButtonSave($this->get_lang('Save'), 'submit_button');
335
336
        return $result;
337
    }
338
339
    /**
340
     * Returns the value of a given plugin global setting.
341
     *
342
     * @param string $name of the plugin setting
343
     *
344
     * @return string Value of the plugin setting
345
     */
346
    public function get($name)
347
    {
348
        $settings = api_get_configuration_value('plugin_settings');
349
        if (!empty($settings) && isset($settings[$this->get_name()])) {
350
            $prioritySettings = $settings[$this->get_name()];
351
            if (!empty($prioritySettings)) {
352
                if (isset($prioritySettings[$name])) {
353
                    return $prioritySettings[$name];
354
                }
355
            }
356
        }
357
358
        $settings = $this->get_settings();
359
        foreach ($settings as $setting) {
360
            if ($setting['variable'] == $this->get_name().'_'.$name) {
361
                $unserialized = UnserializeApi::unserialize('not_allowed_classes', $setting['selected_value'], true);
362
363
                if (!empty($setting['selected_value']) &&
364
                    false !== $unserialized
365
                ) {
366
                    $setting['selected_value'] = $unserialized;
367
                }
368
369
                return $setting['selected_value'];
370
            }
371
        }
372
373
        return false;
374
    }
375
376
    /**
377
     * Returns an array with the global settings for this plugin.
378
     *
379
     * @param bool $forceFromDB Optional. Force get settings from the database
380
     *
381
     * @return array Plugin settings as an array
382
     */
383
    public function get_settings($forceFromDB = false)
384
    {
385
        if (empty($this->settings) || $forceFromDB) {
386
            $settings = api_get_settings_params(
387
                [
388
                    "subkey = ? AND category = ? AND type = ? AND access_url = ?" => [
389
                        $this->get_name(),
390
                        'Plugins',
391
                        'setting',
392
                        api_get_current_access_url_id(),
393
                    ],
394
                ]
395
            );
396
            $this->settings = $settings;
397
        }
398
399
        return $this->settings;
400
    }
401
402
    /**
403
     * Tells whether language variables are defined for this plugin or not.
404
     *
405
     * @param string $name System name of the plugin
406
     *
407
     * @return bool True if the plugin has language variables defined, false otherwise
408
     */
409
    public function get_lang_plugin_exists($name)
410
    {
411
        return isset($this->strings[$name]);
412
    }
413
414
    /**
415
     * Hook for the get_lang() function to check for plugin-defined language terms.
416
     *
417
     * @param string $name of the language variable we are looking for
418
     *
419
     * @return string The translated language term of the plugin
420
     */
421
    public function get_lang($name)
422
    {
423
        // Check whether the language strings for the plugin have already been
424
        // loaded. If so, no need to load them again.
425
        if (is_null($this->strings)) {
426
            $language_interface = api_get_interface_language();
427
            $root = api_get_path(SYS_PLUGIN_PATH);
428
            $plugin_name = $this->get_name();
429
430
            $interfaceLanguageId = api_get_language_id($language_interface);
431
            if (empty($interfaceLanguageId)) {
432
                $language_interface = api_get_setting('platformLanguage');
433
                $interfaceLanguageId = api_get_language_id($language_interface);
434
            }
435
            $interfaceLanguageInfo = api_get_language_info($interfaceLanguageId);
436
            $languageParentId = !empty($interfaceLanguageInfo['parent_id']) ? (int) $interfaceLanguageInfo['parent_id'] : 0;
437
438
            // 1. Loading english if exists
439
            $english_path = $root.$plugin_name."/lang/english.php";
440
441
            if (is_readable($english_path)) {
442
                $strings = [];
443
                include $english_path;
444
                $this->strings = $strings;
445
            }
446
447
            $path = $root.$plugin_name."/lang/$language_interface.php";
448
            // 2. Loading the system language
449
            if (is_readable($path)) {
450
                include $path;
451
                if (!empty($strings)) {
452
                    foreach ($strings as $key => $string) {
453
                        $this->strings[$key] = $string;
454
                    }
455
                }
456
            } elseif ($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
        if (isset($this->strings[$name])) {
472
            return $this->strings[$name];
473
        }
474
475
        return get_lang($name);
476
    }
477
478
    /**
479
     * @param string $variable
480
     * @param string $language
481
     *
482
     * @return string
483
     */
484
    public function getLangFromFile($variable, $language)
485
    {
486
        static $langStrings = [];
487
488
        if (empty($langStrings[$language])) {
489
            $root = api_get_path(SYS_PLUGIN_PATH);
490
            $pluginName = $this->get_name();
491
492
            $englishPath = "$root$pluginName/lang/$language.php";
493
494
            if (is_readable($englishPath)) {
495
                $strings = [];
496
                include $englishPath;
497
498
                $langStrings[$language] = $strings;
499
            }
500
        }
501
502
        if (isset($langStrings[$language][$variable])) {
503
            return $langStrings[$language][$variable];
504
        }
505
506
        return $this->get_lang($variable);
507
    }
508
509
    /**
510
     * Caller for the install_course_fields() function.
511
     *
512
     * @param int  $courseId
513
     * @param bool $addToolLink Whether to add a tool link on the course homepage
514
     */
515
    public function course_install($courseId, $addToolLink = true)
516
    {
517
        $this->install_course_fields($courseId, $addToolLink);
518
    }
519
520
    /**
521
     * Add course settings and, if not asked otherwise, add a tool link on the course homepage.
522
     *
523
     * @param int  $courseId      Course integer ID
524
     * @param bool $add_tool_link Whether to add a tool link or not
525
     *                            (some tools might just offer a configuration section and act on the backend)
526
     *
527
     * @return bool|null False on error, null otherwise
528
     */
529
    public function install_course_fields($courseId, $add_tool_link = true, $iconName = '')
530
    {
531
        $plugin_name = $this->get_name();
532
        $t_course = Database::get_course_table(TABLE_COURSE_SETTING);
533
        $courseId = (int) $courseId;
534
535
        if (empty($courseId)) {
536
            return false;
537
        }
538
539
        // Adding course settings.
540
        if (!empty($this->course_settings)) {
541
            foreach ($this->course_settings as $setting) {
542
                $variable = $setting['name'];
543
                $value = '';
544
                if (isset($setting['init_value'])) {
545
                    $value = $setting['init_value'];
546
                }
547
548
                $pluginGlobalValue = api_get_plugin_setting($plugin_name, $variable);
549
                if (null !== $pluginGlobalValue) {
550
                    $value = 1;
551
                }
552
553
                $type = 'textfield';
554
                if (isset($setting['type'])) {
555
                    $type = $setting['type'];
556
                }
557
558
                if (isset($setting['group'])) {
559
                    $group = $setting['group'];
560
                    $sql = "SELECT value
561
                            FROM $t_course
562
                            WHERE
563
                                c_id = $courseId AND
564
                                variable = '".Database::escape_string($group)."' AND
565
                                subkey = '".Database::escape_string($variable)."'
566
                            ";
567
                    $result = Database::query($sql);
568
                    if (!Database::num_rows($result)) {
569
                        $params = [
570
                            'c_id' => $courseId,
571
                            'variable' => $group,
572
                            'subkey' => $variable,
573
                            'value' => $value,
574
                            'category' => 'plugins',
575
                            'type' => $type,
576
                            'title' => '',
577
                        ];
578
                        Database::insert($t_course, $params);
579
                    }
580
                } else {
581
                    $sql = "SELECT value FROM $t_course
582
                            WHERE c_id = $courseId AND variable = '$variable' ";
583
                    $result = Database::query($sql);
584
                    if (!Database::num_rows($result)) {
585
                        $params = [
586
                            'c_id' => $courseId,
587
                            'variable' => $variable,
588
                            'subkey' => $plugin_name,
589
                            'value' => $value,
590
                            'category' => 'plugins',
591
                            'type' => $type,
592
                            'title' => '',
593
                        ];
594
                        Database::insert($t_course, $params);
595
                    }
596
                }
597
            }
598
        }
599
600
        // Stop here if we don't want a tool link on the course homepage
601
        if (!$add_tool_link || $this->addCourseTool == false) {
602
            return true;
603
        }
604
605
        // Add an icon in the table tool list
606
        $this->createLinkToCourseTool($plugin_name, $courseId, $iconName);
607
    }
608
609
    /**
610
     * Delete the fields added to the course settings page and the link to the
611
     * tool on the course's homepage.
612
     *
613
     * @param int $courseId
614
     *
615
     * @return false|null
616
     */
617
    public function uninstall_course_fields($courseId)
618
    {
619
        $courseId = (int) $courseId;
620
621
        if (empty($courseId)) {
622
            return false;
623
        }
624
        $pluginName = $this->get_name();
625
626
        $t_course = Database::get_course_table(TABLE_COURSE_SETTING);
627
        $t_tool = Database::get_course_table(TABLE_TOOL_LIST);
628
629
        if (!empty($this->course_settings)) {
630
            foreach ($this->course_settings as $setting) {
631
                $variable = Database::escape_string($setting['name']);
632
                if (!empty($setting['group'])) {
633
                    $variable = Database::escape_string($setting['group']);
634
                }
635
                if (empty($variable)) {
636
                    continue;
637
                }
638
                $sql = "DELETE FROM $t_course
639
                        WHERE c_id = $courseId AND variable = '$variable'";
640
                Database::query($sql);
641
            }
642
        }
643
644
        $pluginName = Database::escape_string($pluginName);
645
        $sql = "DELETE FROM $t_tool
646
                WHERE c_id = $courseId AND
647
                (
648
                  name = '$pluginName' OR
649
                  name = '$pluginName:student' OR
650
                  name = '$pluginName:teacher'
651
                )";
652
        Database::query($sql);
653
    }
654
655
    /**
656
     * Install the course fields and tool link of this plugin in all courses.
657
     *
658
     * @param bool $add_tool_link Whether we want to add a plugin link on the course homepage
659
     */
660
    public function install_course_fields_in_all_courses($add_tool_link = true, $iconName = '')
661
    {
662
        // Update existing courses to add plugin settings
663
        $table = Database::get_main_table(TABLE_MAIN_COURSE);
664
        $sql = "SELECT id FROM $table ORDER BY id";
665
        $res = Database::query($sql);
666
        while ($row = Database::fetch_assoc($res)) {
667
            $this->install_course_fields($row['id'], $add_tool_link, $iconName);
668
        }
669
    }
670
671
    /**
672
     * Uninstall the plugin settings fields from all courses.
673
     */
674
    public function uninstall_course_fields_in_all_courses()
675
    {
676
        // Update existing courses to add conference settings
677
        $table = Database::get_main_table(TABLE_MAIN_COURSE);
678
        $sql = "SELECT id FROM $table
679
                ORDER BY id";
680
        $res = Database::query($sql);
681
        while ($row = Database::fetch_assoc($res)) {
682
            $this->uninstall_course_fields($row['id']);
683
        }
684
    }
685
686
    /**
687
     * @return array
688
     */
689
    public function getCourseSettings()
690
    {
691
        $settings = [];
692
        if (is_array($this->course_settings)) {
693
            foreach ($this->course_settings as $item) {
694
                // Skip html type
695
                if ('html' === $item['type']) {
696
                    continue;
697
                }
698
                if (isset($item['group'])) {
699
                    if (!in_array($item['group'], $settings)) {
700
                        $settings[] = $item['group'];
701
                    }
702
                } else {
703
                    $settings[] = $item['name'];
704
                }
705
            }
706
        }
707
708
        return $settings;
709
    }
710
711
    /**
712
     * Method to be extended when changing the setting in the course
713
     * configuration should trigger the use of a callback method.
714
     *
715
     * @param array $values sent back from the course configuration script
716
     */
717
    public function course_settings_updated($values = [])
718
    {
719
    }
720
721
    /**
722
     * Add a tab to platform.
723
     *
724
     * @param string $tabName
725
     * @param string $url
726
     * @param string $userFilter Optional. Filter tab type
727
     *
728
     * @return false|string
729
     */
730
    public function addTab($tabName, $url, $userFilter = null)
731
    {
732
        $sql = "SELECT * FROM settings_current
733
                WHERE
734
                    variable = 'show_tabs' AND
735
                    subkey LIKE 'custom_tab_%'";
736
        $result = Database::query($sql);
737
        $customTabsNum = Database::num_rows($result);
738
739
        $tabNum = $customTabsNum + 1;
740
741
        // Avoid Tab Name Spaces
742
        $tabNameNoSpaces = preg_replace('/\s+/', '', $tabName);
743
        $subkeytext = "Tabs".$tabNameNoSpaces;
744
745
        // Check if it is already added
746
        $checkCondition = [
747
            'where' => [
748
                    "variable = 'show_tabs' AND subkeytext = ?" => [
749
                        $subkeytext,
750
                    ],
751
                ],
752
        ];
753
754
        $checkDuplicate = Database::select('*', 'settings_current', $checkCondition);
755
        if (!empty($checkDuplicate)) {
756
            return false;
757
        }
758
759
        // End Check
760
        $subkey = 'custom_tab_'.$tabNum;
761
762
        if (!empty($userFilter)) {
763
            switch ($userFilter) {
764
                case self::TAB_FILTER_NO_STUDENT:
765
                case self::TAB_FILTER_ONLY_STUDENT:
766
                    $subkey .= $userFilter;
767
                    break;
768
            }
769
        }
770
771
        $currentUrlId = api_get_current_access_url_id();
772
        $attributes = [
773
            'variable' => 'show_tabs',
774
            'subkey' => $subkey,
775
            'type' => 'checkbox',
776
            'category' => 'Platform',
777
            'selected_value' => 'true',
778
            'title' => $tabName,
779
            'comment' => $url,
780
            'subkeytext' => $subkeytext,
781
            'access_url' => $currentUrlId,
782
            'access_url_changeable' => 1,
783
            'access_url_locked' => 0,
784
        ];
785
        $resp = Database::insert('settings_current', $attributes);
786
787
        // Save the id
788
        $settings = $this->get_settings();
789
        $setData = [
790
            'comment' => $subkey,
791
        ];
792
        $whereCondition = [
793
            'id = ?' => key($settings),
794
        ];
795
        Database::update('settings_current', $setData, $whereCondition);
796
797
        return $resp;
798
    }
799
800
    /**
801
     * Delete a tab to chamilo's platform.
802
     *
803
     * @param string $key
804
     *
805
     * @return bool $resp Transaction response
806
     */
807
    public function deleteTab($key)
808
    {
809
        $table = Database::get_main_table(TABLE_MAIN_SETTINGS_CURRENT);
810
        $sql = "SELECT *
811
                FROM $table
812
                WHERE variable = 'show_tabs'
813
                AND subkey <> '$key'
814
                AND subkey like 'custom_tab_%'
815
                ";
816
        $resp = $result = Database::query($sql);
817
        $customTabsNum = Database::num_rows($result);
818
819
        if (!empty($key)) {
820
            $whereCondition = [
821
                'variable = ? AND subkey = ?' => ['show_tabs', $key],
822
            ];
823
            $resp = Database::delete('settings_current', $whereCondition);
824
825
            //if there is more than one tab
826
            //re enumerate them
827
            if (!empty($customTabsNum) && $customTabsNum > 0) {
828
                $tabs = Database::store_result($result, 'ASSOC');
829
                $i = 1;
830
                foreach ($tabs as $row) {
831
                    $newSubKey = "custom_tab_$i";
832
833
                    if (strpos($row['subkey'], self::TAB_FILTER_NO_STUDENT) !== false) {
834
                        $newSubKey .= self::TAB_FILTER_NO_STUDENT;
835
                    } elseif (strpos($row['subkey'], self::TAB_FILTER_ONLY_STUDENT) !== false) {
836
                        $newSubKey .= self::TAB_FILTER_ONLY_STUDENT;
837
                    }
838
839
                    $attributes = ['subkey' => $newSubKey];
840
                    $this->updateTab($row['subkey'], $attributes);
841
                    $i++;
842
                }
843
            }
844
        }
845
846
        return $resp;
847
    }
848
849
    /**
850
     * Update the tabs attributes.
851
     *
852
     * @param string $key
853
     * @param array  $attributes
854
     *
855
     * @return bool
856
     */
857
    public function updateTab($key, $attributes)
858
    {
859
        $whereCondition = [
860
            'variable = ? AND subkey = ?' => ['show_tabs', $key],
861
        ];
862
        $resp = Database::update('settings_current', $attributes, $whereCondition);
863
864
        return $resp;
865
    }
866
867
    /**
868
     * This method shows or hides plugin's tab.
869
     *
870
     * @param bool   $showTab  Shows or hides the main menu plugin tab
871
     * @param string $filePath Plugin starter file path
872
     */
873
    public function manageTab($showTab, $filePath = 'index.php')
874
    {
875
        $langString = str_replace('Plugin', '', get_class($this));
876
        $pluginName = strtolower($langString);
877
        $pluginUrl = 'plugin/'.$pluginName.'/'.$filePath;
878
879
        if ($showTab === 'true') {
880
            $tabAdded = $this->addTab($langString, $pluginUrl);
881
            if ($tabAdded) {
882
                // The page must be refreshed to show the recently created tab
883
                echo "<script>location.href = '".Security::remove_XSS($_SERVER['REQUEST_URI'])."';</script>";
884
            }
885
        } else {
886
            $settingsCurrentTable = Database::get_main_table(TABLE_MAIN_SETTINGS_CURRENT);
887
            $conditions = [
888
                'where' => [
889
                    "variable = 'show_tabs' AND title = ? AND comment = ? " => [
890
                        $langString,
891
                        $pluginUrl,
892
                    ],
893
                ],
894
            ];
895
            $result = Database::select('subkey', $settingsCurrentTable, $conditions);
896
            if (!empty($result)) {
897
                $this->deleteTab($result[0]['subkey']);
898
            }
899
        }
900
    }
901
902
    /**
903
     * @param string $variable
904
     *
905
     * @return bool
906
     */
907
    public function validateCourseSetting($variable)
908
    {
909
        return true;
910
    }
911
912
    /**
913
     * @param string $region
914
     *
915
     * @return string
916
     */
917
    public function renderRegion($region)
918
    {
919
        return '';
920
    }
921
922
    /**
923
     * Returns true if the plugin is installed, false otherwise.
924
     *
925
     * @param bool $checkEnabled Also check if enabled (instead of only installed)
926
     *
927
     * @return bool True if plugin is installed/enabled, false otherwise
928
     */
929
    public function isEnabled(bool $checkEnabled = false): bool
930
    {
931
        $settings = api_get_settings_params_simple(
932
            [
933
                "subkey = ? AND category = ? AND type = ? AND variable = 'status' " => [
934
                    $this->get_name(),
935
                    'Plugins',
936
                    'setting',
937
                ],
938
            ]
939
        );
940
        if (is_array($settings) && isset($settings['selected_value']) && $settings['selected_value'] == 'installed') {
941
            // The plugin is installed
942
            // If we need a check on whether it is enabled, also check for
943
            // *plugin*_tool_enable and make sure it is *NOT* false
944
            if ($checkEnabled) {
945
                $enabled = api_get_settings_params_simple(
946
                    [
947
                        "variable = ? AND subkey = ? AND category = 'Plugins' " => [
948
                            $this->get_name().'_tool_enable',
949
                            $this->get_name(),
950
                        ],
951
                    ]
952
                );
953
                if (is_array($enabled) && isset($enabled['selected_value']) && $enabled['selected_value'] == 'false') {
954
                    // Only return false if the setting exists and it is
955
                    // *specifically* set to false
956
                    return false;
957
                }
958
            }
959
960
            return true;
961
        }
962
963
        return false;
964
    }
965
966
    /**
967
     * Allow make some actions after configure the plugin parameters
968
     * This function is called from main/admin/configure_plugin.php page
969
     * when saving the plugin parameters.
970
     *
971
     * @return \Plugin
972
     */
973
    public function performActionsAfterConfigure()
974
    {
975
        return $this;
976
    }
977
978
    /**
979
     * This function allows to change the visibility of the icon inside a course
980
     * :student tool will be visible only for students
981
     * :teacher tool will be visible only for teachers
982
     * If nothing it's set then tool will be visible for both as a normal icon.
983
     *
984
     * @return string
985
     */
986
    public function getToolIconVisibilityPerUserStatus()
987
    {
988
        return '';
989
    }
990
991
    /**
992
     * Get the admin URL for the plugin if Plugin::isAdminPlugin is true.
993
     *
994
     * @return string
995
     */
996
    public function getAdminUrl()
997
    {
998
        if (!$this->isAdminPlugin) {
999
            return '';
1000
        }
1001
1002
        $name = $this->get_name();
1003
        $sysPath = api_get_path(SYS_PLUGIN_PATH).$name;
1004
        $webPath = api_get_path(WEB_PLUGIN_PATH).$name;
1005
1006
        if (file_exists("$sysPath/admin.php")) {
1007
            return "$webPath/admin.php";
1008
        }
1009
1010
        if (file_exists("$sysPath/start.php")) {
1011
            return "$webPath/start.php";
1012
        }
1013
1014
        return '';
1015
    }
1016
1017
    /**
1018
     * @param bool $value
1019
     */
1020
    public function setHasPersonalEvents($value)
1021
    {
1022
        $this->hasPersonalEvents = $value;
1023
    }
1024
1025
    /**
1026
     * Overwrite to perform some actions when deleting a user.
1027
     *
1028
     * @param int $userId
1029
     */
1030
    public function doWhenDeletingUser($userId)
1031
    {
1032
    }
1033
1034
    /**
1035
     * Overwrite to perform some actions when deleting a course.
1036
     *
1037
     * @param int $courseId
1038
     */
1039
    public function doWhenDeletingCourse($courseId)
1040
    {
1041
    }
1042
1043
    /**
1044
     * Overwrite to perform some actions when deleting a session.
1045
     *
1046
     * @param int $sessionId
1047
     */
1048
    public function doWhenDeletingSession($sessionId)
1049
    {
1050
    }
1051
1052
    /**
1053
     * Disable the settings configured in configuration.php ($configuration[plugin_settings]).
1054
     */
1055
    public function disableSettings()
1056
    {
1057
        $settings = api_get_configuration_value('plugin_settings');
1058
        if (!empty($settings) && isset($settings[$this->get_name()])) {
1059
            return array_keys($settings[$this->get_name()]);
1060
        }
1061
1062
        return [];
1063
    }
1064
1065
    /**
1066
     * Add an link for a course tool.
1067
     *
1068
     * @param string $name     The tool name
1069
     * @param int    $courseId The course ID
1070
     * @param string $iconName Optional. Icon file name
1071
     * @param string $link     Optional. Link URL
1072
     *
1073
     * @return CTool|null
1074
     */
1075
    protected function createLinkToCourseTool(
1076
        $name,
1077
        $courseId,
1078
        $iconName = null,
1079
        $link = null,
1080
        $sessionId = 0,
1081
        $category = 'plugin'
1082
    ) {
1083
        if (!$this->addCourseTool) {
1084
            return null;
1085
        }
1086
1087
        $visibilityPerStatus = $this->getToolIconVisibilityPerUserStatus();
1088
        $visibility = $this->getCourseToolDefaultVisibility();
1089
1090
        $em = Database::getManager();
1091
1092
        /** @var CTool $tool */
1093
        $tool = $em
1094
            ->getRepository('ChamiloCourseBundle:CTool')
1095
            ->findOneBy([
1096
                'name' => $name,
1097
                'cId' => $courseId,
1098
                'category' => $category,
1099
            ]);
1100
1101
        if (!$tool) {
0 ignored issues
show
introduced by
$tool is of type Chamilo\CourseBundle\Entity\CTool, thus it always evaluated to true.
Loading history...
1102
            $pluginName = $this->get_name();
1103
1104
            $tool = new CTool();
1105
            $tool
1106
                ->setCId($courseId)
1107
                ->setName($name.$visibilityPerStatus)
1108
                ->setLink($link ?: "$pluginName/start.php")
1109
                ->setImage($iconName ?: "$pluginName.png")
1110
                ->setVisibility($visibility)
1111
                ->setAdmin(0)
1112
                ->setAddress('squaregrey.gif')
1113
                ->setAddedTool(false)
1114
                ->setTarget('_self')
1115
                ->setCategory($category)
1116
                ->setSessionId($sessionId);
1117
1118
            $em->persist($tool);
1119
            $em->flush();
1120
1121
            $tool->setId(
1122
                $tool->getIid()
1123
            );
1124
1125
            $em->persist($tool);
1126
            $em->flush();
1127
        }
1128
1129
        return $tool;
1130
    }
1131
    /**
1132
     * Get whether the course tool should be visible by default or not
1133
     */
1134
    protected function getCourseToolDefaultVisibility(): bool
1135
    {
1136
        return $this->courseToolDefaultVisibility;
1137
    }
1138
1139
    /**
1140
     * Set whether the tool created in the course must be visible or not
1141
     * @param bool $visibility
1142
     * @return void
1143
     */
1144
    protected function setCourseToolDefaultVisibility(bool $visibility)
1145
    {
1146
        $this->courseToolDefaultVisibility = $visibility;
1147
    }
1148
}
1149