| Commit | Line | Data |
|---|---|---|
| 04b827fa | 1 | <?php |
| e44c2389 | 2 | // $Id$ |
| 8de1e54a | 3 | /** |
| 0c87a920 | 4 | * FCKeditor - The text editor for Internet - http://www.fckeditor.net |
| 20c63aec | 5 | * Copyright (C) 2003-2008 Frederico Caldeira Knabben |
| ebc6fdec | 6 | * |
| 0c87a920 | 7 | * == BEGIN LICENSE == |
| 9b429add | 8 | * |
| 0c87a920 WW |
9 | * Licensed under the terms of any of the following licenses at your |
| 10 | * choice: | |
| f3d88ca0 | 11 | * |
| 0c87a920 WW |
12 | * - GNU General Public License Version 2 or later (the "GPL") |
| 13 | * http://www.gnu.org/licenses/gpl.html | |
| 9b429add | 14 | * |
| 0c87a920 WW |
15 | * - GNU Lesser General Public License Version 2.1 or later (the "LGPL") |
| 16 | * http://www.gnu.org/licenses/lgpl.html | |
| ebc6fdec | 17 | * |
| 0c87a920 WW |
18 | * - Mozilla Public License Version 1.1 or later (the "MPL") |
| 19 | * http://www.mozilla.org/MPL/MPL-1.1.html | |
| ebc6fdec | 20 | * |
| 0c87a920 | 21 | * == END LICENSE == |
| 9b429add | 22 | * |
| 0c87a920 | 23 | * @file |
| 20c63aec | 24 | * FCKeditor Module for Drupal 6.x |
| 0c87a920 WW |
25 | * |
| 26 | * This module allows Drupal to replace textarea fields with FCKeditor. | |
| 04b827fa | 27 | * |
| 0c87a920 WW |
28 | * This HTML text editor brings to the web many of the powerful functionalities |
| 29 | * of known desktop editors like Word. It's really lightweight and doesn't | |
| 30 | * require any kind of installation on the client computer. | |
| 04b827fa DS |
31 | */ |
| 32 | ||
| 0c87a920 WW |
33 | /** |
| 34 | * The name of simplified toolbar which should be forced | |
| 35 | * Be sure that this toolbar is defined in fckeditor.config.js or fckconfig.js | |
| 36 | */ | |
| 37 | define('FCKEDITOR_FORCE_SIMPLE_TOOLBAR_NAME', 'DrupalBasic') ; | |
| 04b827fa | 38 | |
| 95e32685 WW |
39 | global $_fckeditor_configuration; |
| 40 | global $_fckeditor_js_ids; | |
| c46c807b | 41 | |
| 95e32685 WW |
42 | $_fckeditor_configuration = array(); |
| 43 | $_fckeditor_js_ids = array(); | |
| c46c807b | 44 | |
| 04b827fa | 45 | /** |
| 075c1a2d | 46 | * Implementation of hook_help(). |
| af8e9eeb | 47 | * |
| 1b120ffb JS |
48 | * This function delegates execution to fckeditor_help_delegate() in fckeditor.help.inc to |
| 49 | * lower the amount of code in fckeditor.module | |
| 04b827fa | 50 | */ |
| 0c87a920 | 51 | function fckeditor_help($path, $arg) { |
| 1b120ffb JS |
52 | module_load_include('help.inc', 'fckeditor'); |
| 53 | return module_invoke('fckeditor', 'help_delegate', $path, $arg); | |
| 54 | } | |
| 0c87a920 | 55 | |
| 1b120ffb JS |
56 | /** |
| 57 | * Implementation of hook_user(). | |
| af8e9eeb | 58 | * |
| 1b120ffb JS |
59 | * This function delegates execution to fckeditor_user_delegate() in fckeditor.user.inc to |
| 60 | * lower the amount of code in fckeditor.module | |
| 61 | */ | |
| 62 | function fckeditor_user($type, $edit, &$user, $category = NULL) { | |
| 63 | if (($type == 'form' && $category == 'account' && user_access('access fckeditor')) || $type == 'validate') { | |
| 64 | module_load_include('user.inc', 'fckeditor'); | |
| 65 | return module_invoke('fckeditor', 'user_delegate', $type, $edit, $user, $category); | |
| 04b827fa | 66 | } |
| f60bb09c | 67 | return NULL; |
| 04b827fa DS |
68 | } |
| 69 | ||
| b45d1789 | 70 | /* |
| f60bb09c JS |
71 | * Run if there is old menu information in database |
| 72 | */ | |
| b45d1789 | 73 | function fckeditor_admin($arg = NULL) { |
| f1bbcab7 | 74 | drupal_set_message(t('The FCKeditor component is not installed correctly. You should run the <a href="@update-php">database update script</a> immediately.', array('@update-php' => base_path() .'update.php')), 'error'); |
| b45d1789 WW |
75 | return FALSE; |
| 76 | } | |
| 77 | ||
| 04b827fa | 78 | /** |
| 075c1a2d | 79 | * Implementation of hook_perm(). |
| 20c63aec | 80 | * Administer -> User management -> Permissions |
| 04b827fa DS |
81 | */ |
| 82 | function fckeditor_perm() { | |
| 0c87a920 | 83 | return array('administer fckeditor', 'access fckeditor', 'allow fckeditor file uploads'); |
| 04b827fa DS |
84 | } |
| 85 | ||
| 04b827fa | 86 | /** |
| 075c1a2d | 87 | * Implementation of hook_elements(). |
| 0c87a920 | 88 | * Replace textarea with FCKeditor using callback function (fckeditor_process_textarea) |
| 04b827fa | 89 | */ |
| f3d88ca0 | 90 | function fckeditor_elements() { |
| 91 | $type = array(); | |
| e794befa | 92 | $type['textfield'] = array( |
| 0c87a920 | 93 | '#process' => array( |
| 1b120ffb JS |
94 | 'fckeditor_process_input' |
| 95 | ), | |
| e794befa | 96 | ); |
| 0c87a920 | 97 | if (user_access('access fckeditor')) { |
| f3d88ca0 | 98 | // only roles with permission get the fckeditor |
| 99 | if (fckeditor_is_compatible_client()) { | |
| 100 | // it would be useless to dig deeper if we're not able or allowed to | |
| c46c807b | 101 | $type['textarea'] = array('#process' => array('fckeditor_process_textarea')); |
| da1cf0d0 | 102 | $type['form'] = array('#after_build' => array('fckeditor_process_form')); |
| 04b827fa DS |
103 | } |
| 104 | } | |
| f3d88ca0 | 105 | return $type; |
| 04b827fa DS |
106 | } |
| 107 | ||
| 0c87a920 | 108 | /** |
| c46c807b WW |
109 | * AJAX callback - XSS filter |
| 110 | */ | |
| 111 | function fckeditor_filter_xss() { | |
| 5362261b WW |
112 | $GLOBALS['devel_shutdown'] = FALSE; |
| 113 | ||
| c46c807b WW |
114 | if (!isset($_POST['text']) || !is_string($_POST['text']) || !is_array($_POST['filters'])) { |
| 115 | exit; | |
| 116 | } | |
| da1cf0d0 | 117 | |
| c46c807b WW |
118 | $text = $_POST['text']; |
| 119 | $text = strtr($text, array('<!--' => '__COMMENT__START__', '-->' => '__COMMENT__END__')); | |
| da1cf0d0 | 120 | |
| c46c807b WW |
121 | foreach ($_POST['filters'] as $module_delta) { |
| 122 | $module = strtok($module_delta, "/"); | |
| 123 | $delta = strtok("/"); | |
| 124 | $format = strtok("/"); | |
| 5362261b WW |
125 | |
| 126 | if (!module_hook($module, 'filter')) { | |
| 127 | continue; | |
| 128 | } | |
| 129 | ||
| c46c807b WW |
130 | //built-in filter module, a special case where we would like to strip XSS and nothing more |
| 131 | if ($module == 'filter' && $delta == 0) { | |
| 132 | preg_match_all("|</?([a-z][a-z0-9]*)(?:\b[^>]*)>|i", $text, $matches); | |
| 133 | if ($matches[1]) { | |
| 134 | $tags = array_unique($matches[1]); | |
| 135 | $text = filter_xss($text, $tags); | |
| 136 | } | |
| 137 | } | |
| 138 | else { | |
| 139 | $text = module_invoke($module, 'filter', 'process', $delta, $format, $text); | |
| 140 | } | |
| 141 | } | |
| da1cf0d0 | 142 | |
| c46c807b WW |
143 | $text = strtr($text, array('__COMMENT__START__' => '<!--', '__COMMENT__END__' => '-->')); |
| 144 | ||
| 145 | echo $text; | |
| 146 | exit; | |
| 147 | } | |
| 148 | ||
| 149 | function fckeditor_process_form(&$form) { | |
| 95e32685 | 150 | global $_fckeditor_configuration, $_fckeditor_js_ids; |
| c46c807b WW |
151 | static $processed_textareas = array(); |
| 152 | static $found_textareas = array(); | |
| da1cf0d0 | 153 | |
| c46c807b WW |
154 | //Skip if: |
| 155 | // - we're not editing an element | |
| 156 | // - fckeditor is not enabled (configuration is empty) | |
| 95e32685 | 157 | if (arg(1) == "add" || arg(1) == "reply" || !count($_fckeditor_configuration)) { |
| c46c807b | 158 | return $form; |
| da1cf0d0 WW |
159 | } |
| 160 | ||
| c46c807b | 161 | $fckeditor_filters = array(); |
| da1cf0d0 | 162 | |
| c46c807b WW |
163 | // Iterate over element children; resetting array keys to access last index. |
| 164 | if ($children = array_values(element_children($form))) { | |
| 165 | foreach ($children as $index => $item) { | |
| 166 | $element = &$form[$item]; | |
| 167 | ||
| 95e32685 | 168 | if (isset($element['#id']) && in_array($element['#id'], array_keys($_fckeditor_js_ids))) { |
| c46c807b WW |
169 | $found_textareas[$element['#id']] = &$element; |
| 170 | } | |
| da1cf0d0 | 171 | |
| c46c807b WW |
172 | // filter_form() always uses the key 'format'. We need a type-agnostic |
| 173 | // match to prevent false positives. Also, there must have been at least | |
| 174 | // one element on this level. | |
| 175 | if ($item === 'format' && $index > 0) { | |
| da1cf0d0 | 176 | |
| c46c807b WW |
177 | // Make sure we either match a input format selector or input format |
| 178 | // guidelines (displayed if user has access to one input format only). | |
| 179 | if ((isset($element['#type']) && $element['#type'] == 'fieldset') || isset($element['format']['guidelines'])) { | |
| 180 | // The element before this element is the target form field. | |
| 181 | $field = &$form[$children[$index - 1]]; | |
| 182 | $textarea_id = $field['#id']; | |
| 95e32685 | 183 | $js_id = $_fckeditor_js_ids[$textarea_id]; |
| da1cf0d0 | 184 | |
| c46c807b | 185 | array_push($processed_textareas, $js_id); |
| da1cf0d0 | 186 | |
| c46c807b | 187 | //search for checkxss1/2 class |
| 95e32685 | 188 | if (empty($field['#attributes']['class']) || strpos($field['#attributes']['class'], "checkxss") === FALSE) { |
| c46c807b WW |
189 | continue; |
| 190 | } | |
| 191 | ||
| 192 | // Determine the available input formats. The last child element is a | |
| 193 | // link to "More information about formatting options". When only one | |
| 194 | // input format is displayed, we also have to remove formatting | |
| 195 | // guidelines, stored in the child 'format'. | |
| da1cf0d0 WW |
196 | $formats = element_children($element); |
| 197 | ||
| c46c807b | 198 | foreach ($formats as $format_id) { |
| 91651072 | 199 | $format = !empty($element[$format_id]['#default_value']) ? $element[$format_id]['#default_value'] : $element[$format_id]['#value']; |
| c46c807b WW |
200 | break; |
| 201 | } | |
| da1cf0d0 | 202 | |
| c46c807b WW |
203 | $enabled = filter_list_format($format); |
| 204 | $fckeditor_filters = array(); | |
| da1cf0d0 | 205 | |
| c46c807b WW |
206 | //loop through all enabled filters |
| 207 | foreach ($enabled as $id => $filter) { | |
| 208 | //but use only that one selected in FCKeditor profile | |
| 01a3fbad | 209 | if (in_array($id, array_keys($_fckeditor_configuration[$textarea_id]['filters'])) && $_fckeditor_configuration[$textarea_id]['filters'][$id]) { |
| c46c807b WW |
210 | if (!isset($fckeditor_filters[$js_id])) { |
| 211 | $fckeditor_filters[$js_id] = array(); | |
| 212 | } | |
| 95e32685 | 213 | $fckeditor_filters[$js_id][] = $id ."/". $format; |
| c46c807b WW |
214 | } |
| 215 | } | |
| da1cf0d0 | 216 | |
| c46c807b WW |
217 | //No filters assigned, remove xss class |
| 218 | if (empty($fckeditor_filters[$js_id])) { | |
| 219 | $field['#attributes']['class'] = preg_replace("/checkxss(1|2)/", "", $field['#attributes']['class']); | |
| 220 | } | |
| 221 | else { | |
| 222 | $field['#attributes']['class'] = strtr($field['#attributes']['class'], array("checkxss1" => "filterxss1", "checkxss2" => "filterxss2")); | |
| 223 | } | |
| da1cf0d0 | 224 | |
| c46c807b WW |
225 | array_pop($formats); |
| 226 | unset($formats['format']); | |
| 227 | } | |
| 228 | // If this element is 'format', do not recurse further. | |
| 229 | continue; | |
| 230 | } | |
| 231 | // Recurse into children. | |
| 232 | fckeditor_process_form($element); | |
| 233 | } | |
| 234 | } | |
| da1cf0d0 | 235 | |
| c46c807b WW |
236 | //We're in a form |
| 237 | if (isset($form['#action'])) { | |
| 238 | //some textareas associated with FCKeditor has not been processed | |
| 95e32685 | 239 | if (count($processed_textareas) < count($_fckeditor_js_ids)) { |
| c46c807b | 240 | //loop through all found textfields |
| 383ecbc7 | 241 | foreach (array_keys($found_textareas) as $id) { |
| 95e32685 | 242 | $element = &$found_textareas[$id]; |
| c46c807b | 243 | //if not processed yet (checkxss class is before final processing) |
| 01a3fbad | 244 | if (strpos($element['#attributes']['class'], "checkxss") !== FALSE && !in_array($_fckeditor_js_ids[$element['#id']], $processed_textareas) && !empty($_fckeditor_configuration[$id]['filters']) && array_sum($_fckeditor_configuration[$id]['filters'])) { |
| da1cf0d0 | 245 | //assign default Filtered HTML to be safe on fields that do not have input format assigned, but only if at least one security filter is enabled in Security settings |
| 95e32685 | 246 | $js_id = $_fckeditor_js_ids[$element['#id']]; |
| c46c807b WW |
247 | $fckeditor_filters[$js_id][] = "filter/0/1"; |
| 248 | $element['#attributes']['class'] = strtr($element['#attributes']['class'], array("checkxss1" => "filterxss1", "checkxss2" => "filterxss2")); | |
| 249 | } | |
| 250 | } | |
| 251 | } | |
| 252 | } | |
| da1cf0d0 | 253 | |
| c46c807b WW |
254 | if (!empty($fckeditor_filters)) { |
| 255 | drupal_add_js(array('fckeditor_filters' => $fckeditor_filters), 'setting'); | |
| 256 | } | |
| da1cf0d0 | 257 | |
| c46c807b WW |
258 | return $form; |
| 259 | } | |
| 260 | ||
| 261 | /** | |
| 0c87a920 | 262 | * Allow more than 255 chars in Allowed HTML tags textfield |
| 0c87a920 WW |
263 | */ |
| 264 | function fckeditor_process_input($element) { | |
| 265 | if ($element['#id']=='edit-allowed-html-1') { | |
| 266 | $element['#maxlength'] = max($element['#maxlength'], 1024); | |
| 9b429add | 267 | } |
| 0c87a920 | 268 | return $element; |
| 9b429add | 269 | } |
| 270 | ||
| 0c87a920 | 271 | /** |
| f60bb09c | 272 | * Implementation of hook_menu(). |
| 0c87a920 WW |
273 | */ |
| 274 | function fckeditor_menu() { | |
| 0c87a920 | 275 | $items = array(); |
| ebc6fdec | 276 | |
| c46c807b WW |
277 | $items['fckeditor/xss'] = array( |
| 278 | 'title' => 'XSS Filter', | |
| 279 | 'description' => 'XSS Filter.', | |
| 280 | 'page callback' => 'fckeditor_filter_xss', | |
| 281 | 'access arguments' => array('access fckeditor'), | |
| 282 | 'type' => MENU_CALLBACK, | |
| 283 | ); | |
| da1cf0d0 | 284 | |
| 0c87a920 | 285 | $items['admin/settings/fckeditor'] = array( |
| 201b993d | 286 | 'title' => 'FCKeditor settings', |
| 287 | 'description' => 'Configure the rich text editor.', | |
| 288 | 'page callback' => 'fckeditor_admin_main', | |
| 289 | 'file' => 'fckeditor.admin.inc', | |
| 290 | 'access arguments' => array('administer fckeditor'), | |
| 291 | 'type' => MENU_NORMAL_ITEM, | |
| f3d88ca0 | 292 | ); |
| af8e9eeb | 293 | |
| 1b120ffb | 294 | $items['admin/settings/fckeditor/add'] = array( |
| 201b993d | 295 | 'title' => 'Add new FCKeditor profile', |
| 296 | 'description' => 'Configure the rich text editor.', | |
| 297 | 'page callback' => 'drupal_get_form', | |
| 298 | 'page arguments' => array('fckeditor_admin_profile_form'), | |
| 299 | 'file' => 'fckeditor.admin.inc', | |
| 300 | 'access arguments' => array('administer fckeditor'), | |
| 301 | 'type' => MENU_CALLBACK, | |
| 1b120ffb | 302 | ); |
| af8e9eeb | 303 | |
| 4255581d | 304 | $items['admin/settings/fckeditor/clone/%fckeditor_profile'] = array( |
| 201b993d | 305 | 'title' => 'Clone FCKeditor profile', |
| 306 | 'description' => 'Configure the rich text editor.', | |
| 307 | 'page callback' => 'drupal_get_form', | |
| 308 | 'page arguments' => array('fckeditor_admin_profile_clone_form', 4), | |
| 309 | 'file' => 'fckeditor.admin.inc', | |
| 310 | 'access arguments' => array('administer fckeditor'), | |
| 311 | 'type' => MENU_CALLBACK, | |
| 4255581d | 312 | ); |
| af8e9eeb | 313 | |
| 1b120ffb | 314 | $items['admin/settings/fckeditor/edit/%fckeditor_profile'] = array( |
| 201b993d | 315 | 'title' => 'Edit FCKeditor profile', |
| 316 | 'description' => 'Configure the rich text editor.', | |
| 317 | 'page callback' => 'drupal_get_form', | |
| 318 | 'page arguments' => array('fckeditor_admin_profile_form', 4), | |
| 319 | 'file' => 'fckeditor.admin.inc', | |
| 320 | 'access arguments' => array('administer fckeditor'), | |
| 321 | 'type' => MENU_CALLBACK, | |
| 1b120ffb | 322 | ); |
| af8e9eeb | 323 | |
| 1b120ffb | 324 | $items['admin/settings/fckeditor/delete/%fckeditor_profile'] = array( |
| 201b993d | 325 | 'title' => 'Delete FCKeditor profile', |
| 326 | 'description' => 'Configure the rich text editor.', | |
| 327 | 'page callback' => 'drupal_get_form', | |
| 328 | 'page arguments' => array('fckeditor_admin_profile_delete_form', 4), | |
| 329 | 'file' => 'fckeditor.admin.inc', | |
| 330 | 'access arguments' => array('administer fckeditor'), | |
| 331 | 'type' => MENU_CALLBACK, | |
| 1b120ffb | 332 | ); |
| af8e9eeb | 333 | |
| 1b120ffb | 334 | $items['admin/settings/fckeditor/addg'] = array( |
| 201b993d | 335 | 'title' => 'Add FCKeditor Global profile', |
| 336 | 'description' => 'Configure the rich text editor.', | |
| 337 | 'page callback' => 'drupal_get_form', | |
| 338 | 'page arguments' => array('fckeditor_admin_global_profile_form', 'add'), | |
| 339 | 'file' => 'fckeditor.admin.inc', | |
| 340 | 'access arguments' => array('administer fckeditor'), | |
| 341 | 'type' => MENU_CALLBACK, | |
| 1b120ffb | 342 | ); |
| af8e9eeb | 343 | |
| 1b120ffb | 344 | $items['admin/settings/fckeditor/editg'] = array( |
| 201b993d | 345 | 'title' => 'Edit FCKeditor Global profile', |
| 346 | 'description' => 'Configure the rich text editor.', | |
| 347 | 'page callback' => 'drupal_get_form', | |
| 348 | 'page arguments' => array('fckeditor_admin_global_profile_form', 'edit'), | |
| 349 | 'file' => 'fckeditor.admin.inc', | |
| 350 | 'access arguments' => array('administer fckeditor'), | |
| 351 | 'type' => MENU_CALLBACK, | |
| 1b120ffb | 352 | ); |
| 0c87a920 | 353 | |
| 1b120ffb | 354 | return $items; |
| 0c87a920 WW |
355 | } |
| 356 | ||
| 5d2db5be | 357 | /** |
| 1b120ffb | 358 | * Implementation of hook_init(). |
| 0c87a920 | 359 | */ |
| 1b120ffb JS |
360 | function fckeditor_init() { |
| 361 | drupal_add_css(drupal_get_path('module', 'fckeditor') .'/fckeditor.css'); | |
| 8de1e54a WW |
362 | } |
| 363 | ||
| 0c87a920 | 364 | /** |
| da1cf0d0 | 365 | * Implementation of hook_file_download(). |
| 1b120ffb | 366 | * Support for private downloads. |
| b94b689f | 367 | * FCKeditor does not implement any kind of potection on private files. |
| 0c87a920 | 368 | */ |
| 1b120ffb | 369 | function fckeditor_file_download($file) { |
| b94b689f WW |
370 | if ($path = file_create_path($file)) { |
| 371 | $result = db_query("SELECT f.* FROM {files} f WHERE filepath = '%s'", $path); | |
| 2ea49b21 | 372 | if (db_fetch_object($result)) { |
| b94b689f | 373 | return NULL; |
| 1b120ffb | 374 | } |
| da1cf0d0 | 375 | |
| b94b689f WW |
376 | //No info in DB? Probably a file uploaded with FCKeditor |
| 377 | $global_profile = fckeditor_profile_load("FCKeditor Global Profile"); | |
| af8e9eeb | 378 | |
| b94b689f WW |
379 | //Assume that files inside of fckeditor directory belong to the FCKeditor. If private directory is set, let the decision about protection to the user. |
| 380 | $private_dir = isset($global_profile->settings['private_dir']) ? $global_profile->settings['private_dir'] : "/"; | |
| da1cf0d0 | 381 | |
| b94b689f WW |
382 | //If path to the file points to the FCKeditor private directory, allow downloading |
| 383 | if (strpos($path, file_directory_path() ."/". trim($private_dir, "/\\")) === 0) { | |
| 384 | $ctype = ($info = @getimagesize($path)) ? $info['mime'] : (function_exists('mime_content_type') ? mime_content_type($path) : 'application/x-download'); | |
| 385 | return array('Content-type: '. $ctype); | |
| 386 | } | |
| 387 | } | |
| 0c87a920 WW |
388 | } |
| 389 | ||
| 390 | /** | |
| 391 | * Load all profiles. Just load one profile if $name is passed in. | |
| 392 | */ | |
| 393 | function fckeditor_profile_load($name = '') { | |
| 394 | static $profiles = array(); | |
| 395 | ||
| 396 | if (!$profiles) { | |
| 4059f348 | 397 | $result = db_query("SELECT * FROM {fckeditor_settings}"); |
| 075c1a2d | 398 | while (($data = db_fetch_object($result))) { |
| 0c87a920 | 399 | $data->settings = unserialize($data->settings); |
| 1b120ffb | 400 | $data->rids = array(); |
| af8e9eeb | 401 | |
| 0c87a920 WW |
402 | $profiles[$data->name] = $data; |
| 403 | } | |
| af8e9eeb | 404 | |
| 1b120ffb | 405 | $roles = user_roles(); |
| 4059f348 | 406 | $result = db_query("SELECT name, rid FROM {fckeditor_role}"); |
| 1b120ffb JS |
407 | while (($data = db_fetch_object($result))) { |
| 408 | $profiles[$data->name]->rids[$data->rid] = $roles[$data->rid]; | |
| 409 | } | |
| 0c87a920 | 410 | } |
| af8e9eeb | 411 | |
| d9b9589c | 412 | return ($name ? (isset($profiles[urldecode($name)]) ? $profiles[urldecode($name)] : FALSE) : $profiles); |
| 0c87a920 WW |
413 | } |
| 414 | ||
| 8de1e54a WW |
415 | /** |
| 416 | * @param int $excl_mode 1/include, exclude otherwise | |
| c2652cc3 | 417 | * @param string $excl_regex paths (drupal paths with ids attached) |
| 8de1e54a WW |
418 | * @param string $element_id current ID |
| 419 | * @param string $get_q current path | |
| af8e9eeb | 420 | * |
| 8de1e54a WW |
421 | * @return boolean |
| 422 | * returns true if FCKeditor is enabled | |
| 423 | */ | |
| c2652cc3 WW |
424 | function fckeditor_is_enabled($excl_mode, $excl_regex, $element_id, $get_q) { |
| 425 | $front = variable_get('site_frontpage', 'node'); | |
| 426 | $excl_regex = str_replace('<front>', $front, $excl_regex); | |
| 0a856e81 | 427 | $nodetype = fckeditor_get_nodetype($get_q); |
| 8e2207fa | 428 | $element_id = str_replace('.', '\.', $element_id); |
| af8e9eeb | 429 | |
| 27c847ec | 430 | $match = !empty($excl_regex) && preg_match($excl_regex, $nodetype .'@'. $get_q .'.'. $element_id); |
| af8e9eeb | 431 | |
| c2652cc3 | 432 | return ($excl_mode == '0' xor $match); |
| 0c87a920 WW |
433 | } |
| 434 | ||
| 435 | /** | |
| 9286dec5 | 436 | * This function create the HTML objects required for the FCKeditor |
| e44c2389 | 437 | * |
| 438 | * @param $element | |
| 439 | * A fully populated form elment to add the editor to | |
| 440 | * @return | |
| 441 | * The same $element with extra FCKeditor markup and initialization | |
| 04b827fa | 442 | */ |
| f3d88ca0 | 443 | function fckeditor_process_textarea($element) { |
| 0c87a920 WW |
444 | static $is_running = FALSE; |
| 445 | static $num = 1; | |
| 95e32685 | 446 | global $user, $language, $_fckeditor_configuration, $_fckeditor_js_ids; |
| 27c847ec | 447 | $enabled = TRUE; |
| f3d88ca0 | 448 | |
| dec7b1d3 | 449 | //hack for module developers that want to disable FCKeditor on their textareas |
| 5c21faac | 450 | if (key_exists('#wysiwyg', $element) && !$element['#wysiwyg']) { |
| dec7b1d3 WW |
451 | return $element; |
| 452 | } | |
| 8de1e54a | 453 | |
| a26718eb JS |
454 | if (isset($element['#access']) && !$element['#access']) { |
| 455 | return $element; | |
| 456 | } | |
| 457 | ||
| dec7b1d3 | 458 | //skip this one, surely nobody wants WYSIWYG here |
| 0c87a920 | 459 | switch ($element['#id']) { |
| 0c87a920 WW |
460 | case 'edit-log': |
| 461 | return $element; | |
| 462 | break; | |
| 463 | } | |
| 8de1e54a | 464 | |
| 0c87a920 | 465 | if (isset($element['#attributes']['disabled']) && $element['#attributes']['disabled'] == 'disabled') { |
| 8de1e54a WW |
466 | return $element; |
| 467 | } | |
| d3cf16a0 | 468 | |
| af8e9eeb | 469 | |
| 44173850 WW |
470 | $global_profile = fckeditor_profile_load('FCKeditor Global Profile'); |
| 471 | if ($global_profile) { | |
| 472 | $global_conf = $global_profile->settings; | |
| 473 | if ($global_conf) { | |
| 474 | $enabled = fckeditor_is_enabled(empty($global_conf['excl_mode']) ? '0' : $global_conf['excl_mode'], empty($global_conf['excl_regex']) ? '' : $global_conf['excl_regex'], $element['#id'], $_GET['q']); | |
| 475 | } | |
| 0c87a920 WW |
476 | } |
| 477 | ||
| 44173850 WW |
478 | if ($enabled) { |
| 479 | $profile = fckeditor_user_get_profile($user, $element['#id']); | |
| 480 | if ($profile) { | |
| 481 | $conf = array(); | |
| 482 | $conf = $profile->settings; | |
| 483 | ||
| 484 | if ($conf['allow_user_conf']=='t') { | |
| 485 | foreach (array('default', 'show_toggle', 'popup', 'skin', 'toolbar', 'expand', 'width', 'lang', 'auto_lang') as $setting) { | |
| 486 | $conf[$setting] = fckeditor_user_get_setting($user, $profile, $setting); | |
| 487 | } | |
| 488 | } | |
| 27c847ec JS |
489 | if ($conf['popup'] == 't' && $conf['show_toggle'] == 't') { |
| 490 | $conf['show_toggle'] = 'f'; | |
| af8e9eeb | 491 | } |
| 44173850 WW |
492 | } |
| 493 | else { | |
| 27c847ec | 494 | $enabled = FALSE; |
| 0c87a920 | 495 | } |
| 0c87a920 | 496 | } |
| da1cf0d0 | 497 | |
| c46c807b WW |
498 | //old profile info, assume Filtered HTML is enabled |
| 499 | if (!isset($conf['ss'])) { | |
| 500 | $conf['ss'] = 2; | |
| 501 | $conf['filters']['filter/0'] = 1; | |
| 502 | } | |
| 503 | if (!isset($conf['filters'])) { | |
| 504 | $conf['filters'] = array(); | |
| 505 | } | |
| da1cf0d0 | 506 | |
| 8de1e54a | 507 | $themepath = path_to_theme() .'/'; |
| 0c87a920 WW |
508 | $host = base_path(); |
| 509 | ||
| 3a55ac1f | 510 | if (!isset($element['#suffix'])) { |
| ef80606d | 511 | $element['#suffix'] = ''; |
| 3a55ac1f | 512 | } |
| af8e9eeb | 513 | |
| ef80606d | 514 | // only replace textarea when it has enough rows and it is enabled |
| 44173850 | 515 | if ($enabled && (($element['#rows'] > $conf['min_rows']) || ($conf['min_rows'] <= 1 && empty($element['#rows'])))) { |
| ef80606d | 516 | $textarea_id = $element['#id']; |
| af8e9eeb | 517 | |
| ef80606d JS |
518 | if (!isset($element['#attributes'])) { |
| 519 | $element['#attributes'] = array(); | |
| e6589905 | 520 | } |
| ef80606d JS |
521 | if (!isset($element['#attributes']['class'])) { |
| 522 | $element['#attributes']['class'] = 'fckeditor'; | |
| f60bb09c JS |
523 | } |
| 524 | else { | |
| ef80606d JS |
525 | $element['#attributes']['class'] .= ' fckeditor'; |
| 526 | } | |
| da1cf0d0 | 527 | |
| 8de1e54a | 528 | $js_id = 'oFCK_'. $num++; |
| 95e32685 | 529 | $_fckeditor_js_ids[$element['#id']] = $js_id; |
| 8de1e54a WW |
530 | $fckeditor_on = ($conf['default']=='t') ? 1 : 0 ; |
| 531 | ||
| c46c807b WW |
532 | $xss_check = 0; |
| 533 | //it's not a problem when adding new content/comment | |
| 534 | if (arg(1) != "add" && arg(1) != "reply") { | |
| 95e32685 | 535 | $_fckeditor_configuration[$element['#id']] = $conf; |
| da1cf0d0 | 536 | |
| c46c807b WW |
537 | //let FCKeditor know when perform XSS checks auto/manual |
| 538 | if ($conf['ss'] == 1) { | |
| 539 | $xss_class = 'checkxss1'; | |
| 540 | } | |
| 541 | else { | |
| 542 | $xss_class = 'checkxss2'; | |
| 543 | } | |
| 544 | ||
| 545 | $element['#attributes']['class'] .= ' '. $xss_class; | |
| 546 | $xss_check = 1; | |
| 547 | } | |
| da1cf0d0 | 548 | |
| 0c87a920 | 549 | //settings are saved as strings, not booleans |
| a38b3152 | 550 | if ($conf['show_toggle'] == 't') { |
| ef80606d JS |
551 | $content = ''; |
| 552 | if (isset($element['#post']['teaser_js'])) { | |
| 553 | $content .= $element['#post']['teaser_js'] .'<!--break-->'; | |
| 554 | } | |
| 555 | $content .= $element['#value']; | |
| 556 | $wysiwyg_link = ''; | |
| c46c807b | 557 | $wysiwyg_link .= "<a href=\"javascript:Toggle('{$textarea_id}','". str_replace("'", "\\'", t('Switch to plain text editor')) ."','". str_replace("'", "\\'", t('Switch to rich text editor')) ."',". $xss_check .");\" id=\"switch_{$textarea_id}\" ". ($fckeditor_on?"style=\"display:none\"":"") .">"; |
| 42225b39 WW |
558 | $wysiwyg_link .= $fckeditor_on ? t('Switch to plain text editor.') : t('Switch to rich text editor.'); |
| 559 | $wysiwyg_link .= '</a>'; | |
| af8e9eeb | 560 | |
| 0c87a920 WW |
561 | // Make sure to append to #suffix so it isn't completely overwritten |
| 562 | $element['#suffix'] .= $wysiwyg_link; | |
| 563 | } | |
| f3d88ca0 | 564 | // setting some variables |
| 8de1e54a | 565 | $module_drupal_path = drupal_get_path('module', 'fckeditor'); |
| 29d8625e WW |
566 | $module_full_path = $host . $module_drupal_path; |
| 567 | $editor_path = fckeditor_path(FALSE); | |
| 568 | $editor_local_path = fckeditor_path(TRUE); | |
| e2610d9c | 569 | // get the default drupal files path |
| 29d8625e | 570 | $files_path = $host . file_directory_path(); |
| 0c87a920 WW |
571 | // module_drupal_path: |
| 572 | // 'modules/fckeditor' (length=17) | |
| 573 | // module_full_path: | |
| 574 | // '/drupal5/modules/fckeditor' (length=26) | |
| 575 | // files_path: | |
| 576 | // '/drupal5/files' (length=14) | |
| f3d88ca0 | 577 | // configured in settings |
| 0c87a920 | 578 | $width = $conf['width']; |
| f3d88ca0 | 579 | |
| 580 | // sensible default for small toolbars | |
| c46c807b | 581 | $height = intval($element['#rows']) * 14 + 140; |
| f3d88ca0 | 582 | |
| 0c87a920 | 583 | if (!$is_running) { |
| 8de1e54a | 584 | drupal_add_js($module_drupal_path .'/fckeditor.utils.js'); |
| 201b993d | 585 | /* In D6 drupal_add_js() can't add external JS, in D7 use drupal_add_js(...,'external') */ |
| f60bb09c | 586 | drupal_set_html_head('<script type="text/javascript" src="'. $editor_path .'/fckeditor.js?I"></script>'); |
| 075c1a2d | 587 | $is_running = TRUE; |
| e44c2389 | 588 | } |
| 0c87a920 WW |
589 | |
| 590 | $toolbar = $conf['toolbar']; | |
| 591 | //$height += 100; // for larger toolbars | |
| 592 | ||
| c2652cc3 | 593 | $force_simple_toolbar = fckeditor_is_enabled('1', empty($conf['simple_incl_regex']) ? '' : $conf['simple_incl_regex'], $element['#id'], $_GET['q']); |
| 8de1e54a | 594 | if (!$force_simple_toolbar) { |
| c2652cc3 | 595 | $force_simple_toolbar = fckeditor_is_enabled('1', empty($global_conf['simple_incl_regex']) ? '' : $global_conf['simple_incl_regex'], $element['#id'], $_GET['q']); |
| 8de1e54a WW |
596 | } |
| 597 | if ($force_simple_toolbar) { | |
| 0c87a920 | 598 | $toolbar = FCKEDITOR_FORCE_SIMPLE_TOOLBAR_NAME; |
| f3d88ca0 | 599 | } |
| af8e9eeb | 600 | |
| ac9e6b9f WW |
601 | if (!empty($conf['theme_config_js']) && $conf['theme_config_js'] == 't' && file_exists($themepath .'fckeditor.config.js')) { |
| 602 | $fckeditor_config_path = $host . $themepath .'fckeditor.config.js?'. @filemtime($themepath .'fckeditor.config.js'); | |
| 603 | } | |
| 604 | else { | |
| 605 | $fckeditor_config_path = $module_full_path ."/fckeditor.config.js?". @filemtime($module_drupal_path ."/fckeditor.config.js"); | |
| 606 | } | |
| 607 | ||
| 7254e6f4 | 608 | $js = $js_id ." = new FCKeditor( '". $textarea_id ."' ); |
| d065653a | 609 | ". $js_id .".defaultState = ". (($fckeditor_on && $conf['popup'] == 'f') ? 1 : 0) ."; |
| 8b081e6c | 610 | ". $js_id .".BasePath = '". $editor_path ."/'; |
| c46c807b | 611 | ". $js_id .".DrupalId = '". $js_id ."'; |
| 8b081e6c | 612 | ". $js_id .".Config['PluginsPath'] = '". $module_full_path ."/plugins/'; |
| ac9e6b9f | 613 | ". $js_id .".Config['CustomConfigurationsPath'] = \"". $fckeditor_config_path ."\"; |
| 8de1e54a | 614 | ". $js_id .".Config['TextareaID'] = \"". $element['#id'] ."\";"; |
| 0c87a920 WW |
615 | |
| 616 | //if ($conf['appearance_conf'] == 'f') { | |
| 7254e6f4 | 617 | $js .= "\n". $js_id .".ToolbarSet = \"". $toolbar ."\"; |
| 8de1e54a WW |
618 | ". $js_id .".Config['SkinPath'] = ". $js_id .".BasePath + \"editor/skins/". $conf['skin'] ."/\"; |
| 619 | ". $js_id .".Config['DefaultLanguage'] = \"". $conf['lang'] ."\"; | |
| 620 | ". $js_id .".Config['AutoDetectLanguage'] = ". ($conf['auto_lang']=="t"?"true":"false") ."; | |
| 621 | ". $js_id .".Height = \"". $height ."\"; | |
| 622 | ". $js_id .".Config['ToolbarStartExpanded'] = ". ($conf['expand']=="t"?"true":"false") ."; | |
| 623 | ". $js_id .".Width = \"". $width ."\";\n"; | |
| 0c87a920 WW |
624 | //} |
| 625 | //if ($conf['output_conf'] == 'f') { | |
| 7254e6f4 | 626 | $js .= "\n". $js_id .".Config['EnterMode'] = '". $conf['enter_mode'] ."'; |
| 8de1e54a WW |
627 | ". $js_id .".Config['ShiftEnterMode'] = \"". $conf['shift_enter_mode'] ."\"; |
| 628 | ". $js_id .".Config['FontFormats'] = \"". str_replace(",", ";", $conf['font_format']) ."\"; | |
| 629 | ". $js_id .".Config['FormatSource'] = ". ($conf['format_source']=="t"?"true":"false") ."; | |
| 630 | ". $js_id .".Config['FormatOutput'] = ". ($conf['format_output']=="t"?"true":"false") .";\n"; | |
| 0c87a920 | 631 | //} |
| af8e9eeb | 632 | |
| 05abb967 WW |
633 | if (defined('LANGUAGE_RTL') && $language->direction == LANGUAGE_RTL) { |
| 634 | $js .= $js_id .".Config['ContentLangDirection'] = 'rtl';\n"; | |
| 635 | } | |
| 636 | ||
| af03ba76 | 637 | if (function_exists('img_assist_perm')) { //#275158 |
| 7254e6f4 | 638 | drupal_add_js("var fckImgAssistPath = '". base_path() . drupal_get_path('module', 'img_assist') ."';", 'inline'); |
| af03ba76 | 639 | } |
| e44c2389 | 640 | // add code for filebrowser for users that have access |
| 0c87a920 | 641 | if (user_access('allow fckeditor file uploads')==1) { |
| c46c807b | 642 | $filebrowser = !empty($conf['filebrowser']) ? $conf['filebrowser'] : 'none'; |
| 6f7c3903 JS |
643 | if ($filebrowser == 'imce' && !module_exists('imce')) { |
| 644 | $filebrowser = 'none'; | |
| 0c87a920 | 645 | } |
| 12ac377f WW |
646 | if ($filebrowser == 'ib' && !module_exists('imagebrowser')) { |
| 647 | $filebrowser = 'none'; | |
| 648 | } | |
| 43e129e1 WW |
649 | if ($filebrowser == 'webfm' && !module_exists('webfm_popup')) { |
| 650 | $filebrowser = 'none'; | |
| 651 | } | |
| c46c807b | 652 | $quickupload = (!empty($conf['quickupload']) && $conf['quickupload'] == 't'); |
| af8e9eeb | 653 | |
| 6f7c3903 JS |
654 | // load variables used by both quick upload and filebrowser |
| 655 | // and assure that the $_SESSION variables are loaded | |
| 656 | if ($quickupload || $filebrowser == 'builtin') { | |
| 29d8625e WW |
657 | if (file_exists($editor_local_path ."/editor/filemanager/connectors/php/connector.php")) { |
| 658 | $connector_path = $editor_path ."/editor/filemanager/connectors/php/connector.php" ; | |
| 659 | } | |
| f60bb09c | 660 | elseif (file_exists($editor_local_path ."/editor/filemanager/upload/php/connector.php")) { |
| 29d8625e WW |
661 | $connector_path = $editor_path ."/editor/filemanager/upload/php/connector.php"; |
| 662 | } | |
| 663 | ||
| 664 | if (file_exists($editor_local_path ."/editor/filemanager/connectors/php/upload.php")) { | |
| 665 | $upload_path = $editor_path ."/editor/filemanager/connectors/php/upload.php" ; | |
| 666 | } | |
| f60bb09c | 667 | elseif (file_exists($editor_local_path ."/editor/filemanager/upload/php/upload.php")) { |
| 29d8625e WW |
668 | $upload_path = $editor_path ."/editor/filemanager/upload/php/upload.php"; |
| 669 | } | |
| 670 | ||
| 64e4e195 WW |
671 | if (!empty($profile->settings['UserFilesPath'])) $_SESSION['FCKeditor']['UserFilesPath'] = strtr($profile->settings['UserFilesPath'], array("%f" => file_directory_path(), "%u" => $user->uid, "%b" => $host, "%n" => $user->name)); |
| 672 | if (!empty($profile->settings['UserFilesAbsolutePath'])) $_SESSION['FCKeditor']['UserFilesAbsolutePath'] = strtr($profile->settings['UserFilesAbsolutePath'], array("%f" => file_directory_path(), "%u" => $user->uid, "%b" => base_path(), "%d" => $_SERVER['DOCUMENT_ROOT'], "%n" => $user->name)); | |
| 45352a83 | 673 | if (variable_get('file_downloads', '') == FILE_DOWNLOADS_PRIVATE) { |
| 6484321d JS |
674 | $private_dir = isset($global_profile->settings['private_dir']) ? trim($global_profile->settings['private_dir'], '\/') : ''; |
| 675 | if (!empty($private_dir)) { | |
| 676 | $private_dir = strtr($private_dir, array('%u' => $user->uid)); | |
| b94b689f WW |
677 | $_SESSION['FCKeditor']['UserFilesPath'] = url('system/files') .'/'. $private_dir .'/'; |
| 678 | $_SESSION['FCKeditor']['UserFilesAbsolutePath'] = realpath(file_directory_path()) . DIRECTORY_SEPARATOR . $private_dir . DIRECTORY_SEPARATOR; | |
| 679 | } | |
| 680 | else { | |
| 681 | $_SESSION['FCKeditor']['UserFilesPath'] = url('system/files') .'/'; | |
| 682 | $_SESSION['FCKeditor']['UserFilesAbsolutePath'] = realpath(file_directory_path()) . DIRECTORY_SEPARATOR; | |
| 683 | } | |
| 45352a83 | 684 | } |
| 0c87a920 | 685 | } |
| af8e9eeb | 686 | |
| 6f7c3903 | 687 | if ($quickupload) { |
| 7254e6f4 WW |
688 | $js .= $js_id .".Config['LinkUpload'] = true;\n"; |
| 689 | $js .= $js_id .".Config['ImageUpload'] = true;\n"; | |
| 690 | $js .= $js_id .".Config['FlashUpload'] = true;\n"; | |
| 691 | $js .= $js_id .".Config['LinkUploadURL'] = '". $upload_path ."';\n"; | |
| 692 | $js .= $js_id .".Config['ImageUploadURL'] = '". $upload_path ."?Type=Image';\n"; | |
| 693 | $js .= $js_id .".Config['FlashUploadURL'] = '". $upload_path ."?Type=Flash';\n"; | |
| 075c1a2d JS |
694 | } |
| 695 | else { | |
| 7254e6f4 WW |
696 | $js .= $js_id .".Config['LinkUpload'] = false;\n"; |
| 697 | $js .= $js_id .".Config['ImageUpload'] = false;\n"; | |
| 698 | $js .= $js_id .".Config['FlashUpload'] = false;\n"; | |
| 6f7c3903 | 699 | } |
| af8e9eeb | 700 | |
| 075c1a2d | 701 | switch ($filebrowser) { |
| 6f7c3903 | 702 | case 'imce': |
| 7254e6f4 WW |
703 | $js .= $js_id .".Config['LinkBrowser']= true;\n"; |
| 704 | $js .= $js_id .".Config['ImageBrowser']= true;\n"; | |
| 705 | $js .= $js_id .".Config['FlashBrowser']= true;\n"; | |
| dc0840ab | 706 | $js .= $js_id .".Config['LinkBrowserURL']= '". $host ."index.php?q=imce&app=FCKEditor|url@txtLnkUrl,txtUrl';\n"; |
| 2b01c11b WW |
707 | $js .= $js_id .".Config['ImageBrowserURL']= '". $host ."index.php?q=imce&app=FCKEditor|url@txtUrl|width@txtWidth|height@txtHeight';\n"; |
| 708 | $js .= $js_id .".Config['FlashBrowserURL']= '". $host ."index.php?q=imce&app=FCKEditor|url@txtUrl';\n"; | |
| 6f7c3903 | 709 | break; |
| 201b993d | 710 | |
| 43e129e1 WW |
711 | case 'webfm': |
| 712 | $js .= $js_id .".Config['LinkBrowser']= true;\n"; | |
| 713 | $js .= $js_id .".Config['ImageBrowser']= true;\n"; | |
| 714 | $js .= $js_id .".Config['FlashBrowser']= true;\n"; | |
| 715 | $js .= $js_id .".Config['ImageDlgHideLink']= true;\n"; | |
| 716 | $js .= $js_id .".Config['LinkBrowserURL']= '". $host ."index.php?q=webfm_popup&url=txtUrl';\n"; | |
| 717 | $js .= $js_id .".Config['ImageBrowserURL']= '". $host ."index.php?q=webfm_popup&url=txtUrl';\n"; | |
| 718 | $js .= $js_id .".Config['FlashBrowserURL']= '". $host ."index.php?q=webfm_popup&url=txtUrl';\n"; | |
| 719 | break; | |
| 720 | ||
| 6f7c3903 | 721 | case 'builtin': |
| 7254e6f4 WW |
722 | $js .= $js_id .".Config['LinkBrowser'] = true;\n"; |
| 723 | $js .= $js_id .".Config['ImageBrowser'] = true;\n"; | |
| 724 | $js .= $js_id .".Config['FlashBrowser'] = true;\n"; | |
| 725 | $js .= $js_id .".Config['LinkBrowserURL'] = '". $editor_path ."/editor/filemanager/browser/default/browser.html?Connector=". $connector_path ."&ServerPath=". $files_path ."';\n"; | |
| 726 | $js .= $js_id .".Config['ImageBrowserURL'] = '". $editor_path ."/editor/filemanager/browser/default/browser.html?Type=Image&Connector=". $connector_path ."&ServerPath=". $files_path ."';\n"; | |
| 727 | $js .= $js_id .".Config['FlashBrowserURL'] = '". $editor_path ."/editor/filemanager/browser/default/browser.html?Type=Flash&Connector=". $connector_path ."&ServerPath=". $files_path ."';\n"; | |
| 6f7c3903 | 728 | break; |
| 201b993d | 729 | |
| 12ac377f WW |
730 | case 'ib': |
| 731 | $js .= $js_id .".Config['ImageBrowser']= true;\n"; | |
| 732 | $js .= $js_id .".Config['LinkBrowser']= true;\n"; | |
| 733 | $js .= $js_id .".Config['FlashBrowser']= false;\n"; | |
| 43e129e1 WW |
734 | $js .= $js_id .".Config['ImageBrowserURL']= '". $host ."index.php?q=imagebrowser/view/browser&app=FCKEditor';\n"; |
| 735 | $js .= $js_id .".Config['LinkBrowserURL']= '". $host ."index.php?q=imagebrowser/view/browser&app=FCKEditor';\n"; | |
| 12ac377f WW |
736 | $js .= $js_id .".Config['ImageBrowserWindowWidth']= '680';"; |
| 737 | $js .= $js_id .".Config['ImageBrowserWindowHeight'] = '439';"; | |
| 738 | $js .= $js_id .".Config['LinkBrowserWindowWidth']= '680';"; | |
| 739 | $js .= $js_id .".Config['LinkBrowserWindowHeight'] = '439';"; | |
| 740 | break; | |
| 741 | ||
| 6f7c3903 JS |
742 | default: |
| 743 | case 'none': | |
| 7254e6f4 WW |
744 | $js .= $js_id .".Config['LinkBrowser'] = false;\n"; |
| 745 | $js .= $js_id .".Config['ImageBrowser'] = false;\n"; | |
| 746 | $js .= $js_id .".Config['FlashBrowser'] = false;\n"; | |
| 6f7c3903 JS |
747 | break; |
| 748 | } | |
| 0c87a920 WW |
749 | } |
| 750 | else { | |
| 7254e6f4 WW |
751 | $js .= $js_id .".Config['LinkBrowser'] = false;\n"; |
| 752 | $js .= $js_id .".Config['ImageBrowser'] = false;\n"; | |
| 753 | $js .= $js_id .".Config['FlashBrowser'] = false;\n"; | |
| 754 | $js .= $js_id .".Config['LinkUpload'] = false;\n"; | |
| 755 | $js .= $js_id .".Config['ImageUpload'] = false;\n"; | |
| 756 | $js .= $js_id .".Config['FlashUpload'] = false;\n"; | |
| 8de1e54a | 757 | } |
| af8e9eeb | 758 | |
| e9a59651 | 759 | if (!empty($conf['js_conf'])) { |
| 8de1e54a WW |
760 | $lines = preg_split("/[\n\r]+/", $conf['js_conf']); |
| 761 | foreach ($lines as $l) | |
| 762 | if ($l && strlen($l) > 5) { | |
| 763 | $eqpos = strpos($l, "="); | |
| 075c1a2d | 764 | if (FALSE !== $eqpos) { |
| 8de1e54a | 765 | $option = str_replace("FCKConfig.", "", substr($l, 0, $eqpos)); |
| 7254e6f4 | 766 | $js .= "\n". $js_id .".Config['". trim($option) ."'] =". substr($l, $eqpos + 1); |
| 8de1e54a WW |
767 | } |
| 768 | } | |
| 92b2e6cf | 769 | } |
| e44c2389 | 770 | |
| 0c87a920 | 771 | // add custom xml stylesheet if it exists |
| e9a59651 | 772 | if (!empty($conf['css_style']) && $conf['css_style'] == 'theme') { |
| 746b1a35 WW |
773 | if (file_exists($themepath .'fckstyles.xml')) { |
| 774 | $styles_xml_path = $host . $themepath .'fckstyles.xml'; | |
| 7254e6f4 | 775 | $js .= $js_id .".Config['StylesXmlPath'] = \"". $styles_xml_path ."\";\n"; |
| 8de1e54a WW |
776 | } |
| 777 | } | |
| e9a59651 | 778 | else if (!empty($conf['css_style']) && $conf['css_style'] == 'self') { |
| 0ee41c0b | 779 | $conf['styles_path'] = str_replace("%h%t", "%t", $conf['styles_path']); |
| 7254e6f4 | 780 | $js .= $js_id .".Config['StylesXmlPath'] = \"". str_replace(array('%h', '%t', '%m'), array($host, $host . $themepath, $module_drupal_path), $conf['styles_path']) ."\";\n"; |
| 0c87a920 | 781 | } |
| 0c87a920 WW |
782 | // add custom stylesheet if configured |
| 783 | // lets hope it exists but we'll leave that to the site admin | |
| 23809d98 JS |
784 | $cssfiles = array($module_full_path .'/fckeditor.css'); |
| 785 | switch ($conf['css_mode']) { | |
| 786 | case 'theme': | |
| 021b9f79 WW |
787 | global $language, $theme, $theme_info, $base_theme_info; |
| 788 | ||
| 789 | $style_css = $themepath .'style.css'; | |
| 790 | if (!empty($theme_info->stylesheets)) { | |
| cfc7bb33 | 791 | $css_files = array(); |
| 021b9f79 | 792 | $editorcss = "\""; |
| 19e92d68 | 793 | foreach ($base_theme_info as $base) { // Grab stylesheets from base theme |
| cfc7bb33 WW |
794 | foreach ($base->stylesheets as $type => $stylesheets) { |
| 795 | if ($type != "print") { | |
| 796 | foreach ($stylesheets as $name => $path) { | |
| 19e92d68 WW |
797 | if (file_exists($path)) { |
| 798 | $css_files[$name] = $host . $path; | |
| 799 | } | |
| 021b9f79 WW |
800 | } |
| 801 | } | |
| 802 | } | |
| 803 | } | |
| 19e92d68 | 804 | if (!empty($theme_info->stylesheets)) { // Grab stylesheets from current theme |
| cfc7bb33 WW |
805 | foreach ($theme_info->stylesheets as $type => $stylesheets) { |
| 806 | if ($type != "print") { | |
| 807 | foreach ($stylesheets as $name => $path) { | |
| 19e92d68 WW |
808 | if (file_exists($path)) { |
| 809 | $css_files[$name] = $host . $path; | |
| 810 | } | |
| 400f8f63 WW |
811 | else if (!empty($css_files[$name])) { |
| 812 | unset($css_files[$name]); | |
| 813 | } | |
| cfc7bb33 WW |
814 | } |
| 815 | } | |
| 021b9f79 WW |
816 | } |
| 817 | } | |
| cfc7bb33 WW |
818 | if (!empty($css_files)) { |
| 819 | $editorcss .= implode(",", $css_files) .","; | |
| 021b9f79 WW |
820 | } |
| 821 | // Grab stylesheets from color module | |
| 822 | $color_paths = variable_get('color_'. $theme .'_stylesheets', array()); | |
| 823 | if (defined('LANGUAGE_RTL') && $language->direction == LANGUAGE_RTL) { | |
| 824 | if (!empty($color_paths[1])) { | |
| 825 | $editorcss .= $host . $color_paths[1] .","; | |
| 826 | } | |
| 827 | } | |
| 400f8f63 WW |
828 | else if (!empty($color_paths[0])) { |
| 829 | $editorcss .= $host . $color_paths[0] .","; | |
| 021b9f79 WW |
830 | } |
| 831 | $editorcss .= $module_full_path ."/fckeditor.css\";\n"; | |
| 832 | $js .= $js_id .".Config['EditorAreaCSS'] = ". $editorcss; | |
| 69bd70a8 | 833 | } |
| 021b9f79 WW |
834 | else if (file_exists($style_css)) { |
| 835 | $js .= $js_id .".Config['EditorAreaCSS'] = \"". $host . $style_css .",". $module_full_path ."/fckeditor.css\";"; | |
| 23809d98 | 836 | } |
| 021b9f79 WW |
837 | else { |
| 838 | $js .= $js_id .".Config['EditorAreaCSS'] = \"". $module_full_path ."/fckeditor.css\";"; | |
| 23809d98 JS |
839 | } |
| 840 | break; | |
| 201b993d | 841 | |
| 23809d98 JS |
842 | case 'self': |
| 843 | $conf['css_path'] = str_replace("%h%t", "%t", $conf['css_path']); | |
| 844 | $cssfiles[] = str_replace(array('%h', '%t'), array($host, $host . $themepath), $conf['css_path']); | |
| 7254e6f4 | 845 | $js .= $js_id .".Config['EditorAreaCSS'] = '". implode(',', $cssfiles) ."';\n"; |
| 6de0735a | 846 | break; |
| 201b993d | 847 | |
| 6de0735a | 848 | case 'none': |
| 7254e6f4 | 849 | $js .= $js_id .".Config['EditorAreaCSS'] = ". $js_id .".BasePath + 'editor/css/fck_editorarea.css,' + '". implode(',', $cssfiles) ."';\n"; |
| 23809d98 | 850 | break; |
| 0c87a920 | 851 | } |
| a9579640 WW |
852 | if ($num == 2) { |
| 853 | $js .= 'var fckInstances = {};'; | |
| 854 | } | |
| 7254e6f4 | 855 | $js .= 'fckInstances[\''. $textarea_id .'\'] = '. $js_id .";\n"; |
| af8e9eeb | 856 | |
| ec1149f8 | 857 | drupal_add_js('var '. $js_id .';if (Drupal.jsEnabled) {'. $js .'}', 'inline'); |
| f3d88ca0 | 858 | |
| ef80606d | 859 | if ($conf['popup'] == 't') { |
| 42225b39 | 860 | $element['#suffix'] .= ' <span class="fckeditor_popuplink">(<a href="#" onclick="FCKeditor_OpenPopup(\''. $module_full_path .'/fckeditor.popup.html\', \''. $js_id .'\', \''. $element['#id'] .'\'); return false;">'. t('Open rich text editor') ."</a>)</span>"; |
| 0c87a920 | 861 | } |
| f3d88ca0 | 862 | } |
| 9b429add | 863 | |
| 0c87a920 | 864 | // display the field id for administrators |
| 44173850 | 865 | if (user_access('administer fckeditor') && (!isset($global_conf['show_fieldnamehint']) || $global_conf['show_fieldnamehint'] == 't')) { |
| 1b120ffb | 866 | module_load_include('admin.inc', 'fckeditor'); |
| af8e9eeb | 867 | |
| 42225b39 | 868 | $element['#suffix'] .= '<div class="textarea-identifier description">'. t('The ID for <a href="!excluding">excluding or including</a> this element is %fieldname.', array('!excluding' => url('admin/settings/fckeditor'), '%fieldname' => fckeditor_rule_to_string(fckeditor_rule_create(fckeditor_get_nodetype($_GET['q']), $_GET['q'], $element['#id'])))) .'</div>'; |
| 0c87a920 WW |
869 | } |
| 870 | ||
| f3d88ca0 | 871 | return $element; |
| 04b827fa DS |
872 | } |
| 873 | ||
| 23824481 | 874 | /** |
| 8de1e54a WW |
875 | * sort roles according to precedence settings. previously sorted roles are followed by latest added roles. |
| 876 | */ | |
| 877 | function fckeditor_sorted_roles() { | |
| 878 | static $order; | |
| 879 | if (isset($order)) { | |
| 880 | return $order; | |
| 881 | } | |
| 882 | $order = array(); | |
| 883 | $roles = user_roles(0, 'access fckeditor'); | |
| 884 | ||
| 885 | $result = db_query("SELECT settings FROM {fckeditor_settings} WHERE name='FCKeditor Global Profile'"); | |
| 886 | $data = db_fetch_object($result); | |
| d7fbc905 | 887 | if (!empty($data->settings)) { |
| 8de1e54a WW |
888 | $settings = unserialize($data->settings); |
| 889 | if (isset($settings['rank']) && !empty($settings['rank'])) | |
| 890 | foreach ($settings['rank'] as $rid) { | |
| 891 | if (isset($roles[$rid])) { | |
| 892 | $order[$rid] = $roles[$rid]; | |
| 893 | unset($roles[$rid]); | |
| 894 | } | |
| 895 | } | |
| 896 | } | |
| 897 | krsort($roles);//sort the remaining unsorted roles by id, descending. | |
| 898 | $order += $roles; | |
| 899 | return $order; | |
| 900 | } | |
| 901 | ||
| 0c87a920 | 902 | /** |
| e44c2389 | 903 | * Test if client can render the FCKeditor |
| 0c87a920 WW |
904 | * Use built-in test method in fckeditor.php |
| 905 | * If fckeditor.php is not found, return false (probably in such case fckeditor is not installed correctly) | |
| e44c2389 | 906 | * |
| 907 | * @return | |
| 908 | * TRUE if the browser is reasonably capable | |
| 04b827fa DS |
909 | */ |
| 910 | function fckeditor_is_compatible_client() { | |
| 29d8625e | 911 | $editor_local_path = fckeditor_path(TRUE); |
| d6fbb175 WW |
912 | |
| 913 | $fckeditor_main_file = $editor_local_path .'/fckeditor.php'; | |
| 914 | if (!function_exists('version_compare') || version_compare(phpversion(), '5', '<')) { | |
| 915 | $fckeditor_target_file = $editor_local_path .'/fckeditor_php4.php'; | |
| 916 | } | |
| 917 | else { | |
| 918 | $fckeditor_target_file = $editor_local_path .'/fckeditor_php5.php'; | |
| 919 | } | |
| 920 | ||
| 921 | if (file_exists($fckeditor_target_file)) { | |
| 922 | include_once $fckeditor_target_file; | |
| 923 | //FCKeditor 2.6.1+ | |
| 0c87a920 WW |
924 | if (function_exists('FCKeditor_IsCompatibleBrowser')) { |
| 925 | return FCKeditor_IsCompatibleBrowser(); | |
| 926 | } | |
| 81db85ca | 927 | else if (class_exists('FCKeditor')) { |
| d6fbb175 WW |
928 | //FCKeditor 2.5.1 up to 2.6 with definition of FCKeditor_IsCompatibleBrowser() in fckeditor.php |
| 929 | if (filesize($fckeditor_main_file) > 1500) { | |
| 930 | include_once $fckeditor_main_file; | |
| 931 | } | |
| 932 | //FCKeditor 2.5.0 and earlier | |
| 1b120ffb | 933 | $fck = new FCKeditor('fake'); |
| 0c87a920 WW |
934 | return $fck->IsCompatible(); |
| 935 | } | |
| 936 | } | |
| 937 | ||
| 075c1a2d | 938 | return FALSE; |
| 0c87a920 WW |
939 | } |
| 940 | ||
| 29d8625e | 941 | /** |
| 6dab511d | 942 | * Get an array of input formats that include HTML filter |
| 5d2db5be WW |
943 | * |
| 944 | * @return array | |
| 945 | */ | |
| 946 | function fckeditor_html_filter_formats() { | |
| 947 | static $return; | |
| da1cf0d0 | 948 | |
| 5d2db5be WW |
949 | if (isset($return)) { |
| 950 | return $return; | |
| 951 | } | |
| da1cf0d0 | 952 | |
| 5d2db5be WW |
953 | $return = array(); |
| 954 | $r = db_query("SELECT format FROM {filters} WHERE module = 'filter' AND delta = 0"); | |
| 955 | while ($row = db_fetch_object($r)) { | |
| 956 | $return[] = $row->format; | |
| 957 | } | |
| da1cf0d0 | 958 | |
| 5d2db5be WW |
959 | return $return; |
| 960 | } | |
| 961 | ||
| 962 | /** | |
| 29d8625e WW |
963 | * Read FCKeditor path from Global profile |
| 964 | * | |
| 965 | * @return | |
| 966 | * path to FCKeditor folder | |
| 967 | */ | |
| 29d8625e WW |
968 | function fckeditor_path($local = FALSE) { |
| 969 | static $fck_path; | |
| 970 | static $fck_local_path; | |
| 971 | ||
| 972 | if (!$fck_path) { | |
| 973 | $mod_path = drupal_get_path('module', 'fckeditor'); | |
| 974 | $global_profile = fckeditor_profile_load('FCKeditor Global Profile'); | |
| 975 | ||
| 976 | //default: path to fckeditor subdirectory in the fckeditor module directory (starting from the document root) | |
| 977 | //e.g. for http://example.com/drupal it will be /drupal/sites/all/modules/fckeditor/fckeditor | |
| f60bb09c | 978 | $fck_path = base_path() . $mod_path .'/fckeditor'; |
| af8e9eeb | 979 | |
| 29d8625e WW |
980 | //default: path to fckeditor subdirectory in the fckeditor module directory (relative to index.php) |
| 981 | //e.g.: sites/all/modules/fckeditor/fckeditor | |
| f60bb09c | 982 | $fck_local_path = $mod_path .'/fckeditor'; |
| 29d8625e WW |
983 | |
| 984 | if ($global_profile) { | |
| 985 | $gs = $global_profile->settings; | |
| af8e9eeb | 986 | |
| f60bb09c | 987 | if (isset($gs['fckeditor_path'])) { |
| 29d8625e WW |
988 | $tmp_path = $gs['fckeditor_path']; |
| 989 | $tmp_path = strtr($tmp_path, array("%b" => base_path(), "%m" => base_path() . $mod_path)); | |
| 990 | $tmp_path = str_replace('\\', '/', $tmp_path); | |
| 991 | $tmp_path = str_replace('//', '/', $tmp_path); | |
| 992 | $tmp_path = rtrim($tmp_path, ' \/'); | |
| f60bb09c | 993 | if (substr($tmp_path, 0, 1) != '/') { |
| 29d8625e WW |
994 | $tmp_path = '/'. $tmp_path; //starts with '/' |
| 995 | } | |
| 996 | $fck_path = $tmp_path; | |
| af8e9eeb | 997 | |
| 29d8625e WW |
998 | if (empty($gs['fckeditor_local_path'])) { |
| 999 | //fortunately wildcards are used, we can easily get the right server path | |
| 1000 | if (false !== strpos($gs['fckeditor_path'], "%m")) { | |
| 1001 | $gs['fckeditor_local_path'] = strtr($gs['fckeditor_path'], array("%m" => $mod_path)); | |
| 1002 | } | |
| 1003 | if (false !== strpos($gs['fckeditor_path'], "%b")) { | |
| 1004 | $gs['fckeditor_local_path'] = strtr($gs['fckeditor_path'], array("%b" => ".")); | |
| 1005 | } | |
| 1006 | } | |
| 1007 | } | |
| 1008 | ||
| af8e9eeb | 1009 | //fckeditor_path is defined, but wildcards are not used, we need to try to find out where is |
| 29d8625e WW |
1010 | //the document root located and append fckeditor_path to it. |
| 1011 | if (!empty($gs['fckeditor_local_path'])) { | |
| 1012 | $fck_local_path = $gs['fckeditor_local_path']; | |
| 1013 | } | |
| 1014 | else if (!empty($gs['fckeditor_path'])) { | |
| 1015 | module_load_include('lib.inc', 'fckeditor'); | |
| 1016 | $local_path = fckeditor_resolve_url( $gs['fckeditor_path'] ."/" ); | |
| 1017 | if (FALSE !== $local_path) { | |
| 1018 | $fck_local_path = $local_path; | |
| 1019 | } | |
| 1020 | } | |
| af8e9eeb | 1021 | } |
| 29d8625e WW |
1022 | } |
| 1023 | if ($local) { | |
| 1024 | return $fck_local_path; | |
| 1025 | } | |
| 1026 | else { | |
| 1027 | return $fck_path; | |
| 1028 | } | |
| 1029 | } | |
| 1030 | ||
| 8de1e54a | 1031 | function fckeditor_user_get_setting($user, $profile, $setting) { |
| 0c87a920 | 1032 | $default = array( |
| 201b993d | 1033 | 'default' => 't', |
| 1034 | 'show_toggle' => 't', | |
| 1035 | 'popup' => 'f', | |
| 1036 | 'skin' => 'default', | |
| 1037 | 'toolbar' => 'default', | |
| 1038 | 'expand' => 't', | |
| 1039 | 'width' => '100%', | |
| 1040 | 'lang' => 'en', | |
| 1041 | 'auto_lang' => 't', | |
| 0c87a920 | 1042 | ); |
| 0c87a920 | 1043 | |
| a38b3152 JS |
1044 | if ($profile->settings['allow_user_conf']) { |
| 1045 | $status = isset($user->{'fckeditor_'. $setting}) ? $user->{'fckeditor_'. $setting} : (isset($profile->settings[$setting]) ? $profile->settings[$setting] : $default[$setting]); | |
| 04b827fa | 1046 | } |
| 0c87a920 | 1047 | else { |
| a38b3152 | 1048 | $status = isset($profile->settings[$setting]) ? $profile->settings[$setting] : $default[$setting]; |
| 04b827fa | 1049 | } |
| 0c87a920 WW |
1050 | |
| 1051 | return $status; | |
| 1052 | } | |
| 1053 | ||
| 44173850 WW |
1054 | function fckeditor_user_get_profile($user, $element_id = NULL) { |
| 1055 | $rids = array(); | |
| 8bdf4d22 WW |
1056 | |
| 1057 | // Since fckeditor_profile_load() makes a db hit, only call it when we're pretty sure | |
| 1058 | // we're gonna render fckeditor. | |
| 27c847ec JS |
1059 | $sorted_roles = fckeditor_sorted_roles(); |
| 1060 | foreach (array_keys($sorted_roles) as $rid) { | |
| 1061 | if (isset($user->roles[$rid])) { | |
| 1062 | $rids[] = $rid; | |
| 8bdf4d22 | 1063 | } |
| 44173850 | 1064 | } |
| 8bdf4d22 | 1065 | |
| 44173850 | 1066 | if ($user->uid == 1 && !sizeof($rids)) { |
| 0d50e82a WW |
1067 | $r = db_fetch_object(db_query_range("SELECT r.rid FROM {fckeditor_role} r ORDER BY r.rid DESC", 1)); |
| 1068 | $rids[] = $r->rid; | |
| 44173850 WW |
1069 | } |
| 1070 | ||
| 1071 | $profile_names = array(); | |
| 1072 | if (sizeof($rids)) { | |
| 1073 | $result = db_query("SELECT r.rid, s.name FROM {fckeditor_settings} s INNER JOIN {fckeditor_role} r ON r.name = s.name WHERE r.rid IN (". implode(",", $rids) .")"); | |
| 27c847ec | 1074 | while (($row = db_fetch_array($result))) { |
| 44173850 WW |
1075 | if (!isset($profile_names[$row['rid']])) { |
| 1076 | $profile_names[$row['rid']] = array(); | |
| 1077 | } | |
| 1078 | array_push($profile_names[$row['rid']], $row['name']); | |
| 8bdf4d22 | 1079 | } |
| 0c87a920 | 1080 | } |
| d3cf16a0 | 1081 | |
| 44173850 WW |
1082 | foreach ($rids as $rid) { |
| 1083 | if (!empty($profile_names[$rid])) { | |
| 1084 | foreach ($profile_names[$rid] as $profile_name) { | |
| 1085 | $profile = fckeditor_profile_load($profile_name); | |
| 1086 | ||
| 1087 | $conf = $profile->settings; | |
| 1088 | $enabled = fckeditor_is_enabled(empty($conf['excl_mode']) ? '0' : $conf['excl_mode'], empty($conf['excl_regex']) ? '' : $conf['excl_regex'], $element_id, $_GET['q']); | |
| 1089 | ||
| 1090 | if ($enabled) { | |
| 1091 | return $profile; | |
| 1092 | } | |
| 1093 | } | |
| 1094 | } | |
| 0c87a920 | 1095 | } |
| d3cf16a0 | 1096 | |
| 075c1a2d | 1097 | return FALSE; |
| 29d8625e | 1098 | } |
| ed7a9537 | 1099 | |
| 0a856e81 | 1100 | function fckeditor_get_nodetype($get_q) { |
| ed7a9537 | 1101 | static $nodetype; |
| af8e9eeb | 1102 | |
| ed7a9537 JS |
1103 | if (!isset($nodetype)) { |
| 1104 | $menuitem = menu_get_item(); | |
| 1105 | $nodetype = '*'; | |
| 1106 | if (!empty($menuitem['page_arguments'])) { | |
| 1107 | foreach ($menuitem['page_arguments'] as $item) { | |
| 1108 | if (!empty($item->nid) && !empty($item->type)) { | |
| 1109 | // not 100% valid check if $item is a node | |
| 1110 | $nodetype = $item->type; | |
| 1111 | break; | |
| 1112 | } | |
| 1113 | } | |
| 1114 | } | |
| 0a856e81 WW |
1115 | |
| 1116 | if ($nodetype == '*') { | |
| 1117 | $get_q = explode("/", $get_q, 3); | |
| 1118 | if ($get_q[0] == "node" && $get_q[1] == "add" && !empty($get_q[2])) { | |
| 1119 | $nodetype = $get_q[2]; | |
| 1120 | } | |
| 1121 | } | |
| ed7a9537 | 1122 | } |
| af8e9eeb | 1123 | |
| ed7a9537 | 1124 | return $nodetype; |
| a892f30b | 1125 | } |