See Release Notes
Long Term Support Release
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/>. 16 17 /** 18 * TinyMCE text editor integration. 19 * 20 * @package editor 21 * @subpackage tinymce 22 * @copyright 2009 Petr Skoda (http://skodak.org) 23 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 24 */ 25 26 defined('MOODLE_INTERNAL') || die(); 27 28 class tinymce_texteditor extends texteditor { 29 /** @var string active version - this is the directory name where to find tinymce code */ 30 public $version = '3.5.11'; 31 32 /** 33 * Is the current browser supported by this editor? 34 * @return bool 35 */ 36 public function supported_by_browser() { 37 // We don't support any browsers which it doesn't support. 38 return true; 39 } 40 41 /** 42 * Returns array of supported text formats. 43 * @return array 44 */ 45 public function get_supported_formats() { 46 // FORMAT_MOODLE is not supported here, sorry. 47 return array(FORMAT_HTML => FORMAT_HTML); 48 } 49 50 /** 51 * Returns text format preferred by this editor. 52 * @return int 53 */ 54 public function get_preferred_format() { 55 return FORMAT_HTML; 56 } 57 58 /** 59 * Does this editor support picking from repositories? 60 * @return bool 61 */ 62 public function supports_repositories() { 63 return true; 64 } 65 66 /** 67 * Sets up head code if necessary. 68 */ 69 public function head_setup() { 70 } 71 72 /** 73 * Use this editor for give element. 74 * 75 * @param string $elementid 76 * @param array $options 77 * @param null $fpoptions 78 */ 79 public function use_editor($elementid, array $options=null, $fpoptions=null) { 80 global $PAGE, $CFG; 81 // Note: use full moodle_url instance to prevent standard JS loader, make sure we are using https on profile page if required. 82 if ($CFG->debugdeveloper) { 83 $PAGE->requires->js(new moodle_url('/lib/editor/tinymce/tiny_mce/'.$this->version.'/tiny_mce_src.js')); 84 } else { 85 $PAGE->requires->js(new moodle_url('/lib/editor/tinymce/tiny_mce/'.$this->version.'/tiny_mce.js')); 86 } 87 $PAGE->requires->js_init_call('M.editor_tinymce.init_editor', array($elementid, $this->get_init_params($elementid, $options)), true); 88 if ($fpoptions) { 89 $PAGE->requires->js_init_call('M.editor_tinymce.init_filepicker', array($elementid, $fpoptions), true); 90 } 91 } 92 93 protected function get_init_params($elementid, array $options=null) { 94 global $CFG, $PAGE, $OUTPUT; 95 96 //TODO: we need to implement user preferences that affect the editor setup too 97 98 $directionality = get_string('thisdirection', 'langconfig'); 99 $strtime = get_string('strftimetime'); 100 $strdate = get_string('strftimedaydate'); 101 $lang = current_language(); 102 $contentcss = $PAGE->theme->editor_css_url()->out(false); 103 104 $context = empty($options['context']) ? context_system::instance() : $options['context']; 105 106 $config = get_config('editor_tinymce'); 107 if (!isset($config->disabledsubplugins)) { 108 $config->disabledsubplugins = ''; 109 } 110 111 // Remove the manage files button if requested. 112 if (isset($options['enable_filemanagement']) && !$options['enable_filemanagement']) { 113 if (!strpos($config->disabledsubplugins, 'managefiles')) { 114 $config->disabledsubplugins .= ',managefiles'; 115 } 116 } 117 118 $fontselectlist = empty($config->fontselectlist) ? '' : $config->fontselectlist; 119 120 $langrev = -1; 121 if (!empty($CFG->cachejs)) { 122 $langrev = get_string_manager()->get_revision(); 123 } 124 125 $params = array( 126 'moodle_config' => $config, 127 'mode' => "exact", 128 'elements' => $elementid, 129 'relative_urls' => false, 130 'document_base_url' => $CFG->wwwroot, 131 'moodle_plugin_base' => "$CFG->wwwroot/lib/editor/tinymce/plugins/", 132 'content_css' => $contentcss, 133 'language' => $lang, 134 'directionality' => $directionality, 135 'plugin_insertdate_dateFormat ' => $strdate, 136 'plugin_insertdate_timeFormat ' => $strtime, 137 'theme' => "advanced", 138 'skin' => "moodle", 139 'apply_source_formatting' => true, 140 'remove_script_host' => false, 141 'entity_encoding' => "raw", 142 'plugins' => 'lists,table,style,layer,advhr,advlink,emotions,inlinepopups,' . 143 'searchreplace,paste,directionality,fullscreen,nonbreaking,contextmenu,' . 144 'insertdatetime,save,iespell,preview,print,noneditable,visualchars,' . 145 'xhtmlxtras,template,pagebreak', 146 'gecko_spellcheck' => true, 147 'theme_advanced_font_sizes' => "1,2,3,4,5,6,7", 148 'theme_advanced_layout_manager' => "SimpleLayout", 149 'theme_advanced_toolbar_align' => "left", 150 'theme_advanced_fonts' => $fontselectlist, 151 'theme_advanced_resize_horizontal' => true, 152 'theme_advanced_resizing' => true, 153 'theme_advanced_resizing_min_height' => 30, 154 'min_height' => 30, 155 'theme_advanced_toolbar_location' => "top", 156 'theme_advanced_statusbar_location' => "bottom", 157 'language_load' => false, // We load all lang strings directly from Moodle. 158 'langrev' => $langrev, 159 ); 160 161 // Should we override the default toolbar layout unconditionally? 162 if (!empty($config->customtoolbar) and $customtoolbar = self::parse_toolbar_setting($config->customtoolbar)) { 163 $i = 1; 164 foreach ($customtoolbar as $line) { 165 $params['theme_advanced_buttons'.$i] = $line; 166 $i++; 167 } 168 } else { 169 // At least one line is required. 170 $params['theme_advanced_buttons1'] = ''; 171 } 172 173 if (!empty($config->customconfig)) { 174 $config->customconfig = trim($config->customconfig); 175 $decoded = json_decode($config->customconfig, true); 176 if (is_array($decoded)) { 177 foreach ($decoded as $k=>$v) { 178 $params[$k] = $v; 179 } 180 } 181 } 182 183 if (!empty($options['legacy']) or !empty($options['noclean']) or !empty($options['trusted'])) { 184 // now deal somehow with non-standard tags, people scream when we do not make moodle code xtml strict, 185 // but they scream even more when we strip all tags that are not strict :-( 186 $params['valid_elements'] = 'script[src|type],*[*]'; // for some reason the *[*] does not inlcude javascript src attribute MDL-25836 187 $params['invalid_elements'] = ''; 188 } 189 // Add unique moodle elements - unfortunately we have to decide if these are SPANs or DIVs. 190 $params['extended_valid_elements'] = 'nolink,tex,algebra,lang[lang]'; 191 $params['custom_elements'] = 'nolink,~tex,~algebra,lang'; 192 193 //Add onblur event for client side text validation 194 if (!empty($options['required'])) { 195 $params['init_instance_callback'] = 'M.editor_tinymce.onblur_event'; 196 } 197 198 // Allow plugins to adjust parameters. 199 editor_tinymce_plugin::all_update_init_params($params, $context, $options); 200 201 // Remove temporary parameters. 202 unset($params['moodle_config']); 203 204 return $params; 205 } 206 207 /** 208 * Parse the custom toolbar setting. 209 * @param string $customtoolbar 210 * @return array csv toolbar lines 211 */ 212 public static function parse_toolbar_setting($customtoolbar) { 213 $result = array(); 214 $customtoolbar = trim($customtoolbar); 215 if ($customtoolbar === '') { 216 return $result; 217 } 218 $customtoolbar = str_replace("\r", "\n", $customtoolbar); 219 $customtoolbar = strtolower($customtoolbar); 220 $i = 0; 221 foreach (explode("\n", $customtoolbar) as $line) { 222 $line = preg_replace('/[^a-z0-9_,\|\-]/', ',', $line); 223 $line = str_replace('|', ',|,', $line); 224 $line = preg_replace('/,,+/', ',', $line); 225 $line = trim($line, ',|'); 226 if ($line === '') { 227 continue; 228 } 229 if ($i == 10) { 230 // Maximum is ten lines, merge the rest to the last line. 231 $result[9] = $result[9].','.$line; 232 } else { 233 $result[] = $line; 234 $i++; 235 } 236 } 237 return $result; 238 } 239 240 /** 241 * Gets a named plugin object. Will cause fatal error if plugin doesn't 242 * exist. This is intended for use by plugin files themselves. 243 * 244 * @param string $plugin Name of plugin e.g. 'moodleemoticon' 245 * @return editor_tinymce_plugin Plugin object 246 */ 247 public function get_plugin($plugin) { 248 global $CFG; 249 return editor_tinymce_plugin::get($plugin); 250 } 251 252 /** 253 * Equivalent to tinyMCE.baseURL value available from JavaScript, 254 * always use instead of /../ when referencing tinymce core code from moodle plugins! 255 * 256 * @return moodle_url url pointing to the root of TinyMCE javascript code. 257 */ 258 public function get_tinymce_base_url() { 259 global $CFG; 260 return new moodle_url("/lib/editor/tinymce/tiny_mce/$this->version/"); 261 } 262 263 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body