MDL-55127 mod_data: Search entries fixes
[moodle.git] / mod / data / field / multimenu / field.class.php
1 <?php
2 ///////////////////////////////////////////////////////////////////////////
3 //                                                                       //
4 // NOTICE OF COPYRIGHT                                                   //
5 //                                                                       //
6 // Moodle - Modular Object-Oriented Dynamic Learning Environment         //
7 //          http://moodle.org                                            //
8 //                                                                       //
9 // Copyright (C) 1999-onwards Moodle Pty Ltd  http://moodle.com          //
10 //                                                                       //
11 // This program is free software; you can redistribute it and/or modify  //
12 // it under the terms of the GNU General Public License as published by  //
13 // the Free Software Foundation; either version 2 of the License, or     //
14 // (at your option) any later version.                                   //
15 //                                                                       //
16 // This program is distributed in the hope that it will be useful,       //
17 // but WITHOUT ANY WARRANTY; without even the implied warranty of        //
18 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         //
19 // GNU General Public License for more details:                          //
20 //                                                                       //
21 //          http://www.gnu.org/copyleft/gpl.html                         //
22 //                                                                       //
23 ///////////////////////////////////////////////////////////////////////////
25 class data_field_multimenu extends data_field_base {
27     var $type = 'multimenu';
28     /**
29      * priority for globalsearch indexing
30      *
31      * @var int
32      * */
33     protected static $priority = self::LOW_PRIORITY;
35     function display_add_field($recordid = 0, $formdata = null) {
36         global $DB, $OUTPUT;
38         if ($formdata) {
39             $fieldname = 'field_' . $this->field->id;
40             if (isset($formdata->$fieldname)) {
41                 $content = $formdata->$fieldname;
42             } else {
43                 $content = array();
44             }
45         } else if ($recordid) {
46             $content = $DB->get_field('data_content', 'content', array('fieldid'=>$this->field->id, 'recordid'=>$recordid));
47             $content = explode('##', $content);
48         } else {
49             $content = array();
50         }
52         $str = '<div title="'.s($this->field->description).'">';
53         $str .= '<input name="field_' . $this->field->id . '[xxx]" type="hidden" value="xxx"/>'; // hidden field - needed for empty selection
55         $str .= '<label for="field_' . $this->field->id . '">';
56         $str .= html_writer::span($this->field->name, 'accesshide');
57         if ($this->field->required) {
58             $str .= '<div class="inline-req">';
59             $str .= html_writer::img($OUTPUT->pix_url('req'), get_string('requiredelement', 'form'),
60                                      array('class' => 'req', 'title' => get_string('requiredelement', 'form')));
61             $str .= '</div>';
62         }
63         $str .= '</label>';
64         $str .= '<select name="field_' . $this->field->id . '[]" id="field_' . $this->field->id . '"';
65         $str .= ' multiple="multiple" class="mod-data-input">';
67         foreach (explode("\n", $this->field->param1) as $option) {
68             $option = trim($option);
69             $str .= '<option value="' . s($option) . '"';
71             if (in_array($option, $content)) {
72                 // Selected by user.
73                 $str .= ' selected = "selected"';
74             }
76             $str .= '>';
77             $str .= $option . '</option>';
78         }
79         $str .= '</select>';
80         $str .= '</div>';
82         return $str;
83     }
85     function display_search_field($value = '') {
86         global $CFG, $DB;
88         if (is_array($value)){
89             $content     = $value['selected'];
90             $allrequired = $value['allrequired'] ? true : false;
91         } else {
92             $content     = array();
93             $allrequired = false;
94         }
96         static $c = 0;
98         $str = '<label class="accesshide" for="f_' . $this->field->id . '">' . $this->field->name . '</label>';
99         $str .= '<select id="f_'.$this->field->id.'" name="f_'.$this->field->id.'[]" multiple="multiple">';
101         // display only used options
102         $varcharcontent =  $DB->sql_compare_text('content', 255);
103         $sql = "SELECT DISTINCT $varcharcontent AS content
104                   FROM {data_content}
105                  WHERE fieldid=? AND content IS NOT NULL";
107         $usedoptions = array();
108         if ($used = $DB->get_records_sql($sql, array($this->field->id))) {
109             foreach ($used as $data) {
110                 $valuestr = $data->content;
111                 if ($valuestr === '') {
112                     continue;
113                 }
114                 $values = explode('##', $valuestr);
115                 foreach ($values as $value) {
116                     $usedoptions[$value] = $value;
117                 }
118             }
119         }
121         $found = false;
122         foreach (explode("\n",$this->field->param1) as $option) {
123             $option = trim($option);
124             if (!isset($usedoptions[$option])) {
125                 continue;
126             }
127             $found = true;
128             $str .= '<option value="' . s($option) . '"';
130             if (in_array($option, $content)) {
131                 // Selected by user.
132                 $str .= ' selected = "selected"';
133             }
134             $str .= '>' . $option . '</option>';
135         }
136         if (!$found) {
137             // oh, nothing to search for
138             return '';
139         }
141         $str .= '</select>';
143         $str .= html_writer::checkbox('f_'.$this->field->id.'_allreq', null, $allrequired, get_string('selectedrequired', 'data'));
145         return $str;
147     }
149     function parse_search_field() {
150         $selected    = optional_param_array('f_'.$this->field->id, array(), PARAM_NOTAGS);
151         $allrequired = optional_param('f_'.$this->field->id.'_allreq', 0, PARAM_BOOL);
152         if (empty($selected)) {
153             // no searching
154             return '';
155         }
156         return array('selected'=>$selected, 'allrequired'=>$allrequired);
157     }
159     function generate_sql($tablealias, $value) {
160         global $DB;
162         static $i=0;
163         $i++;
164         $name = "df_multimenu_{$i}_";
165         $params = array();
166         $varcharcontent = $DB->sql_compare_text("{$tablealias}.content", 255);
168         $allrequired = $value['allrequired'];
169         $selected    = $value['selected'];
171         if ($selected) {
172             $conditions = array();
173             $j=0;
174             foreach ($selected as $sel) {
175                 $j++;
176                 $xname = $name.$j;
177                 $likesel = str_replace('%', '\%', $sel);
178                 $likeselsel = str_replace('_', '\_', $likesel);
179                 $conditions[] = "({$tablealias}.fieldid = {$this->field->id} AND ({$varcharcontent} = :{$xname}a
180                                                                                OR {$tablealias}.content LIKE :{$xname}b
181                                                                                OR {$tablealias}.content LIKE :{$xname}c
182                                                                                OR {$tablealias}.content LIKE :{$xname}d))";
183                 $params[$xname.'a'] = $sel;
184                 $params[$xname.'b'] = "$likesel##%";
185                 $params[$xname.'c'] = "%##$likesel";
186                 $params[$xname.'d'] = "%##$likesel##%";
187             }
188             if ($allrequired) {
189                 return array(" (".implode(" AND ", $conditions).") ", $params);
190             } else {
191                 return array(" (".implode(" OR ", $conditions).") ", $params);
192             }
193         } else {
194             return array(" ", array());
195         }
196     }
198     function update_content($recordid, $value, $name='') {
199         global $DB;
201         $content = new stdClass();
202         $content->fieldid  = $this->field->id;
203         $content->recordid = $recordid;
204         $content->content  = $this->format_data_field_multimenu_content($value);
206         if ($oldcontent = $DB->get_record('data_content', array('fieldid'=>$this->field->id, 'recordid'=>$recordid))) {
207             $content->id = $oldcontent->id;
208             return $DB->update_record('data_content', $content);
209         } else {
210             return $DB->insert_record('data_content', $content);
211         }
212     }
214     function format_data_field_multimenu_content($content) {
215         if (!is_array($content)) {
216             return NULL;
217         }
218         $options = explode("\n", $this->field->param1);
219         $options = array_map('trim', $options);
221         $vals = array();
222         foreach ($content as $key=>$val) {
223             if ($key === 'xxx') {
224                 continue;
225             }
226             if (!in_array($val, $options)) {
227                 continue;
228             }
229             $vals[] = $val;
230         }
232         if (empty($vals)) {
233             return NULL;
234         }
236         return implode('##', $vals);
237     }
240     function display_browse_field($recordid, $template) {
241         global $DB;
243         if ($content = $DB->get_record('data_content', array('fieldid'=>$this->field->id, 'recordid'=>$recordid))) {
244             if (strval($content->content) === '') {
245                 return false;
246             }
248             $options = explode("\n",$this->field->param1);
249             $options = array_map('trim', $options);
251             $contentArr = explode('##', $content->content);
252             $str = '';
253             foreach ($contentArr as $line) {
254                 if (!in_array($line, $options)) {
255                     // hmm, looks like somebody edited the field definition
256                     continue;
257                 }
258                 $str .= $line . "<br />\n";
259             }
260             return $str;
261         }
262         return false;
263     }
265     /**
266      * Check if a field from an add form is empty
267      *
268      * @param mixed $value
269      * @param mixed $name
270      * @return bool
271      */
272     function notemptyfield($value, $name) {
273         unset($value['xxx']);
274         return !empty($value);
275     }
277     /**
278      * Returns the presentable string value for a field content.
279      *
280      * The returned string should be plain text.
281      *
282      * @param stdClass $content
283      * @return string
284      */
285     public static function get_content_value($content) {
286         $arr = explode('##', $content->content);
288         $strvalue = '';
289         foreach ($arr as $a) {
290             $strvalue .= $a . ' ';
291         }
293         return trim($strvalue, "\r\n ");
294     }