Completed
Push — 1.10.x ( 123d3d...a32a3a )
by
unknown
52:30
created

Plugin::validateCourseSetting()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

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