Completed
Push — master ( d5b39b...ee3fd0 )
by Julito
27:10
created

Plugin   F

Complexity

Total Complexity 118

Size/Duplication

Total Lines 921
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 921
rs 1.263
wmc 118

32 Methods

Rating   Name   Duplication   Size   Complexity  
A get_lang_plugin_exists() 0 3 1
A getCamelCaseName() 0 4 1
A get_comment() 0 3 1
F getSettingsForm() 0 108 21
A course_install() 0 3 1
B get() 0 16 5
B get_info() 0 27 4
C get_lang() 0 55 13
A get_version() 0 3 1
A get_name() 0 7 1
C install_course_fields() 0 73 11
A __construct() 0 8 1
A get_author() 0 3 1
A get_title() 0 3 1
A get_css() 0 12 2
A get_settings() 0 17 3
B addTab() 0 68 5
A uninstall_course_fields_in_all_courses() 0 9 2
A updateTab() 0 8 1
A getAdminUrl() 0 19 4
B getCourseSettings() 0 16 5
C deleteTab() 0 40 7
A performActionsAfterConfigure() 0 3 1
B manageTab() 0 25 4
A renderRegion() 0 3 1
A install_course_fields_in_all_courses() 0 8 2
A validateCourseSetting() 0 3 1
A course_settings_updated() 0 2 1
A isEnabled() 0 15 4
B uninstall_course_fields() 0 36 6
B createLinkToCourseTool() 0 46 5
A getToolIconVisibility() 0 3 1

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
/* For licensing terms, see /license.txt */
3
4
use Chamilo\CourseBundle\Entity\CTool;
5
6
/**
7
 * Class Plugin
8
 * Base class for plugins
9
 *
10
 * This class has to be extended by every plugin. It defines basic methods
11
 * to install/uninstall and get information about a plugin
12
 *
13
 * @author    Julio Montoya <[email protected]>
14
 * @author    Yannick Warnier <[email protected]>
15
 * @author    Laurent Opprecht    <[email protected]>
16
 * @copyright 2012 University of Geneva
17
 * @license   GNU General Public License - http://www.gnu.org/copyleft/gpl.html
18
 *
19
 */
