Differences Between: [Versions 310 and 402] [Versions 311 and 402] [Versions 39 and 402] [Versions 400 and 402] [Versions 401 and 402]
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 // This program is distributed in the hope that it will be useful, // 16 // but WITHOUT ANY WARRANTY; without even the implied warranty of // 17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // 18 // GNU General Public License for more details: // 19 // // 20 // http://www.gnu.org/copyleft/gpl.html // 21 // // 22 /////////////////////////////////////////////////////////////////////////// 23 24 defined('MOODLE_INTERNAL') || die(); 25 26 global $CFG; 27 28 require_once($CFG->dirroot.'/lib/filelib.php'); 29 require_once($CFG->dirroot.'/repository/lib.php'); 30 31 class data_field_textarea extends data_field_base { 32 33 var $type = 'textarea'; 34 /** 35 * priority for globalsearch indexing 36 * 37 * @var int 38 */ 39 protected static $priority = self::LOW_PRIORITY; 40 41 public function supports_preview(): bool { 42 return true; 43 } 44 45 public function get_data_content_preview(int $recordid): stdClass { 46 return (object)[ 47 'id' => 0, 48 'fieldid' => $this->field->id, 49 'recordid' => $recordid, 50 'content' => get_string('sample', 'datafield_textarea'), 51 'content1' => 1, 52 'content2' => null, 53 'content3' => null, 54 'content4' => null, 55 ]; 56 } 57 58 /** 59 * Returns options for embedded files 60 * 61 * @return array 62 */ 63 private function get_options() { 64 if (!isset($this->field->param5)) { 65 $this->field->param5 = 0; 66 } 67 $options = array(); 68 $options['trusttext'] = false; 69 $options['forcehttps'] = false; 70 $options['subdirs'] = false; 71 $options['maxfiles'] = -1; 72 $options['context'] = $this->context; 73 $options['maxbytes'] = $this->field->param5; 74 $options['changeformat'] = 0; 75 $options['noclean'] = false; 76 return $options; 77 } 78 79 function display_add_field($recordid = 0, $formdata = null) { 80 global $CFG, $DB, $OUTPUT, $PAGE; 81 82 $text = ''; 83 $format = 0; 84 $str = '<div title="' . s($this->field->description) . '" class="d-inline-flex">'; 85 $str .= '<label for="field_' . $this->field->id . '">'; 86 $str .= html_writer::span($this->field->name, 'accesshide'); 87 if ($this->field->required) { 88 $image = $OUTPUT->pix_icon('req', get_string('requiredelement', 'form')); 89 $str .= html_writer::div($image, 'inline-req'); 90 } 91 $str .= '</label>'; 92 93 editors_head_setup(); 94 $options = $this->get_options(); 95 96 $itemid = $this->field->id; 97 $field = 'field_'.$itemid; 98 99 if ($formdata) { 100 $fieldname = 'field_' . $this->field->id . '_content1'; 101 if (isset($formdata->$fieldname)) { 102 $format = $formdata->$fieldname; 103 } else { 104 $format = file_get_unused_draft_itemid(); 105 } 106 $fieldname = 'field_' . $this->field->id . '_itemid'; 107 if (isset($formdata->$fieldname)) { 108 $draftitemid = clean_param($formdata->$fieldname, PARAM_INT); 109 } else { 110 $draftitemid = file_get_unused_draft_itemid(); 111 } 112 $fieldname = 'field_' . $this->field->id; 113 if (isset($formdata->$fieldname)) { 114 $text = $formdata->$fieldname; 115 } 116 } else if ($recordid && 117 $content = $DB->get_record('data_content', array('fieldid' => $this->field->id, 'recordid' => $recordid))) { 118 $format = $content->content1; 119 $text = clean_text($content->content, $format); 120 $text = file_prepare_draft_area($draftitemid, $this->context->id, 'mod_data', 'content', $content->id, $options, $text); 121 } else { 122 $draftitemid = file_get_unused_draft_itemid(); 123 $format = editors_get_preferred_format(); 124 } 125 126 // get filepicker info 127 // 128 $fpoptions = array(); 129 if ($options['maxfiles'] != 0 ) { 130 $args = new stdClass(); 131 // need these three to filter repositories list 132 $args->accepted_types = array('web_image'); 133 $args->return_types = (FILE_INTERNAL | FILE_EXTERNAL); 134 $args->context = $this->context; 135 $args->env = 'filepicker'; 136 // advimage plugin 137 $image_options = initialise_filepicker($args); 138 $image_options->context = $this->context; 139 $image_options->client_id = uniqid(); 140 $image_options->maxbytes = $options['maxbytes']; 141 $image_options->env = 'editor'; 142 $image_options->itemid = $draftitemid; 143 144 // moodlemedia plugin 145 $args->accepted_types = array('video', 'audio'); 146 $media_options = initialise_filepicker($args); 147 $media_options->context = $this->context; 148 $media_options->client_id = uniqid(); 149 $media_options->maxbytes = $options['maxbytes']; 150 $media_options->env = 'editor'; 151 $media_options->itemid = $draftitemid; 152 153 // advlink plugin 154 $args->accepted_types = '*'; 155 $link_options = initialise_filepicker($args); 156 $link_options->context = $this->context; 157 $link_options->client_id = uniqid(); 158 $link_options->maxbytes = $options['maxbytes']; 159 $link_options->env = 'editor'; 160 $link_options->itemid = $draftitemid; 161 162 // H5P plugin. 163 $args->accepted_types = ['h5p']; 164 $h5poptions = initialise_filepicker($args); 165 $h5poptions->context = $this->context; 166 $h5poptions->client_id = uniqid(); 167 $h5poptions->maxbytes = $options['maxbytes']; 168 $h5poptions->env = 'editor'; 169 $h5poptions->itemid = $draftitemid; 170 171 $fpoptions['image'] = $image_options; 172 $fpoptions['media'] = $media_options; 173 $fpoptions['link'] = $link_options; 174 $fpoptions['h5p'] = $h5poptions; 175 } 176 177 $editor = editors_get_preferred_editor($format); 178 $strformats = format_text_menu(); 179 $formats = $editor->get_supported_formats(); 180 foreach ($formats as $fid) { 181 $formats[$fid] = $strformats[$fid]; 182 } 183 $editor->set_text($text); 184 $editor->use_editor($field, $options, $fpoptions); 185 $str .= '<input type="hidden" name="'.$field.'_itemid" value="'.s($draftitemid).'" />'; 186 $str .= '<div class="mod-data-input">'; 187 $str .= '<div><textarea id="'.$field.'" name="'.$field.'" rows="'.$this->field->param3.'" class="form-control" ' . 188 'data-fieldtype="editor" ' . 189 'cols="'.$this->field->param2.'" spellcheck="true">'.s($text).'</textarea></div>'; 190 $str .= '<div><label class="accesshide" for="' . $field . '_content1">' . get_string('format') . '</label>'; 191 $str .= '<select id="' . $field . '_content1" name="'.$field.'_content1">'; 192 foreach ($formats as $key=>$desc) { 193 $selected = ($format == $key) ? 'selected="selected"' : ''; 194 $str .= '<option value="'.s($key).'" '.$selected.'>'.$desc.'</option>'; 195 } 196 $str .= '</select>'; 197 198 $str .= '</div>'; 199 $str .= '</div>'; 200 $str .= '</div>'; 201 return $str; 202 } 203 204 205 function display_search_field($value = '') { 206 return '<label class="accesshide" for="f_' . $this->field->id . '">' . $this->field->name . '</label>' . 207 '<input type="text" size="16" id="f_' . $this->field->id . '" name="f_' . $this->field->id . '" ' . 208 'value="' . s($value) . '" class="form-control"/>'; 209 } 210 211 public function parse_search_field($defaults = null) { 212 $param = 'f_'.$this->field->id; 213 if (empty($defaults[$param])) { 214 $defaults = array($param => ''); 215 } 216 return optional_param($param, $defaults[$param], PARAM_NOTAGS); 217 } 218 219 function generate_sql($tablealias, $value) { 220 global $DB; 221 222 static $i=0; 223 $i++; 224 $name = "df_textarea_$i"; 225 return array(" ({$tablealias}.fieldid = {$this->field->id} AND ".$DB->sql_like("{$tablealias}.content", ":$name", false).") ", array($name=>"%$value%")); 226 } 227 228 function print_after_form() { 229 } 230 231 232 function update_content($recordid, $value, $name='') { 233 global $DB; 234 235 $content = new stdClass(); 236 $content->fieldid = $this->field->id; 237 $content->recordid = $recordid; 238 239 $names = explode('_', $name); 240 if (!empty($names[2])) { 241 if ($names[2] == 'itemid') { 242 // the value will be retrieved by file_get_submitted_draft_itemid, do not need to save in DB 243 return true; 244 } else { 245 $content->{$names[2]} = clean_param($value, PARAM_NOTAGS); // content[1-4] 246 } 247 } else { 248 $content->content = clean_param($value, PARAM_CLEAN); 249 } 250 251 if ($oldcontent = $DB->get_record('data_content', array('fieldid'=>$this->field->id, 'recordid'=>$recordid))) { 252 $content->id = $oldcontent->id; 253 } else { 254 $content->id = $DB->insert_record('data_content', $content); 255 if (!$content->id) { 256 return false; 257 } 258 } 259 if (!empty($content->content)) { 260 $draftitemid = file_get_submitted_draft_itemid('field_'. $this->field->id. '_itemid'); 261 $options = $this->get_options(); 262 $content->content = file_save_draft_area_files($draftitemid, $this->context->id, 'mod_data', 'content', $content->id, $options, $content->content); 263 } 264 $rv = $DB->update_record('data_content', $content); 265 return $rv; 266 } 267 268 /** 269 * Display the content of the field in browse mode 270 * 271 * @param int $recordid 272 * @param object $template 273 * @return bool|string 274 */ 275 function display_browse_field($recordid, $template) { 276 $content = $this->get_data_content($recordid); 277 if (!$content || !isset($content->content)) { 278 return ''; 279 } 280 $options = new stdClass(); 281 if ($this->field->param1 == '1') { // We are autolinking this field, so disable linking within us. 282 $options->filter = false; 283 } 284 $options->para = false; 285 $str = file_rewrite_pluginfile_urls( 286 $content->content, 287 'pluginfile.php', 288 $this->context->id, 289 'mod_data', 290 'content', 291 $content->id, 292 $this->get_options() 293 ); 294 $str = format_text($str, $content->content1, $options); 295 return '<div class="data-field-html">' . $str . '</div>'; 296 } 297 298 /** 299 * Whether this module support files 300 * 301 * @param string $relativepath 302 * @return bool 303 */ 304 function file_ok($relativepath) { 305 return true; 306 } 307 308 /** 309 * Only look at the first item (second is format) 310 * 311 * @param string $value 312 * @param string $name 313 * @return bool 314 */ 315 function notemptyfield($value, $name) { 316 $names = explode('_', $name); 317 // Clean first. 318 if (count($names) == 2) { 319 // Don't assume that this is coming from a text editor with tags. 320 return strval($value) !== ''; 321 } 322 return false; 323 } 324 325 /** 326 * Returns the presentable string value for a field content. 327 * 328 * The returned string should be plain text. 329 * 330 * @param stdClass $content 331 * @return string 332 */ 333 public static function get_content_value($content) { 334 return content_to_text($content->content, $content->content1); 335 } 336 337 /** 338 * Return the plugin configs for external functions. 339 * 340 * @return array the list of config parameters 341 * @since Moodle 3.3 342 */ 343 public function get_config_for_external() { 344 // Return all the config parameters. 345 $configs = []; 346 for ($i = 1; $i <= 10; $i++) { 347 $configs["param$i"] = $this->field->{"param$i"}; 348 } 349 return $configs; 350 } 351 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body