See Release Notes
Long Term Support Release
Differences Between: [Versions 310 and 401] [Versions 311 and 401] [Versions 39 and 401] [Versions 400 and 401]
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 /////////////////////////////////////////////////////////////////////////// 24 25 class data_field_multimenu extends data_field_base { 26 27 var $type = 'multimenu'; 28 /** 29 * priority for globalsearch indexing 30 * 31 * @var int 32 * */ 33 protected static $priority = self::LOW_PRIORITY; 34 35 public function supports_preview(): bool { 36 return true; 37 } 38 39 public function get_data_content_preview(int $recordid): stdClass { 40 $options = explode("\n", $this->field->param1); 41 $options = array_map('trim', $options); 42 $selected = $options[$recordid % count($options)]; 43 $selected .= '##' . $options[($recordid + 1) % count($options)]; 44 return (object)[ 45 'id' => 0, 46 'fieldid' => $this->field->id, 47 'recordid' => $recordid, 48 'content' => $selected, 49 'content1' => null, 50 'content2' => null, 51 'content3' => null, 52 'content4' => null, 53 ]; 54 } 55 56 function display_add_field($recordid = 0, $formdata = null) { 57 global $DB, $OUTPUT; 58 59 if ($formdata) { 60 $fieldname = 'field_' . $this->field->id; 61 if (isset($formdata->$fieldname)) { 62 $content = $formdata->$fieldname; 63 } else { 64 $content = array(); 65 } 66 } else if ($recordid) { 67 $content = $DB->get_field('data_content', 'content', array('fieldid'=>$this->field->id, 'recordid'=>$recordid)); 68 $content = explode('##', $content); 69 } else { 70 $content = array(); 71 } 72 73 $str = '<div title="'.s($this->field->description).'">'; 74 $str .= '<input name="field_' . $this->field->id . '[xxx]" type="hidden" value="xxx"/>'; // hidden field - needed for empty selection 75 76 $str .= '<label for="field_' . $this->field->id . '">'; 77 $str .= '<legend><span class="accesshide">' . $this->field->name; 78 79 if ($this->field->required) { 80 $str .= ' ' . get_string('requiredelement', 'form') . '</span></legend>'; 81 $str .= '<div class="inline-req">'; 82 $str .= $OUTPUT->pix_icon('req', get_string('requiredelement', 'form')); 83 $str .= '</div>'; 84 } else { 85 $str .= '</span></legend>'; 86 } 87 $str .= '</label>'; 88 $str .= '<select name="field_' . $this->field->id . '[]" id="field_' . $this->field->id . '"'; 89 $str .= ' multiple="multiple" class="mod-data-input form-control">'; 90 91 foreach (explode("\n", $this->field->param1) as $option) { 92 $option = trim($option); 93 $str .= '<option value="' . s($option) . '"'; 94 95 if (in_array($option, $content)) { 96 // Selected by user. 97 $str .= ' selected = "selected"'; 98 } 99 100 $str .= '>'; 101 $str .= $option . '</option>'; 102 } 103 $str .= '</select>'; 104 $str .= '</div>'; 105 106 return $str; 107 } 108 109 function display_search_field($value = '') { 110 global $CFG, $DB; 111 112 if (is_array($value)){ 113 $content = $value['selected']; 114 $allrequired = $value['allrequired'] ? true : false; 115 } else { 116 $content = array(); 117 $allrequired = false; 118 } 119 120 static $c = 0; 121 122 $str = '<label class="accesshide" for="f_' . $this->field->id . '">' . $this->field->name . '</label>'; 123 $str .= '<select id="f_'.$this->field->id.'" name="f_'.$this->field->id.'[]" multiple="multiple" class="form-control">'; 124 125 // display only used options 126 $varcharcontent = $DB->sql_compare_text('content', 255); 127 $sql = "SELECT DISTINCT $varcharcontent AS content 128 FROM {data_content} 129 WHERE fieldid=? AND content IS NOT NULL"; 130 131 $usedoptions = array(); 132 if ($used = $DB->get_records_sql($sql, array($this->field->id))) { 133 foreach ($used as $data) { 134 $valuestr = $data->content; 135 if ($valuestr === '') { 136 continue; 137 } 138 $values = explode('##', $valuestr); 139 foreach ($values as $value) { 140 $usedoptions[$value] = $value; 141 } 142 } 143 } 144 145 $found = false; 146 foreach (explode("\n",$this->field->param1) as $option) { 147 $option = trim($option); 148 if (!isset($usedoptions[$option])) { 149 continue; 150 } 151 $found = true; 152 $str .= '<option value="' . s($option) . '"'; 153 154 if (in_array($option, $content)) { 155 // Selected by user. 156 $str .= ' selected = "selected"'; 157 } 158 $str .= '>' . $option . '</option>'; 159 } 160 if (!$found) { 161 // oh, nothing to search for 162 return ''; 163 } 164 165 $str .= '</select>'; 166 167 $str .= html_writer::checkbox('f_'.$this->field->id.'_allreq', null, $allrequired, 168 get_string('selectedrequired', 'data'), array('class' => 'mr-1')); 169 170 return $str; 171 172 } 173 174 public function parse_search_field($defaults = null) { 175 $paramselected = 'f_'.$this->field->id; 176 $paramallrequired = 'f_'.$this->field->id.'_allreq'; 177 178 if (empty($defaults[$paramselected])) { // One empty means the other ones are empty too. 179 $defaults = array($paramselected => array(), $paramallrequired => 0); 180 } 181 182 $selected = optional_param_array($paramselected, $defaults[$paramselected], PARAM_NOTAGS); 183 $allrequired = optional_param($paramallrequired, $defaults[$paramallrequired], PARAM_BOOL); 184 185 if (empty($selected)) { 186 // no searching 187 return ''; 188 } 189 return array('selected'=>$selected, 'allrequired'=>$allrequired); 190 } 191 192 function generate_sql($tablealias, $value) { 193 global $DB; 194 195 static $i=0; 196 $i++; 197 $name = "df_multimenu_{$i}_"; 198 $params = array(); 199 $varcharcontent = $DB->sql_compare_text("{$tablealias}.content", 255); 200 201 $allrequired = $value['allrequired']; 202 $selected = $value['selected']; 203 204 if ($selected) { 205 $conditions = array(); 206 $j=0; 207 foreach ($selected as $sel) { 208 $j++; 209 $xname = $name.$j; 210 $likesel = str_replace('%', '\%', $sel); 211 $likeselsel = str_replace('_', '\_', $likesel); 212 $conditions[] = "({$tablealias}.fieldid = {$this->field->id} AND ({$varcharcontent} = :{$xname}a 213 OR {$tablealias}.content LIKE :{$xname}b 214 OR {$tablealias}.content LIKE :{$xname}c 215 OR {$tablealias}.content LIKE :{$xname}d))"; 216 $params[$xname.'a'] = $sel; 217 $params[$xname.'b'] = "$likesel##%"; 218 $params[$xname.'c'] = "%##$likesel"; 219 $params[$xname.'d'] = "%##$likesel##%"; 220 } 221 if ($allrequired) { 222 return array(" (".implode(" AND ", $conditions).") ", $params); 223 } else { 224 return array(" (".implode(" OR ", $conditions).") ", $params); 225 } 226 } else { 227 return array(" ", array()); 228 } 229 } 230 231 function update_content($recordid, $value, $name='') { 232 global $DB; 233 234 $content = new stdClass(); 235 $content->fieldid = $this->field->id; 236 $content->recordid = $recordid; 237 $content->content = $this->format_data_field_multimenu_content($value); 238 239 if ($oldcontent = $DB->get_record('data_content', array('fieldid'=>$this->field->id, 'recordid'=>$recordid))) { 240 $content->id = $oldcontent->id; 241 return $DB->update_record('data_content', $content); 242 } else { 243 return $DB->insert_record('data_content', $content); 244 } 245 } 246 247 function format_data_field_multimenu_content($content) { 248 if (!is_array($content)) { 249 return NULL; 250 } 251 $options = explode("\n", $this->field->param1); 252 $options = array_map('trim', $options); 253 254 $vals = array(); 255 foreach ($content as $key=>$val) { 256 if ($key === 'xxx') { 257 continue; 258 } 259 if (!in_array($val, $options)) { 260 continue; 261 } 262 $vals[] = $val; 263 } 264 265 if (empty($vals)) { 266 return NULL; 267 } 268 269 return implode('##', $vals); 270 } 271 272 273 function display_browse_field($recordid, $template) { 274 $content = $this->get_data_content($recordid); 275 if (!$content || empty($content->content)) { 276 return ''; 277 } 278 $options = explode("\n", $this->field->param1); 279 $options = array_map('trim', $options); 280 281 $contentarray = explode('##', $content->content); 282 $str = ''; 283 foreach ($contentarray as $line) { 284 if (!in_array($line, $options)) { 285 // Hmm, looks like somebody edited the field definition. 286 continue; 287 } 288 $str .= $line . "<br />\n"; 289 } 290 return $str; 291 } 292 293 /** 294 * Check if a field from an add form is empty 295 * 296 * @param mixed $value 297 * @param mixed $name 298 * @return bool 299 */ 300 function notemptyfield($value, $name) { 301 unset($value['xxx']); 302 return !empty($value); 303 } 304 305 /** 306 * Returns the presentable string value for a field content. 307 * 308 * The returned string should be plain text. 309 * 310 * @param stdClass $content 311 * @return string 312 */ 313 public static function get_content_value($content) { 314 $arr = explode('##', $content->content); 315 316 $strvalue = ''; 317 foreach ($arr as $a) { 318 $strvalue .= $a . ' '; 319 } 320 321 return trim($strvalue, "\r\n "); 322 } 323 324 /** 325 * Return the plugin configs for external functions. 326 * 327 * @return array the list of config parameters 328 * @since Moodle 3.3 329 */ 330 public function get_config_for_external() { 331 // Return all the config parameters. 332 $configs = []; 333 for ($i = 1; $i <= 10; $i++) { 334 $configs["param$i"] = $this->field->{"param$i"}; 335 } 336 return $configs; 337 } 338 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body