Merge branch 'MDL-68797-master' of https://github.com/nguyenphuctien/moodle
[moodle.git] / admin / classes / local / settings / autocomplete.php
1 <?php
2 // This file is part of Moodle - http://moodle.org/
3 //
4 // Moodle is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // Moodle is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 // GNU General Public License for more details.
13 //
14 // You should have received a copy of the GNU General Public License
15 // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
17 /**
18  * Auto complete admin setting.
19  *
20  * @package    core_admin
21  * @copyright  2020 The Open University
22  * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
23  */
25 namespace core_admin\local\settings;
27 defined('MOODLE_INTERNAL') || die();
29 require_once($CFG->libdir . '/adminlib.php');
30 /**
31  * Auto complete setting class.
32  *
33  * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
34  * @copyright 2020 The Open University
35  */
36 class autocomplete extends \admin_setting_configmultiselect {
37     /** @var boolean Should we allow typing new entries to the field? */
38     protected $tags = false;
39     /** @var string Name of an AMD module to send/process ajax requests. */
40     protected $ajax = '';
41     /** @var string Placeholder text for an empty list. */
42     protected $placeholder = '';
43     /** @var bool Whether the search has to be case-sensitive. */
44     protected $casesensitive = false;
45     /** @var bool Show suggestions by default - but this can be turned off. */
46     protected $showsuggestions = true;
47     /** @var string String that is shown when there are no selections. */
48     protected $noselectionstring = '';
49     /** @var string Delimiter to store values in database. */
50     protected $delimiter = ',';
51     /** @var string Should be multiple choices? */
52     protected $multiple = true;
53     /** @var string The link to manage choices. */
54     protected $manageurl = true;
55     /** @var string The text to display in manage link. */
56     protected $managetext = true;
58     /**
59      * Constructor
60      *
61      * @param string $name unique ascii name, either 'mysetting' for settings that in config, or 'myplugin/mysetting'
62      * for ones in config_plugins.
63      * @param string $visiblename localised
64      * @param string $description long localised info
65      * @param array $defaultsetting array of selected items
66      * @param array $choices options for autocomplete field
67      * @param array $attributes settings for autocomplete field
68      */
69     public function __construct($name, $visiblename, $description, $defaultsetting, $choices, $attributes = null) {
71         if ($attributes === null) {
72             $attributes = [];
73         }
75         $this->placeholder = get_string('search');
76         $this->noselectionstring = get_string('noselection', 'form');
77         $defaultattributes = [
78                 'tags',
79                 'showsuggestions',
80                 'placeholder',
81                 'noselectionstring',
82                 'ajax',
83                 'casesensitive',
84                 'delimiter',
85                 'multiple',
86                 'manageurl',
87                 'managetext'
88         ];
90         foreach ($defaultattributes as $attributename) {
91             if (isset($attributes[$attributename])) {
92                 $this->$attributename = $attributes[$attributename];
93             }
94         }
96         parent::__construct($name, $visiblename, $description, $defaultsetting, $choices);
97     }
99     /**
100      * Returns the select setting(s)
101      *
102      * @return mixed null or array. Null if no settings else array of setting(s)
103      */
104     public function get_setting() {
105         $result = $this->config_read($this->name);
106         if (is_null($result)) {
107             return null;
108         }
109         if ($result === '') {
110             return [];
111         }
112         return explode($this->delimiter, $result);
113     }
115     /**
116      * Saves setting(s) provided through $data
117      *
118      * @param array $data
119      */
120     public function write_setting($data) {
121         if (!is_array($data)) {
122             return ''; // Ignore it.
123         }
124         if (!$this->load_choices() || empty($this->choices)) {
125             return '';
126         }
128         unset($data['xxxxx']);
130         $save = [];
131         foreach ($data as $value) {
132             if (!array_key_exists($value, $this->choices)) {
133                 continue; // Ignore it.
134             }
135             $save[] = $value;
136         }
138         return ($this->config_write($this->name, implode($this->delimiter, $save)) ? '' : get_string('errorsetting', 'admin'));
139     }
141     /**
142      * Returns XHTML autocomplete field
143      *
144      * @param array $data Array of values to select by default
145      * @param string $query
146      * @return string XHTML autocomplete field
147      */
148     public function output_html($data, $query = '') {
149         global $OUTPUT;
151         if (!$this->load_choices() or empty($this->choices)) {
152             return '';
153         }
155         $default = $this->get_defaultsetting();
156         if (empty($default)) {
157             $default = [];
158         }
160         if (is_null($data)) {
161             $data = [];
162         }
164         $context = [
165                 'id' => $this->get_id(),
166                 'name' => $this->get_full_name()
167         ];
169         $defaults = [];
170         $options = [];
171         $template = 'core_admin/local/settings/autocomplete';
173         foreach ($this->choices as $value => $name) {
174             if (in_array($value, $default)) {
175                 $defaults[] = $name;
176             }
177             $options[] = [
178                     'value' => $value,
179                     'text' => $name,
180                     'selected' => in_array($value, $data),
181                     'disabled' => false
182             ];
183         }
185         $context['options'] = $options;
186         $context['tags'] = $this->tags;
187         $context['placeholder'] = $this->placeholder;
188         $context['casesensitive'] = $this->casesensitive;
189         $context['multiple'] = $this->multiple;
190         $context['showsuggestions'] = $this->showsuggestions;
191         $context['manageurl'] = $this->manageurl;
192         $context['managetext'] = $this->managetext;
194         if (is_null($default)) {
195             $defaultinfo = null;
196         } if (!empty($defaults)) {
197             $defaultinfo = implode(', ', $defaults);
198         } else {
199             $defaultinfo = get_string('none');
200         }
202         $element = $OUTPUT->render_from_template($template, $context);
204         return format_admin_setting($this, $this->visiblename, $element, $this->description, true, '', $defaultinfo, $query);
205     }