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

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

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