2 // This file is part of Moodle - http://moodle.org/
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.
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.
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/>.
19 * Tag autocomplete field.
21 * Contains HTML class for editing tags, both standard and not.
24 * @copyright 2009 Tim Hunt
25 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
29 require_once($CFG->libdir
. '/form/autocomplete.php');
32 * Form field type for editing tags.
34 * HTML class for editing tags, both standard and not.
37 * @copyright 2009 Tim Hunt
38 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
40 class MoodleQuickForm_tags
extends MoodleQuickForm_autocomplete
{
42 * Inidcates that the user should be the usual interface, with the official
43 * tags listed seprately, and a text box where they can type anything.
44 * @deprecated since 3.1
47 const DEFAULTUI
= 'defaultui';
50 * Indicates that the user should only be allowed to select official tags.
51 * @deprecated since 3.1
54 const ONLYOFFICIAL
= 'onlyofficial';
57 * Indicates that the user should just be given a text box to type in (they
58 * can still type official tags though.
59 * @deprecated since 3.1
62 const NOOFFICIAL
= 'noofficial';
65 * @var boolean $showstandard Standard tags suggested? (if not, then don't show link to manage standard tags).
67 protected $showstandard = false;
70 * Options passed when creating an element.
73 protected $tagsoptions = array();
78 * @param string $elementName Element name
79 * @param mixed $elementLabel Label(s) for an element
80 * @param array $options Options to control the element's display
81 * @param mixed $attributes Either a typical HTML attribute string or an associative array.
83 public function __construct($elementName = null, $elementLabel = null, $options = array(), $attributes = null) {
84 $validoptions = array();
86 if (!empty($options)) {
87 // Only execute it when the element was created and $options has values set by user.
88 // In onQuickFormEvent() we make sure that $options is not empty even if developer left it empty.
89 $showstandard = core_tag_tag
::BOTH_STANDARD_AND_NOT
;
90 if (isset($options['showstandard'])) {
91 $showstandard = $options['showstandard'];
92 } else if (isset($options['display'])) {
93 debugging('Option "display" is deprecated, each tag area can be configured to show standard tags or not ' .
94 'by admin or manager. If it is necessary for the developer to override it, please use "showstandard" option',
96 if ($options['display'] === self
::NOOFFICIAL
) {
97 $showstandard = core_tag_tag
::HIDE_STANDARD
;
98 } else if ($options['display'] === self
::ONLYOFFICIAL
) {
99 $showstandard = core_tag_tag
::STANDARD_ONLY
;
101 } else if (!empty($options['component']) && !empty($options['itemtype'])) {
102 $showstandard = core_tag_area
::get_showstandard($options['component'], $options['itemtype']);
105 $this->tagsoptions
= $options;
107 $this->showstandard
= ($showstandard != core_tag_tag
::HIDE_STANDARD
);
108 if ($this->showstandard
) {
109 $validoptions = $this->load_standard_tags();
111 // Option 'tags' allows us to type new tags.
112 $attributes['tags'] = ($showstandard != core_tag_tag
::STANDARD_ONLY
);
113 $attributes['multiple'] = 'multiple';
114 $attributes['placeholder'] = get_string('entertags', 'tag');
115 $attributes['showsuggestions'] = $this->showstandard
;
119 parent
::__construct($elementName, $elementLabel, $validoptions, $attributes);
120 $this->_type
= 'tags';
124 * Called by HTML_QuickForm whenever form event is made on this element
126 * @param string $event Name of event
127 * @param mixed $arg event arguments
128 * @param object $caller calling object
131 public function onQuickFormEvent($event, $arg, &$caller) {
132 if ($event === 'createElement') {
133 if (!is_array($arg[2])) {
136 $arg[2] +
= array('itemtype' => '', 'component' => '');
138 return parent
::onQuickFormEvent($event, $arg, $caller);
142 * Checks if tagging is enabled for this itemtype
146 protected function is_tagging_enabled() {
147 if (!empty($this->tagsoptions
['itemtype']) && !empty($this->tagsoptions
['component'])) {
148 $enabled = core_tag_tag
::is_enabled($this->tagsoptions
['component'], $this->tagsoptions
['itemtype']);
149 if ($enabled === false) {
153 // Backward compatibility with code developed before Moodle 3.0 where itemtype/component were not specified.
158 * Old syntax of class constructor. Deprecated in PHP7.
160 * @deprecated since Moodle 3.1
162 public function MoodleQuickForm_tags($elementName = null, $elementLabel = null, $options = array(), $attributes = null) {
163 debugging('Use of class name as constructor is deprecated', DEBUG_DEVELOPER
);
164 self
::__construct($elementName, $elementLabel, $options, $attributes);
168 * Finds the tag collection to use for standard tag selector
172 protected function get_tag_collection() {
173 if (empty($this->tagsoptions
['tagcollid']) && (empty($this->tagsoptions
['itemtype']) ||
174 empty($this->tagsoptions
['component']))) {
175 debugging('You need to specify \'itemtype\' and \'component\' of the tagged '
176 . 'area in the tags form element options',
179 if (!empty($this->tagsoptions
['tagcollid'])) {
180 return $this->tagsoptions
['tagcollid'];
182 if ($this->tagsoptions
['itemtype']) {
183 $this->tagsoptions
['tagcollid'] = core_tag_area
::get_collection($this->tagsoptions
['component'],
184 $this->tagsoptions
['itemtype']);
186 $this->tagsoptions
['tagcollid'] = core_tag_collection
::get_default();
188 return $this->tagsoptions
['tagcollid'];
192 * Returns HTML for select form element.
200 if (has_capability('moodle/tag:manage', context_system
::instance()) && $this->showstandard
) {
201 $url = new moodle_url('/tag/manage.php', array('tc' => $this->get_tag_collection()));
202 $managelink = ' ' . $OUTPUT->action_link($url, get_string('managestandardtags', 'tag'));
205 return parent
::toHTML() . $managelink;
211 * @param HTML_QuickForm_Renderer $renderer An HTML_QuickForm_Renderer object
212 * @param bool $required Whether a group is required
213 * @param string $error An error message associated with a group
215 public function accept(&$renderer, $required = false, $error = null) {
216 if ($this->is_tagging_enabled()) {
217 $renderer->renderElement($this, $required, $error);
219 $renderer->renderHidden($this);
224 * Internal function to load standard tags
226 protected function load_standard_tags() {
228 if (!$this->is_tagging_enabled()) {
231 $namefield = empty($CFG->keeptagnamecase
) ?
'name' : 'rawname';
232 $tags = $DB->get_records_menu('tag',
233 array('isstandard' => 1, 'tagcollid' => $this->get_tag_collection()),
234 $namefield, 'id,' . $namefield);
235 return array_combine($tags, $tags);
239 * Returns a 'safe' element's value
241 * @param array $submitValues array of submitted values to search
242 * @param bool $assoc whether to return the value as associative array
245 public function exportValue(&$submitValues, $assoc = false) {
246 if (!$this->is_tagging_enabled()) {
247 return $this->_prepareValue([], $assoc);
249 if ($this->_findValue($submitValues) === '_qf__force_multiselect_submission') {
250 // Nothing was selected.
251 return $this->_prepareValue([], $assoc);
254 return parent
::exportValue($submitValues, $assoc);
257 public function export_for_template(renderer_base
$output) {
259 $context = parent
::export_for_template($output);
260 if (has_capability('moodle/tag:manage', context_system
::instance()) && $this->showstandard
) {
261 $url = new moodle_url('/tag/manage.php', array('tc' => $this->get_tag_collection()));
262 $context['managestandardtagsurl'] = $url->out(false);
264 $context['nameraw'] = $this->getName();