20
class Plugin
21
{
22
    const TAB_FILTER_NO_STUDENT = '::no-student';
23
    const TAB_FILTER_ONLY_STUDENT = '::only-student';
24
25
    protected $version = '';
26
    protected $author = '';
27
    protected $fields = [];
28
    private $settings = [];
29
    // Translation strings.
30
    private $strings = null;
31
    public $isCoursePlugin = false;
32
    public $isAdminPlugin = false;
33
    public $isMailPlugin = false;
34
    // Adds icon in the course home
35
    public $addCourseTool = true;
36
37
    /**
38
     * When creating a new course, these settings are added to the course, in
39
     * the course_info/infocours.php
40
     * To show the plugin course icons you need to add these icons:
41
     * main/img/icons/22/plugin_name.png
42
     * main/img/icons/64/plugin_name.png
43
     * main/img/icons/64/plugin_name_na.png
44
     * @example
45
     * $course_settings = array(
46
    array('name' => 'big_blue_button_welcome_message',  'type' => 'text'),
47
    array('name' => 'big_blue_button_record_and_store', 'type' => 'checkbox')
48
    );
49
     */
50
    public $course_settings = [];
51
    /**
52
     * This indicates whether changing the setting should execute the callback
53
     * function.
54
     */
55
    public $course_settings_callback = false;
56
57
    /**
58
     * Default constructor for the plugin class. By default, it only sets
59
     * a few attributes of the object
60
     * @param string $version   of this plugin
61
     * @param string $author    of this plugin
62
     * @param array  $settings  settings to be proposed to configure the plugin
63
     */
64
    protected function __construct($version, $author, $settings = [])
65
    {
66
        $this->version = $version;
67
        $this->author = $author;
68
        $this->fields = $settings;
69
70
        global $language_files;
71
        $language_files[] = 'plugin_'.$this->get_name();
72
    }
73
74
    /**
75
     * Gets an array of information about this plugin (name, version, ...)
76
     * @return  array Array of information elements about this plugin
77
     */
78
    public function get_info()
79
    {
80
        $result = [];
81
        $result['obj'] = $this;
82
        $result['title'] = $this->get_title();
83
        $result['comment'] = $this->get_comment();
84
        $result['version'] = $this->get_version();
85
        $result['author'] = $this->get_author();
86
        $result['plugin_class'] = get_class($this);
87
        $result['is_course_plugin'] = $this->isCoursePlugin;
88
        $result['is_admin_plugin'] = $this->isAdminPlugin;
89
        $result['is_mail_plugin'] = $this->isMailPlugin;
90
91
        if ($form = $this->getSettingsForm()) {
92
            $result['settings_form'] = $form;
93
94
            foreach ($this->fields as $name => $type) {
95
                $value = $this->get($name);
96
97
                if (is_array($type)) {
98
                    $value = $type['options'];
99
                }
100
                $result[$name] = $value;
101
            }
102
        }
103
104
        return $result;
105
    }
106
107
    /**
108
     * Returns the "system" name of the plugin in lowercase letters
109
     * @return string
110
     */
111
    public function get_name()
112
    {
113
        $result = get_class($this);
114
        $result = str_replace('Plugin', '', $result);
115
        $result = strtolower($result);
116
117
        return $result;
118
    }
119
120
    /**
121
     * @return string
122
     */
123
    public function getCamelCaseName()
124
    {
125
        $result = get_class($this);
126
        return str_replace('Plugin', '', $result);
127
    }
128
129
    /**
130
     * Returns the title of the plugin
131
     * @return string
132
     */
133
    public function get_title()
134
    {
135
        return $this->get_lang('plugin_title');
136
    }
137
138
    /**
139
     * Returns the description of the plugin
140
     * @return string
141
     */
142
    public function get_comment()
143
    {
144
        return $this->get_lang('plugin_comment');
145
    }
146
147
    /**
148
     * Returns the version of the plugin
149
     * @return string
150
     */
151
    public function get_version()
152
    {
153
        return $this->version;
154
    }
155
156
    /**
157
     * Returns the author of the plugin
158
     * @return string
159
     */
160
    public function get_author()
161
    {
162
        return $this->author;
163
    }
164
165
    /**
166
     * Returns the contents of the CSS defined by the plugin
167
     * @return string
168
     */
169
    public function get_css()
170
    {
171
        $name = $this->get_name();
172
        $path = api_get_path(SYS_PLUGIN_PATH)."$name/resources/$name.css";
173
        if (!is_readable($path)) {
174
            return '';
175
        }
176
        $css = [];
177
        $css[] = file_get_contents($path);
178
        $result = implode($css);
179
180
        return $result;
181
    }
182
183
    /**
184
     * Returns an HTML form (generated by FormValidator) of the plugin settings
185
     * @return FormValidator FormValidator-generated form
186
     */
187
    public function getSettingsForm()
188
    {
189
        $result = new FormValidator($this->get_name());
190
191
        $defaults = [];
192
        $checkboxGroup = [];
193
        $checkboxCollection = [];
194
195
        if ($checkboxNames = array_keys($this->fields, 'checkbox')) {
196
            $pluginInfoCollection = api_get_settings('Plugins');
197
            foreach ($pluginInfoCollection as $pluginInfo) {
198
                if (array_search($pluginInfo['title'], $checkboxNames) !== false) {
199
                    $checkboxCollection[$pluginInfo['title']] = $pluginInfo;
200
                }
201
            }
202
        }
203
204
        foreach ($this->fields as $name => $type) {
205
            $options = null;
206
            if (is_array($type) && isset($type['type']) && $type['type'] === 'select') {
207
                $attributes = isset($type['attributes']) ? $type['attributes'] : [];
208
                $options = $type['options'];
209
                $type = $type['type'];
210
            }
211
212
            $value = $this->get($name);
213
            $defaults[$name] = $value;
214
            $type = isset($type) ? $type : 'text';
215
216
            $help = null;
217
            if ($this->get_lang_plugin_exists($name.'_help')) {
218
                $help = $this->get_lang($name.'_help');
219
                if ($name === "show_main_menu_tab") {
220
                    $pluginName = strtolower(str_replace('Plugin', '', get_class($this)));
221
                    $pluginUrl = api_get_path(WEB_PATH)."plugin/$pluginName/index.php";
222
                    $pluginUrl = "<a href=$pluginUrl>$pluginUrl</a>";
223
                    $help = sprintf($help, $pluginUrl);
224
                }
225
            }
226
227
            switch ($type) {
228
                case 'html':
229
                    $result->addHtml($this->get_lang($name));
230
                    break;
231
                case 'wysiwyg':
232
                    $result->addHtmlEditor($name, $this->get_lang($name), false);
233
                    break;
234
                case 'text':
235
                    $result->addElement($type, $name, [$this->get_lang($name), $help]);
236
                    break;
237
                case 'boolean':
238
                    $group = [];
239
                    $group[] = $result->createElement(
240
                        'radio',
241
                        $name,
242
                        '',
243
                        get_lang('Yes'),
244
                        'true'
245
                    );
246
                    $group[] = $result->createElement(
247
                        'radio',
248
                        $name,
249
                        '',
250
                        get_lang('No'),
251
                        'false'
252
                    );
253
                    $result->addGroup($group, null, [$this->get_lang($name), $help]);
254
                    break;
255
                case 'checkbox':
256
                    $selectedValue = null;
257
                    if (isset($checkboxCollection[$name])) {
258
                        if ($checkboxCollection[$name]['selected_value'] === 'true') {
259
                            $selectedValue = 'checked';
260
                        }
261
                    }
262
                    $element = $result->createElement(
263
                        $type,
264
                        $name,
265
                        '',
266
                        $this->get_lang($name),
267
                        $selectedValue
268
                    );
269
                    $element->_attributes['value'] = 'true';
270
                    $checkboxGroup[] = $element;
271
                    break;
272
                case 'select':
273
                    $result->addElement(
274
                        $type,
275
                        $name,
276
                        [$this->get_lang($name), $help],
277
                        $options,
278
                        $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...
279
                    );
280
                    break;
281
            }
282
        }
283
284
        if (!empty($checkboxGroup)) {
285
            $result->addGroup(
286
                $checkboxGroup,
287
                null,
288
                [$this->get_lang('sms_types'), $help]
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $help seems to be defined by a foreach iteration on line 204. Are you sure the iterator is never empty, otherwise this variable is not defined?
Loading history...
289
            );
290
        }
291
        $result->setDefaults($defaults);
292
        $result->addButtonSave($this->get_lang('Save'), 'submit_button');
293
294
        return $result;
295
    }
296
297
    /**
298
     * Returns the value of a given plugin global setting
299
     * @param string $name of the plugin
300
     *
301
     * @return string Value of the plugin
302
     */
303
    public function get($name)
304
    {
305
        $settings = $this->get_settings();
306
        foreach ($settings as $setting) {
307
            if ($setting['variable'] == $this->get_name().'_'.$name) {
308
                if (!empty($setting['selected_value']) &&
309
                    @unserialize($setting['selected_value']) !== false
310
                ) {
311
                    $setting['selected_value'] = unserialize($setting['selected_value']);
312
                }
313
314
                return $setting['selected_value'];
315
            }
316
        }
317
318
        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 string.
Loading history...
319
    }
320
321
    /**
322
     * Returns an array with the global settings for this plugin
323
     * @param bool $forceFromDB Optional. Force get settings from the database
324
     * @return array Plugin settings as an array
325
     */
326
    public function get_settings($forceFromDB = false)
327
    {
328
        if (empty($this->settings) || $forceFromDB) {
329
            $settings = api_get_settings_params(
330
                [
331
                    "subkey = ? AND category = ? AND type = ? AND access_url = ?" => [
332
                        $this->get_name(),
333
                        'Plugins',
334
                        'setting',
335
                        api_get_current_access_url_id()
336
                    ]
337
                ]
338
            );
339
            $this->settings = $settings;
340
        }
341
342
        return $this->settings;
343
    }
344
345
    /**
346
     * Tells whether language variables are defined for this plugin or not
347
     * @param string $name System name of the plugin
348
     *
349
     * @return bool True if the plugin has language variables defined, false otherwise
350
     */
351
    public function get_lang_plugin_exists($name)
352
    {
353
        return isset($this->strings[$name]);
354
    }
355
356
    /**
357
     * Hook for the get_lang() function to check for plugin-defined language terms
358
     * @param string $name of the language variable we are looking for
359
     *
360
     * @return string The translated language term of the plugin
361
     */
362
    public function get_lang($name)
363
    {
364
        // Check whether the language strings for the plugin have already been
365
        // loaded. If so, no need to load them again.
366
        if (is_null($this->strings)) {
367
            $language_interface = api_get_interface_language();
368
            $root = api_get_path(SYS_PLUGIN_PATH);
369
            $plugin_name = $this->get_name();
370
371
            $interfaceLanguageId = api_get_language_id($language_interface);
372
            if (empty($interfaceLanguageId)) {
373
                $language_interface = api_get_setting('platformLanguage');
374
                $interfaceLanguageId = api_get_language_id($language_interface);
375
            }
376
            $interfaceLanguageInfo = api_get_language_info($interfaceLanguageId);
377
            $languageParentId = !empty($interfaceLanguageInfo['parent_id']) ? (int) $interfaceLanguageInfo['parent_id'] : 0;
378
379
            // 1. Loading english if exists
380
            $english_path = $root.$plugin_name."/lang/english.php";
381
382
            if (is_readable($english_path)) {
383
                $strings = [];
384
                include $english_path;
385
                $this->strings = $strings;
386
            }
387
388
            $path = $root.$plugin_name."/lang/$language_interface.php";
389
            // 2. Loading the system language
390
            if (is_readable($path)) {
391
                include $path;
392
                if (!empty($strings)) {
393
                    foreach ($strings as $key => $string) {
394
                        $this->strings[$key] = $string;
395
                    }
396
                }
397
            } elseif ($languageParentId > 0) {
398
                $languageParentInfo = api_get_language_info($languageParentId);
399
                $languageParentFolder = $languageParentInfo['dokeos_folder'];
400
401
                $parentPath = "{$root}{$plugin_name}/lang/{$languageParentFolder}.php";
402
                if (is_readable($parentPath)) {
403
                    include $parentPath;
404
                    if (!empty($strings)) {
405
                        foreach ($strings as $key => $string) {
406
                            $this->strings[$key] = $string;
407
                        }
408
                    }
409
                }
410
            }
411
        }
412
        if (isset($this->strings[$name])) {
413
            return $this->strings[$name];
414
        }
415
416
        return get_lang($name);
417
    }
418
419
    /**
420
     * Caller for the install_course_fields() function
421
     * @param int $courseId
422
     *
423
     * @param boolean $addToolLink Whether to add a tool link on the course homepage
424
     *
425
     * @return void
426
     */
427
    public function course_install($courseId, $addToolLink = true)
428
    {
429
        $this->install_course_fields($courseId, $addToolLink);
430
    }
431
432
    /**
433
     * Add course settings and, if not asked otherwise, add a tool link on the course homepage
434
     * @param int $courseId Course integer ID
435
     * @param boolean $add_tool_link Whether to add a tool link or not
436
     * (some tools might just offer a configuration section and act on the backend)
437
     *
438
     * @return boolean|null  False on error, null otherwise
439
     */
440
    public function install_course_fields($courseId, $add_tool_link = true)
441
    {
442
        $plugin_name = $this->get_name();
443
        $t_course = Database::get_course_table(TABLE_COURSE_SETTING);
444
        $courseId = (int) $courseId;
445
446
        if (empty($courseId)) {
447
            return false;
448
        }
449
450
        // Adding course settings.
451
        if (!empty($this->course_settings)) {
452
            foreach ($this->course_settings as $setting) {
0 ignored issues
show
Bug introduced by
The expression $this->course_settings of type string is not traversable.
Loading history...
453
                $variable = $setting['name'];
454
                $value = '';
455
                if (isset($setting['init_value'])) {
456
                    $value = $setting['init_value'];
457
                }
458
459
                $type = 'textfield';
460
                if (isset($setting['type'])) {
461
                    $type = $setting['type'];
462
                }
463
464
                if (isset($setting['group'])) {
465
                    $group = $setting['group'];
466
                    $sql = "SELECT value
467
                            FROM $t_course
468
                            WHERE
469
                                c_id = $courseId AND
470
                                variable = '".Database::escape_string($group)."' AND
471
                                subkey = '".Database::escape_string($variable)."'
472
                            ";
473
                    $result = Database::query($sql);
474
                    if (!Database::num_rows($result)) {
475
                        $params = [
476
                            'c_id' => $courseId,
477
                            'variable' => $group,
478
                            'subkey' => $variable,
479
                            'value' => $value,
480
                            'category' => 'plugins',
481
                            'type' => $type,
482
                            'title' => ''
483
                        ];
484
                        Database::insert($t_course, $params);
485
                    }
486
                } else {
487
                    $sql = "SELECT value FROM $t_course
488
                            WHERE c_id = $courseId AND variable = '$variable' ";
489
                    $result = Database::query($sql);
490
                    if (!Database::num_rows($result)) {
491
                        $params = [
492
                            'c_id' => $courseId,
493
                            'variable' => $variable,
494
                            'subkey' => $plugin_name,
495
                            'value' => $value,
496
                            'category' => 'plugins',
497
                            'type' => $type,
498
                            'title' => ''
499
                        ];
500
                        Database::insert($t_course, $params);
501
                    }
502
                }
503
            }
504
        }
505
506
        // Stop here if we don't want a tool link on the course homepage
507
        if (!$add_tool_link || $this->addCourseTool == 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...
508
            return true;
509
        }
510
511
        //Add an icon in the table tool list
512
        $this->createLinkToCourseTool($plugin_name, $courseId);
513
    }
514
515
    /**
516
     * Delete the fields added to the course settings page and the link to the
517
     * tool on the course's homepage
518
     * @param int $courseId
519
     *
520
     * @return false|null
521
     */
522
    public function uninstall_course_fields($courseId)
523
    {
524
        $courseId = intval($courseId);
525
526
        if (empty($courseId)) {
527
            return false;
528
        }
529
        $pluginName = $this->get_name();
530
531
        $t_course = Database::get_course_table(TABLE_COURSE_SETTING);
532
        $t_tool = Database::get_course_table(TABLE_TOOL_LIST);
533
534
        if (!empty($this->course_settings)) {
535
            foreach ($this->course_settings as $setting) {
0 ignored issues
show
Bug introduced by
The expression $this->course_settings of type string is not traversable.
Loading history...
536
                $variable = Database::escape_string($setting['name']);
537
                if (!empty($setting['group'])) {
538
                    $variable = Database::escape_string($setting['group']);
539
                }
540
                if (empty($variable)) {
541
                    continue;
542
                }
543
                $sql = "DELETE FROM $t_course
544
                        WHERE c_id = $courseId AND variable = '$variable'";
545
                Database::query($sql);
546
            }
547
        }
548
549
        $pluginName = Database::escape_string($pluginName);
550
        $sql = "DELETE FROM $t_tool
551
                WHERE c_id = $courseId AND 
552
                (
553
                  name = '$pluginName' OR
554
                  name = '$pluginName:student' OR
555
                  name = '$pluginName:teacher'  
556
                )";
557
        Database::query($sql);
558
    }
559
560
    /**
561
     * Add an link for a course tool
562
     * @param string $name The tool name
563
     * @param int $courseId The course ID
564
     * @param string $iconName Optional. Icon file name
565
     * @param string $link Optional. Link URL
566
     * @return CTool|null
567
     */
568
    protected function createLinkToCourseTool(
569
        $name,
570
        $courseId,
571
        $iconName = null,
572
        $link = null
573
    ) {
574
        if (!$this->addCourseTool) {
575
            return null;
576
        }
577
578
        $visibility = $this->getToolIconVisibility();
579
580
        $em = Database::getManager();
581
582
        /** @var CTool $tool */
583
        $tool = $em
584
            ->getRepository('ChamiloCourseBundle:CTool')
585
            ->findOneBy([
586
                'name' => $name,
587
                'cId' => $courseId
588
            ]);
589
590
        if (!$tool) {
591
            $cToolId = AddCourse::generateToolId($courseId);
592
            $pluginName = $this->get_name();
593
594
            $tool = new CTool();
595
            $tool
596
                ->setId($cToolId)
597
                ->setCId($courseId)
598
                ->setName($name.$visibility)
599
                ->setLink($link ?: "$pluginName/start.php")
600
                ->setImage($iconName ?: "$pluginName.png")
601
                ->setVisibility(true)
602
                ->setAdmin(0)
603
                ->setAddress('squaregrey.gif')
604
                ->setAddedTool(false)
605
                ->setTarget('_self')
606
                ->setCategory('plugin')
607
                ->setSessionId(0);
608
609
            $em->persist($tool);
610
            $em->flush();
611
        }
612
613
        return $tool;
614
    }
615
616
    /**
617
     * Install the course fields and tool link of this plugin in all courses
618
     * @param boolean $add_tool_link Whether we want to add a plugin link on the course homepage
619
     *
620
     * @return void
621
     */
622
    public function install_course_fields_in_all_courses($add_tool_link = true)
623
    {
624
        // Update existing courses to add plugin settings
625
        $t_courses = Database::get_main_table(TABLE_MAIN_COURSE);
626
        $sql = "SELECT id FROM $t_courses ORDER BY id";
627
        $res = Database::query($sql);
628
        while ($row = Database::fetch_assoc($res)) {
629
            $this->install_course_fields($row['id'], $add_tool_link);
630
        }
631
    }
632
633
    /**
634
     * Uninstall the plugin settings fields from all courses
635
     * @return void
636
     */
637
    public function uninstall_course_fields_in_all_courses()
638
    {
639
        // Update existing courses to add conference settings
640
        $t_courses = Database::get_main_table(TABLE_MAIN_COURSE);
641
        $sql = "SELECT id FROM $t_courses
642
                ORDER BY id";
643
        $res = Database::query($sql);
644
        while ($row = Database::fetch_assoc($res)) {
645
            $this->uninstall_course_fields($row['id']);
646
        }
647
    }
648
649
    /**
650
     * @return array
651
     */
652
    public function getCourseSettings()
653
    {
654
        $settings = [];
655
        if (is_array($this->course_settings)) {
656
            foreach ($this->course_settings as $item) {
657
                if (isset($item['group'])) {
658
                    if (!in_array($item['group'], $settings)) {
659
                        $settings[] = $item['group'];
660
                    }
661
                } else {
662
                    $settings[] = $item['name'];
663
                }
664
            }
665
        }
666
667
        return $settings;
668
    }
669
670
    /**
671
     * Method to be extended when changing the setting in the course
672
     * configuration should trigger the use of a callback method
673
     * @param array $values sent back from the course configuration script
674
     *
675
     */
676
    public function course_settings_updated($values = [])
0 ignored issues
show
Unused Code introduced by
The parameter $values is not used and could be removed. ( Ignorable by Annotation )

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

676
    public function course_settings_updated(/** @scrutinizer ignore-unused */ $values = [])

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
677
    {
678
    }
679
680
    /**
681
     * Add a tab to platform
682
     * @param string $tabName
683
     * @param string $url
684
     * @param string $userFilter Optional. Filter tab type
685
     * @return false|string
686
     */
687
    public function addTab($tabName, $url, $userFilter = null)
688
    {
689
        $sql = "SELECT * FROM settings_current
690
                WHERE
691
                    variable = 'show_tabs' AND
692
                    subkey LIKE 'custom_tab_%'";
693
        $result = Database::query($sql);
694
        $customTabsNum = Database::num_rows($result);
695
696
        $tabNum = $customTabsNum + 1;
697
698
        // Avoid Tab Name Spaces
699
        $tabNameNoSpaces = preg_replace('/\s+/', '', $tabName);
700
        $subkeytext = "Tabs".$tabNameNoSpaces;
701
702
        // Check if it is already added
703
        $checkCondition = [
704
            'where' =>
705
                [
706
                    "variable = 'show_tabs' AND subkeytext = ?" => [
707
                        $subkeytext
708
                    ]
709
                ]
710
        ];
711
712
        $checkDuplicate = Database::select('*', 'settings_current', $checkCondition);
713
        if (!empty($checkDuplicate)) {
714
            return false;
715
        }
716
717
        // End Check
718
        $subkey = 'custom_tab_'.$tabNum;
719
720
        if (!empty($userFilter)) {
721
            switch ($userFilter) {
722
                case self::TAB_FILTER_NO_STUDENT:
723
                case self::TAB_FILTER_ONLY_STUDENT:
724
                    $subkey .= $userFilter;
725
                    break;
726
            }
727
        }
728
729
        $attributes = [
730
            'variable' => 'show_tabs',
731
            'subkey' => $subkey,
732
            'type' => 'checkbox',
733
            'category' => 'Platform',
734
            'selected_value' => 'true',
735
            'title' => $tabName,
736
            'comment' => $url,
737
            'subkeytext' => $subkeytext,
738
            'access_url' => 1,
739
            'access_url_changeable' => 1,
740
            'access_url_locked' => 0
741
        ];
742
        $resp = Database::insert('settings_current', $attributes);
743
744
        // Save the id
745
        $settings = $this->get_settings();
746
        $setData = [
747
            'comment' => $subkey
748
        ];
749
        $whereCondition = [
750
            'id = ?' => key($settings)
751
        ];
752
        Database::update('settings_current', $setData, $whereCondition);
753
754
        return $resp;
755
    }
756
757
    /**
758
     * Delete a tab to chamilo's platform
759
     * @param string $key
760
     * @return boolean $resp Transaction response
761
     */
762
    public function deleteTab($key)
763
    {
764
        $table = Database::get_main_table(TABLE_MAIN_SETTINGS_CURRENT);
765
        $sql = "SELECT *
766
                FROM $table
767
                WHERE variable = 'show_tabs'
768
                AND subkey <> '$key'
769
                AND subkey like 'custom_tab_%'
770
                ";
771
        $resp = $result = Database::query($sql);
772
        $customTabsNum = Database::num_rows($result);
773
774
        if (!empty($key)) {
775
            $whereCondition = [
776
                'variable = ? AND subkey = ?' => ['show_tabs', $key]
777
            ];
778
            $resp = Database::delete('settings_current', $whereCondition);
779
780
            //if there is more than one tab
781
            //re enumerate them
782
            if (!empty($customTabsNum) && $customTabsNum > 0) {
783
                $tabs = Database::store_result($result, 'ASSOC');
784
                $i = 1;
785
                foreach ($tabs as $row) {
786
                    $newSubKey = "custom_tab_$i";
787
788
                    if (strpos($row['subkey'], self::TAB_FILTER_NO_STUDENT) !== false) {
789
                        $newSubKey .= self::TAB_FILTER_NO_STUDENT;
790
                    } elseif (strpos($row['subkey'], self::TAB_FILTER_ONLY_STUDENT) !== false) {
791
                        $newSubKey .= self::TAB_FILTER_ONLY_STUDENT;
792
                    }
793
794
                    $attributes = ['subkey' => $newSubKey];
795
                    $this->updateTab($row['subkey'], $attributes);
796
                    $i++;
797
                }
798
            }
799
        }
800
801
        return $resp;
802
    }
803
804
    /**
805
     * Update the tabs attributes
806
     * @param string $key
807
     * @param array  $attributes
808
     *
809
     * @return boolean
810
     */
811
    public function updateTab($key, $attributes)
812
    {
813
        $whereCondition = [
814
            'variable = ? AND subkey = ?' => ['show_tabs', $key]
815
        ];
816
        $resp = Database::update('settings_current', $attributes, $whereCondition);
817
818
        return $resp;
819
    }
820
821
    /**
822
     * This method shows or hides plugin's tab
823
     * @param boolean $showTab Shows or hides the main menu plugin tab
824
     * @param string $filePath Plugin starter file path
825
     */
826
    public function manageTab($showTab, $filePath = 'index.php')
827
    {
828
        $langString = str_replace('Plugin', '', get_class($this));
829
        $pluginName = strtolower($langString);
830
        $pluginUrl = 'plugin/'.$pluginName.'/'.$filePath;
831
832
        if ($showTab === 'true') {
833
            $tabAdded = $this->addTab($langString, $pluginUrl);
834
            if ($tabAdded) {
835
                // The page must be refreshed to show the recently created tab
836
                echo "<script>location.href = '".Security::remove_XSS($_SERVER['REQUEST_URI'])."';</script>";
837
            }
838
        } else {
839
            $settingsCurrentTable = Database::get_main_table(TABLE_MAIN_SETTINGS_CURRENT);
840
            $conditions = [
841
                'where' => [
842
                    "variable = 'show_tabs' AND title = ? AND comment = ? " => [
843
                        $langString,
844
                        $pluginUrl
845
                    ]
846
                ]
847
            ];
848
            $result = Database::select('subkey', $settingsCurrentTable, $conditions);
849
            if (!empty($result)) {
850
                $this->deleteTab($result[0]['subkey']);
851
            }
852
        }
853
    }
854
855
    /**
856
     * @param string $variable
857
     * @return bool
858
     */
859
    public function validateCourseSetting($variable)
0 ignored issues
show
Unused Code introduced by
The parameter $variable is not used and could be removed. ( Ignorable by Annotation )

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

859
    public function validateCourseSetting(/** @scrutinizer ignore-unused */ $variable)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
860
    {
861
        return true;
862
    }
863
864
    /**
865
     * @param string $region
866
     * @return string
867
     */
868
    public function renderRegion($region)
0 ignored issues
show
Unused Code introduced by
The parameter $region is not used and could be removed. ( Ignorable by Annotation )

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

868
    public function renderRegion(/** @scrutinizer ignore-unused */ $region)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
869
    {
870
        return '';
871
    }
872
873
    /**
874
     * Returns true if the plugin is installed, false otherwise
875
     * @return bool True if plugin is installed/enabled, false otherwise
876
     */
877
    public function isEnabled()
878
    {
879
        $settings = api_get_settings_params_simple(
880
            [
881
                "subkey = ? AND category = ? AND type = ? AND variable = 'status' " => [
882
                    $this->get_name(),
883
                    'Plugins',
884
                    'setting',
885
                ]
886
            ]
887
        );
888
        if (is_array($settings) && isset($settings['selected_value']) && $settings['selected_value'] == 'installed') {
889
            return true;
890
        }
891
        return false;
892
    }
893
894
    /**
895
     * Allow make some actions after configure the plugin parameters
896
     * This function is called from main/admin/configure_plugin.php page
897
     * when saving the plugin parameters
898
     * @return \Plugin
899
     */
900
    public function performActionsAfterConfigure()
901
    {
902
        return $this;
903
    }
904
905
    /**
906
     * This function allows to change the visibility of the icon inside a course
907
     * :student tool will be visible only for students
908
     * :teacher tool will be visible only for teachers
909
     * If nothing it's set then tool will be visible for both as a normal icon.
910
     *
911
     * @return string
912
     */
913
    public function getToolIconVisibility()
914
    {
915
        return '';
916
    }
917
918
    /**
919
     * Get the admin URL for the plugin if Plugin::isAdminPlugin is true
920
     * @return string
921
     */
922
    public function getAdminUrl()
923
    {
924
        if (!$this->isAdminPlugin) {
925
            return '';
926
        }
927
928
        $name = $this->get_name();
929
        $sysPath = api_get_path(SYS_PLUGIN_PATH).$name;
930
        $webPath = api_get_path(WEB_PLUGIN_PATH).$name;
931
932
        if (file_exists("$sysPath/admin.php")) {
933
            return "$webPath/admin.php";
934
        }
935
936
        if (file_exists("$sysPath/start.php")) {
937
            return "$webPath/start.php";
938
        }
939
940
        return '';
941
    }
942
}
943