MDL-55417 forms: Improve some of the new templates for form elements
[moodle.git] / lib / form / selectwithlink.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/>.
18 /**
19  * select type form element
20  *
21  * Contains HTML class for a select type element with options containing link
22  *
23  * @package   core_form
24  * @copyright 2008 Nicolas Connault <nicolasconnault@gmail.com>
25  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
26  */
28 require_once('HTML/QuickForm/select.php');
29 require_once('templatable_form_element.php');
31 /**
32  * select type form element
33  *
34  * HTML class for a select type element with options containing link
35  *
36  * @deprecated since 3.2
37  * @package   core_form
38  * @category  form
39  * @copyright 2008 Nicolas Connault <nicolasconnault@gmail.com>
40  * @license   http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
41  */
42 class MoodleQuickForm_selectwithlink extends HTML_QuickForm_select implements templatable {
44     use templatable_form_element {
45         export_for_template as export_for_template_base;
46     }
47     /** @var string html for help button, if empty then no help */
48     var $_helpbutton='';
50     /** @var bool if true label will be hidden */
51     var $_hiddenLabel=false;
53     /** @var string url to which select option will be posted */
54     var $_link=null;
56     /** @var string data which will be posted to link */
57     var $_linklabel=null;
59     /** @var string url return link */
60     var $_linkreturn=null;
62     /**
63      * constructor
64      *
65      * @param string $elementName Select name attribute
66      * @param mixed $elementLabel Label(s) for the select
67      * @param array $options Data to be used to populate options
68      * @param mixed $attributes Either a typical HTML attribute string or an associative array
69      * @param bool $linkdata data to be posted
70      */
71     public function __construct($elementName=null, $elementLabel=null, $options=null, $attributes=null, $linkdata=null) {
72         if (!empty($linkdata['link']) && !empty($linkdata['label'])) {
73             $this->_link = $linkdata['link'];
74             $this->_linklabel = $linkdata['label'];
75         }
77         if (!empty($linkdata['return'])) {
78             $this->_linkreturn = $linkdata['return'];
79         }
81         parent::__construct($elementName, $elementLabel, $options, $attributes);
83         $this->_type = 'selectwithlink';
84     }
86     /**
87      * Old syntax of class constructor. Deprecated in PHP7.
88      *
89      * @deprecated since Moodle 3.1
90      */
91     public function MoodleQuickForm_selectwithlink($elementName=null, $elementLabel=null, $options=null, $attributes=null, $linkdata=null) {
92         debugging('Use of class name as constructor is deprecated', DEBUG_DEVELOPER);
93         self::__construct($elementName, $elementLabel, $options, $attributes, $linkdata);
94     }
96     /**
97      * Sets label to be hidden
98      *
99      * @param bool $hiddenLabel sets if label should be hidden
100      */
101     function setHiddenLabel($hiddenLabel){
102         $this->_hiddenLabel = $hiddenLabel;
103     }
105     /**
106      * Returns the SELECT in HTML
107      *
108      * @return string
109      */
110     function toHtml(){
111         $retval = '';
112         if ($this->_hiddenLabel){
113             $this->_generateId();
114             $retval = '<label class="accesshide" for="'.$this->getAttribute('id').'" >'.
115                         $this->getLabel().'</label>'.parent::toHtml();
116         } else {
117              $retval = parent::toHtml();
118         }
120         if (!empty($this->_link)) {
121             if (!empty($this->_linkreturn) && is_array($this->_linkreturn)) {
122                 $appendchar = '?';
123                 if (strstr($this->_link, '?')) {
124                     $appendchar = '&amp;';
125                 }
127                 foreach ($this->_linkreturn as $key => $val) {
128                     $this->_link .= $appendchar."$key=$val";
129                     $appendchar = '&amp;';
130                 }
131             }
133             $retval .= '<a style="margin-left: 5px" href="'.$this->_link.'">'.$this->_linklabel.'</a>';
134         }
136         return $retval;
137     }
139     /**
140      * get html for help button
141      *
142      * @return string html for help button
143      */
144     function getHelpButton(){
145         return $this->_helpbutton;
146     }
148     /**
149      * Removes an OPTION from the SELECT
150      *
151      * @param string $value Value for the OPTION to remove
152      */
153     function removeOption($value)
154     {
155         $key=array_search($value, $this->_values);
156         if ($key!==FALSE and $key!==null) {
157             unset($this->_values[$key]);
158         }
159         foreach ($this->_options as $key=>$option){
160             if ($option['attr']['value']==$value){
161                 unset($this->_options[$key]);
162                 return;
163             }
164         }
165     }
167     /**
168      * Removes all OPTIONs from the SELECT
169      */
170     function removeOptions()
171     {
172         $this->_options = array();
173     }
175     /**
176      * Slightly different container template when frozen. Don't want to use a label tag
177      * with a for attribute in that case for the element label but instead use a div.
178      * Templates are defined in renderer constructor.
179      *
180      * @return string
181      */
182     function getElementTemplateType(){
183         if ($this->_flagFrozen){
184             return 'static';
185         } else {
186             return 'default';
187         }
188     }
190    /**
191     * We check the options and return only the values that _could_ have been
192     * selected. We also return a scalar value if select is not "multiple"
193     *
194     * @param array $submitValues submitted values
195     * @param bool $assoc if true the retured value is associated array
196     * @return mixed
197     */
198     function exportValue(&$submitValues, $assoc = false)
199     {
200         if (empty($this->_options)) {
201             return $this->_prepareValue(null, $assoc);
202         }
204         $value = $this->_findValue($submitValues);
205         if (is_null($value)) {
206             $value = $this->getValue();
207         }
208         $value = (array)$value;
210         $cleaned = array();
211         foreach ($value as $v) {
212             foreach ($this->_options as $option) {
213                 if ((string)$option['attr']['value'] === (string)$v) {
214                     $cleaned[] = (string)$option['attr']['value'];
215                     break;
216                 }
217             }
218         }
220         if (empty($cleaned)) {
221             return $this->_prepareValue(null, $assoc);
222         }
223         if ($this->getMultiple()) {
224             return $this->_prepareValue($cleaned, $assoc);
225         } else {
226             return $this->_prepareValue($cleaned[0], $assoc);
227         }
228     }
230     public function export_for_template(renderer_base $output) {
231         $context = $this->export_for_template_base($output);
233         $options = [];
234         foreach ($this->_options as $option) {
235             if (is_array($this->_values) && in_array( (string) $option['attr']['value'], $this->_values)) {
236                 $this->_updateAttrArray($option['attr'], ['selected' => 'selected']);
237             }
238             $o = [
239                 'text' => $option['text'],
240                 'value' => $option['attr']['value'],
241                 'selected' => !empty($option['attr']['selected'])
242             ];
243             $options[] = $o;
244         }
245         $context['options'] = $options;
246         if (!empty($this->_link)) {
247             if (!empty($this->_linkreturn) && is_array($this->_linkreturn)) {
248                 $appendchar = '?';
249                 if (strstr($this->_link, '?')) {
250                     $appendchar = '&amp;';
251                 }
253                 foreach ($this->_linkreturn as $key => $val) {
254                     $this->_link .= $appendchar."$key=$val";
255                     $appendchar = '&amp;';
256                 }
257             }
258         }
259         $context['link'] = $this->_link;
260         $context['linklabel'] = $this->_linklabel;
262         return $context;
263     }