Passed
Pull Request — master (#6270)
by
unknown
09:35
created

Plugin::getCourseSettings()   A

Complexity

Conditions 6
Paths 2

Size

Total Lines 20
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

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