Commit | Line | Data |
---|---|---|
ae4a98a1 | 1 | <?php |
6c1fd304 RT |
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/>. | |
16 | ||
17 | ||
18 | /** | |
19 | * Editor input element | |
20 | * | |
21 | * Contains class to create preffered editor form element | |
22 | * | |
23 | * @package core_form | |
24 | * @copyright 2009 Petr Skoda {@link http://skodak.org} | |
25 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later | |
26 | */ | |
ae4a98a1 | 27 | |
28 | global $CFG; | |
cefe1408 | 29 | |
30 | require_once('HTML/QuickForm/element.php'); | |
ae4a98a1 | 31 | require_once($CFG->dirroot.'/lib/filelib.php'); |
ad362539 | 32 | require_once($CFG->dirroot.'/repository/lib.php'); |
cefe1408 | 33 | |
6c1fd304 RT |
34 | /** |
35 | * Editor element | |
36 | * | |
58b7d48f | 37 | * It creates preffered editor (textbox/TinyMce) form element for the format (Text/HTML) selected. |
6c1fd304 RT |
38 | * |
39 | * @package core_form | |
40 | * @category form | |
41 | * @copyright 2009 Petr Skoda {@link http://skodak.org} | |
42 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later | |
43 | * @todo MDL-29421 element Freezing | |
44 | * @todo MDL-29426 ajax format conversion | |
45 | */ | |
cefe1408 | 46 | class MoodleQuickForm_editor extends HTML_QuickForm_element { |
6c1fd304 | 47 | /** @var string html for help button, if empty then no help will icon will be dispalyed. */ |
12f11f23 | 48 | public $_helpbutton = ''; |
775af58f | 49 | |
6c1fd304 | 50 | /** @var string defines the type of editor */ |
775af58f | 51 | public $_type = 'editor'; |
6c1fd304 RT |
52 | |
53 | /** @var array options provided to initalize filepicker */ | |
69429650 | 54 | protected $_options = array('subdirs'=>0, 'maxbytes'=>0, 'maxfiles'=>0, 'changeformat'=>0, |
c469b396 MG |
55 | 'context'=>null, 'noclean'=>0, 'trusttext'=>0, 'return_types'=>7); |
56 | // $_options['return_types'] = FILE_INTERNAL | FILE_EXTERNAL | FILE_REFERENCE | |
6c1fd304 RT |
57 | |
58 | /** @var array values for editor */ | |
cefe1408 | 59 | protected $_values = array('text'=>null, 'format'=>null, 'itemid'=>null); |
60 | ||
6c1fd304 RT |
61 | /** |
62 | * Constructor | |
63 | * | |
64 | * @param string $elementName (optional) name of the editor | |
65 | * @param string $elementLabel (optional) editor label | |
66 | * @param array $attributes (optional) Either a typical HTML attribute string | |
67 | * or an associative array | |
68 | * @param array $options set of options to initalize filepicker | |
69 | */ | |
34d39b79 | 70 | function MoodleQuickForm_editor($elementName=null, $elementLabel=null, $attributes=null, $options=null) { |
99eaca9d | 71 | global $CFG, $PAGE; |
cefe1408 | 72 | |
73 | $options = (array)$options; | |
74 | foreach ($options as $name=>$value) { | |
75 | if (array_key_exists($name, $this->_options)) { | |
76 | $this->_options[$name] = $value; | |
0b94f320 | 77 | } |
78 | } | |
cefe1408 | 79 | if (!empty($options['maxbytes'])) { |
80 | $this->_options['maxbytes'] = get_max_upload_file_size($CFG->maxbytes, $options['maxbytes']); | |
0b94f320 | 81 | } |
69429650 | 82 | if (!$this->_options['context']) { |
a8d25955 KA |
83 | // trying to set context to the current page context to make legacy files show in filepicker (e.g. forum post) |
84 | if (!empty($PAGE->context->id)) { | |
85 | $this->_options['context'] = $PAGE->context; | |
86 | } else { | |
87 | $this->_options['context'] = context_system::instance(); | |
88 | } | |
69429650 | 89 | } |
7de5a29a | 90 | $this->_options['trusted'] = trusttext_trusted($this->_options['context']); |
cefe1408 | 91 | parent::HTML_QuickForm_element($elementName, $elementLabel, $attributes); |
ff5fe311 | 92 | |
ff5fe311 | 93 | editors_head_setup(); |
0b94f320 | 94 | } |
cefe1408 | 95 | |
6c1fd304 RT |
96 | /** |
97 | * Sets name of editor | |
98 | * | |
99 | * @param string $name name of the editor | |
100 | */ | |
cefe1408 | 101 | function setName($name) { |
102 | $this->updateAttributes(array('name'=>$name)); | |
103 | } | |
104 | ||
6c1fd304 RT |
105 | /** |
106 | * Returns name of element | |
107 | * | |
108 | * @return string | |
109 | */ | |
cefe1408 | 110 | function getName() { |
111 | return $this->getAttribute('name'); | |
112 | } | |
113 | ||
6c1fd304 RT |
114 | /** |
115 | * Updates editor values, if part of $_values | |
58b7d48f | 116 | * |
6c1fd304 RT |
117 | * @param array $values associative array of values to set |
118 | */ | |
cefe1408 | 119 | function setValue($values) { |
120 | $values = (array)$values; | |
121 | foreach ($values as $name=>$value) { | |
122 | if (array_key_exists($name, $this->_values)) { | |
123 | $this->_values[$name] = $value; | |
0b94f320 | 124 | } |
125 | } | |
0b94f320 | 126 | } |
127 | ||
6c1fd304 RT |
128 | /** |
129 | * Returns editor values | |
130 | * | |
58b7d48f | 131 | * @return array |
6c1fd304 | 132 | */ |
cefe1408 | 133 | function getValue() { |
8367651e | 134 | return $this->_values; |
cefe1408 | 135 | } |
136 | ||
6c1fd304 RT |
137 | /** |
138 | * Returns maximum file size which can be uploaded | |
139 | * | |
140 | * @return int | |
141 | */ | |
cefe1408 | 142 | function getMaxbytes() { |
143 | return $this->_options['maxbytes']; | |
144 | } | |
145 | ||
6c1fd304 RT |
146 | /** |
147 | * Sets maximum file size which can be uploaded | |
148 | * | |
149 | * @param int $maxbytes file size | |
150 | */ | |
cefe1408 | 151 | function setMaxbytes($maxbytes) { |
152 | global $CFG; | |
153 | $this->_options['maxbytes'] = get_max_upload_file_size($CFG->maxbytes, $maxbytes); | |
154 | } | |
155 | ||
6c1fd304 RT |
156 | /** |
157 | * Returns maximum number of files which can be uploaded | |
158 | * | |
159 | * @return int | |
160 | */ | |
ac025043 | 161 | function getMaxfiles() { |
162 | return $this->_options['maxfiles']; | |
163 | } | |
164 | ||
6c1fd304 RT |
165 | /** |
166 | * Sets maximum number of files which can be uploaded. | |
167 | * | |
168 | * @param int $num number of files | |
169 | */ | |
ac025043 | 170 | function setMaxfiles($num) { |
171 | $this->_options['maxfiles'] = $num; | |
172 | } | |
173 | ||
6c1fd304 RT |
174 | /** |
175 | * Returns true if subdirectoy can be created, else false | |
176 | * | |
177 | * @return bool | |
178 | */ | |
cefe1408 | 179 | function getSubdirs() { |
180 | return $this->_options['subdirs']; | |
181 | } | |
182 | ||
6c1fd304 RT |
183 | /** |
184 | * Set option to create sub directory, while uploading file | |
185 | * | |
186 | * @param bool $allow true if sub directory can be created. | |
187 | */ | |
cefe1408 | 188 | function setSubdirs($allow) { |
189 | $this->_options['subdirs'] = $allow; | |
190 | } | |
191 | ||
ab978b38 RT |
192 | /** |
193 | * Returns editor format | |
194 | * | |
195 | * @return int. | |
196 | */ | |
197 | function getFormat() { | |
198 | return $this->_values['format']; | |
199 | } | |
200 | ||
cbe20ec3 | 201 | /** |
6c1fd304 | 202 | * Checks if editor used is a required field |
cbe20ec3 | 203 | * |
6c1fd304 | 204 | * @return bool true if required field. |
cbe20ec3 | 205 | */ |
ab978b38 RT |
206 | function isRequired() { |
207 | return (isset($this->_options['required']) && $this->_options['required']); | |
cbe20ec3 RT |
208 | } |
209 | ||
6c1fd304 RT |
210 | /** |
211 | * Sets help button for editor | |
58b7d48f | 212 | * |
6c1fd304 RT |
213 | * @param mixed $_helpbuttonargs arguments to create help button |
214 | * @param string $function name of the callback function | |
215 | * @deprecated since Moodle 2.0. Please do not call this function any more. | |
c277b502 | 216 | * @todo MDL-34508 this api will be removed. |
42b60b27 | 217 | * @see MoodleQuickForm::addHelpButton() |
6c1fd304 | 218 | */ |
cefe1408 | 219 | function setHelpButton($_helpbuttonargs, $function='_helpbutton') { |
c277b502 | 220 | debugging('setHelpButton() is deprecated, please use $mform->addHelpButton() instead'); |
cefe1408 | 221 | if (!is_array($_helpbuttonargs)) { |
222 | $_helpbuttonargs = array($_helpbuttonargs); | |
223 | } else { | |
224 | $_helpbuttonargs = $_helpbuttonargs; | |
225 | } | |
226 | //we do this to to return html instead of printing it | |
227 | //without having to specify it in every call to make a button. | |
228 | if ('_helpbutton' == $function){ | |
229 | $defaultargs = array('', '', 'moodle', true, false, '', true); | |
230 | $_helpbuttonargs = $_helpbuttonargs + $defaultargs ; | |
231 | } | |
232 | $this->_helpbutton=call_user_func_array($function, $_helpbuttonargs); | |
233 | } | |
234 | ||
6c1fd304 RT |
235 | /** |
236 | * Returns html for help button. | |
237 | * | |
238 | * @return string html for help button | |
239 | */ | |
cefe1408 | 240 | function getHelpButton() { |
241 | return $this->_helpbutton; | |
242 | } | |
243 | ||
6c1fd304 RT |
244 | /** |
245 | * Returns type of editor element | |
246 | * | |
247 | * @return string | |
248 | */ | |
cefe1408 | 249 | function getElementTemplateType() { |
250 | if ($this->_flagFrozen){ | |
251 | return 'nodisplay'; | |
252 | } else { | |
253 | return 'default'; | |
254 | } | |
255 | } | |
256 | ||
6c1fd304 RT |
257 | /** |
258 | * Returns HTML for editor form element. | |
259 | * | |
260 | * @return string | |
261 | */ | |
cefe1408 | 262 | function toHtml() { |
057815f3 | 263 | global $CFG, $PAGE; |
99eaca9d | 264 | require_once($CFG->dirroot.'/repository/lib.php'); |
cefe1408 | 265 | |
0b94f320 | 266 | if ($this->_flagFrozen) { |
267 | return $this->getFrozenHtml(); | |
cefe1408 | 268 | } |
269 | ||
4c508047 PS |
270 | $ctx = $this->_options['context']; |
271 | ||
cefe1408 | 272 | $id = $this->_attributes['id']; |
273 | $elname = $this->_attributes['name']; | |
274 | ||
275 | $subdirs = $this->_options['subdirs']; | |
276 | $maxbytes = $this->_options['maxbytes']; | |
ac025043 | 277 | $maxfiles = $this->_options['maxfiles']; |
cefe1408 | 278 | $changeformat = $this->_options['changeformat']; // TO DO: implement as ajax calls |
279 | ||
280 | $text = $this->_values['text']; | |
281 | $format = $this->_values['format']; | |
7cdee748 | 282 | $draftitemid = $this->_values['itemid']; |
cefe1408 | 283 | |
284 | // security - never ever allow guest/not logged in user to upload anything | |
285 | if (isguestuser() or !isloggedin()) { | |
ac025043 | 286 | $maxfiles = 0; |
cefe1408 | 287 | } |
288 | ||
289 | $str = $this->_getTabs(); | |
290 | $str .= '<div>'; | |
291 | ||
20e5da7d | 292 | $editor = editors_get_preferred_editor($format); |
5ca3c838 | 293 | $strformats = format_text_menu(); |
294 | $formats = $editor->get_supported_formats(); | |
295 | foreach ($formats as $fid) { | |
296 | $formats[$fid] = $strformats[$fid]; | |
cefe1408 | 297 | } |
298 | ||
4c508047 | 299 | // get filepicker info |
875f4e7b DC |
300 | // |
301 | $fpoptions = array(); | |
4c508047 PS |
302 | if ($maxfiles != 0 ) { |
303 | if (empty($draftitemid)) { | |
304 | // no existing area info provided - let's use fresh new draft area | |
305 | require_once("$CFG->libdir/filelib.php"); | |
306 | $this->setValue(array('itemid'=>file_get_unused_draft_itemid())); | |
307 | $draftitemid = $this->_values['itemid']; | |
308 | } | |
309 | ||
6bdfef5d | 310 | $args = new stdClass(); |
4c508047 | 311 | // need these three to filter repositories list |
ae7f35b9 | 312 | $args->accepted_types = array('web_image'); |
c469b396 | 313 | $args->return_types = $this->_options['return_types']; |
4c508047 PS |
314 | $args->context = $ctx; |
315 | $args->env = 'filepicker'; | |
a4d91438 | 316 | // advimage plugin |
875f4e7b | 317 | $image_options = initialise_filepicker($args); |
766514a0 DC |
318 | $image_options->context = $ctx; |
319 | $image_options->client_id = uniqid(); | |
320 | $image_options->maxbytes = $this->_options['maxbytes']; | |
321 | $image_options->env = 'editor'; | |
322 | $image_options->itemid = $draftitemid; | |
875f4e7b | 323 | |
a4d91438 | 324 | // moodlemedia plugin |
033aad78 | 325 | $args->accepted_types = array('video', 'audio'); |
775af58f | 326 | $media_options = initialise_filepicker($args); |
be85f7ab | 327 | $media_options->context = $ctx; |
875f4e7b | 328 | $media_options->client_id = uniqid(); |
875f4e7b | 329 | $media_options->maxbytes = $this->_options['maxbytes']; |
875f4e7b | 330 | $media_options->env = 'editor'; |
875f4e7b | 331 | $media_options->itemid = $draftitemid; |
766514a0 | 332 | |
a4d91438 | 333 | // advlink plugin |
766514a0 DC |
334 | $args->accepted_types = '*'; |
335 | $link_options = initialise_filepicker($args); | |
336 | $link_options->context = $ctx; | |
337 | $link_options->client_id = uniqid(); | |
338 | $link_options->maxbytes = $this->_options['maxbytes']; | |
339 | $link_options->env = 'editor'; | |
340 | $link_options->itemid = $draftitemid; | |
341 | ||
875f4e7b DC |
342 | $fpoptions['image'] = $image_options; |
343 | $fpoptions['media'] = $media_options; | |
766514a0 | 344 | $fpoptions['link'] = $link_options; |
4c508047 PS |
345 | } |
346 | ||
cbe20ec3 RT |
347 | //If editor is required and tinymce, then set required_tinymce option to initalize tinymce validation. |
348 | if (($editor instanceof tinymce_texteditor) && !is_null($this->getAttribute('onchange'))) { | |
ab978b38 | 349 | $this->_options['required'] = true; |
cbe20ec3 RT |
350 | } |
351 | ||
58b7d48f | 352 | // print text area - TODO: add on-the-fly switching, size configuration, etc. |
4c508047 | 353 | $editor->use_editor($id, $this->_options, $fpoptions); |
7cdee748 | 354 | |
cb2c1963 PS |
355 | $rows = empty($this->_attributes['rows']) ? 15 : $this->_attributes['rows']; |
356 | $cols = empty($this->_attributes['cols']) ? 80 : $this->_attributes['cols']; | |
357 | ||
cbe20ec3 | 358 | //Apply editor validation if required field |
56728202 AO |
359 | $editorrules = ''; |
360 | if (!is_null($this->getAttribute('onblur')) && !is_null($this->getAttribute('onchange'))) { | |
856484f9 | 361 | $editorrules = ' onblur="'.htmlspecialchars($this->getAttribute('onblur')).'" onchange="'.htmlspecialchars($this->getAttribute('onchange')).'"'; |
56728202 AO |
362 | } |
363 | $str .= '<div><textarea id="'.$id.'" name="'.$elname.'[text]" rows="'.$rows.'" cols="'.$cols.'"'.$editorrules.'>'; | |
e19dc11e | 364 | $str .= s($text); |
7cdee748 | 365 | $str .= '</textarea></div>'; |
366 | ||
cefe1408 | 367 | $str .= '<div>'; |
5a1a7112 | 368 | if (count($formats)>1) { |
ecc5cc31 RW |
369 | $str .= html_writer::label(get_string('format'), 'menu'. $elname. 'format', false, array('class' => 'accesshide')); |
370 | $str .= html_writer::select($formats, $elname.'[format]', $format, false, array('id' => 'menu'. $elname. 'format')); | |
5a1a7112 | 371 | } else { |
fabbf439 | 372 | $keys = array_keys($formats); |
ecc5cc31 | 373 | $str .= html_writer::empty_tag('input', |
fabbf439 | 374 | array('name'=>$elname.'[format]', 'type'=> 'hidden', 'value' => array_pop($keys))); |
cefe1408 | 375 | } |
376 | $str .= '</div>'; | |
377 | ||
137bbbc6 DC |
378 | // during moodle installation, user area doesn't exist |
379 | // so we need to disable filepicker here. | |
380 | if (!during_initial_install() && empty($CFG->adminsetuppending)) { | |
381 | // 0 means no files, -1 unlimited | |
382 | if ($maxfiles != 0 ) { | |
563d0417 DC |
383 | $str .= '<input type="hidden" name="'.$elname.'[itemid]" value="'.$draftitemid.'" />'; |
384 | ||
385 | // used by non js editor only | |
386 | $editorurl = new moodle_url("$CFG->wwwroot/repository/draftfiles_manager.php", array( | |
7f39d66a DC |
387 | 'action'=>'browse', |
388 | 'env'=>'editor', | |
389 | 'itemid'=>$draftitemid, | |
390 | 'subdirs'=>$subdirs, | |
391 | 'maxbytes'=>$maxbytes, | |
563d0417 | 392 | 'maxfiles'=>$maxfiles, |
7f39d66a | 393 | 'ctx_id'=>$ctx->id, |
71267723 DC |
394 | 'course'=>$PAGE->course->id, |
395 | 'sesskey'=>sesskey(), | |
7f39d66a | 396 | )); |
563d0417 | 397 | $str .= '<noscript>'; |
6ef1402e | 398 | $str .= "<div><object type='text/html' data='$editorurl' height='160' width='600' style='border:1px solid #000'></object></div>"; |
563d0417 | 399 | $str .= '</noscript>'; |
137bbbc6 | 400 | } |
0b94f320 | 401 | } |
cefe1408 | 402 | |
137bbbc6 | 403 | |
cefe1408 | 404 | $str .= '</div>'; |
405 | ||
406 | return $str; | |
407 | } | |
408 | ||
8367651e RW |
409 | /** |
410 | * What to display when element is frozen. | |
411 | * | |
412 | * @return empty string | |
413 | */ | |
414 | function getFrozenHtml() { | |
415 | ||
416 | return ''; | |
417 | } | |
67233725 | 418 | } |