fix TinyMCE gzip path issue
[project/tinymce.git] / tinymce.module
CommitLineData
6f760c55
MW
1<?php
2// $Id$
76a1692d
MW
3// A collaborative project by Matt Westgate <drupal at asitis dot org>,
4// Richard Bennett <richard.b@ at ritechnologies dot com> and Jeff Robbins <robbins at jjeff dot com>
6f760c55
MW
5
6/**
7 * @file
8 * Integrate the TinyMCE editor (http://tinymce.moxiecode.com/) into Drupal.
9 */
10
11/**
12 * Implementation of hook_menu().
6f760c55
MW
13 */
14function tinymce_menu($may_cache) {
01a85ffd 15 $items = array();
277d4328
MW
16 if ($may_cache) {
17 $items[] = array('path' => 'admin/settings/tinymce', 'title' => t('tinymce'),
18 'callback' => 'tinymce_admin',
19 'access' => user_access('administer tinymce'));
01a85ffd
MW
20 }
21 return $items;
6f760c55
MW
22}
23
24/**
25 * Implementation of hook_help().
26 */
27function tinymce_help($section) {
28 switch ($section) {
29 case 'admin/modules#description':
30 return t('The TinyMCE Javascript HTML WYSIWYG editor.');
6f760c55
MW
31 case 'admin/settings/tinymce#pages':
32 return "node/*\nuser/*\ncomment/*";
2227c39d 33 case 'admin/settings/tinymce':
32dcf62b 34 return t('<p>TinyMCE adds what-you-see-is-what-you-get (WYSIWYG) HTML editing to textareas, enabling users to create rich content.</p><p>TinyMCE Profiles are based on user roles, and defines for example, what pages receive TinyMCE capabilities, what buttons or themes are enabled for the editor, how the editor is displayed, and a few other settings. Users may disable the editor for any textarea without reloading the page. This setting can be reversed so that pages load with conventional textarea form fields. A link below each textarea allows TinyMCE to be turned on or off "on the fly".</p><p>Be aware that things can get confusing if a user is a member of a role defined in multiple profiles. In this case, the user will receive the profile for the role with the lowest role id they belong to. Did I mention it was confusing?</p><p>lastly, only users with the <code>access tinymce</code> permission will be able to use TinyMCE.</p>');
6f760c55
MW
35 }
36}
37
38/**
39 * Implementation of hook_perm().
40 */
41function tinymce_perm() {
01a85ffd 42 return array('administer tinymce', 'access tinymce');
6f760c55
MW
43}
44
45/**
64d74024
MW
46 * Implementation of hook_img_assist_head().
47 */
48function tinymce_img_assist_head() {
619695bd 49 // The tinymce docs say to include tiny_mce_popup.js, but this was killing IE!
71e75abb 50 $popup_path = base_path() . drupal_get_path('module', 'tinymce'). '/tinymce/jscripts/tiny_mce/tiny_mce_popup.js';
76a1692d
MW
51 $img_assist_prop = $img_template = '';
52 if (module_exist('img_assist')) {
71e75abb 53 $img_assist_prop = base_path() . drupal_get_path('module', 'img_assist'). '/properties.js';
0bdcb567 54 $img_assist_prop = '<script type="text/javascript" src="'. $img_assist_prop .'"></script>';
76a1692d
MW
55
56 $img_template = variable_get('img_assist_img_html', img_assist_help('img_assist/template'));
d286eb02
MW
57 $nl = "\n";
58 $img_template = preg_replace('/\n|\r|(\r\n)/m', '\\'. $nl, $img_template);
76a1692d 59 }
093240f8 60 $clean_url = variable_get('clean_url', 0);
64d74024
MW
61
62$output = <<<EOD
76a1692d 63$img_assist_prop
0bdcb567 64<script type="text/javascript">
093240f8 65 var clean_url = $clean_url;
d286eb02 66 var img_template = '$img_template';
093240f8 67
64d74024
MW
68 function insertImage(form) {
69 if (window.opener) {
093240f8
MW
70 form['edit[filepath]'].value = window.opener.tinyMCE.convertURL(form['edit[filepath]'].value);
71 form['edit[nodePath]'].value = window.opener.tinyMCE.convertURL(form['edit[nodePath]'].value);
72
73 var img = generate_image_tag(form, 'html');
76a1692d 74 //img = img.replace(/\\r|\\n|\\t/g, '');
93c073b0 75
65badaba 76 window.opener.tinyMCE.execInstanceCommand(myTextarea.name, 'mceInsertContent', false, img, true);
64d74024
MW
77 }
78 }
79</script>
80EOD;
81
82 return $output;
83}
84
85/**
86 * Implementation of hook_img_assist_on_submit().
87 */
88function tinymce_img_assist_on_submit() {
89 return 'parent.insertImage(this.form);';
90}
91
92/**
5120a0c6 93 * Implementation of hook_elements().
64d74024 94 */
5120a0c6 95function tinymce_elements() {
eb76ebc7
MW
96 $type = array();
97
98 if (user_access('access tinymce')) {
f9ec7c08
TS
99 // Set resizable to false to avoid drupal.js resizable function from taking control of the textarea
100 $type['textarea'] = array('#process' => array('tinymce_process_textarea' => array()), '#resizable' => FALSE);
eb76ebc7
MW
101 }
102
5120a0c6
MW
103 return $type;
104}
105
106/**
107 * Attach tinymce to a textarea
108 */
109function tinymce_process_textarea($element) {
dd7d7335 110 static $is_running = FALSE;
6f760c55 111 global $user;
6a17f63a 112 static $profile_name;
d8e137a6 113
5120a0c6
MW
114 //$element is an array of attributes for the textarea but there is no just 'name' value, so we extract this from the #id field
115 $textarea_name = substr($element['#id'], strpos($element['#id'], '-') + 1);
6f760c55 116
01a85ffd
MW
117 // Since tinymce_config() makes a db hit, only call it when we're pretty sure
118 // we're gonna render tinymce.
5120a0c6
MW
119 if (!$profile_name) {
120 $profile_name = db_result(db_query('SELECT s.name FROM {tinymce_settings} s INNER JOIN {tinymce_role} r ON r.name = s.name WHERE r.rid IN (%s)', implode(',', array_keys($user->roles))));
01a85ffd 121 }
5120a0c6
MW
122 $profile = tinymce_profile_load($profile_name);
123 $init = tinymce_config($profile);
124 $init['elements'] = 'edit['. $textarea_name .']';
6739c75d 125
5120a0c6 126 if (_tinymce_page_match($profile)) {
2227c39d
MW
127 // Merge user-defined TinyMCE settings.
128 $init = (array) theme('tinymce_theme', $init, $textarea_name, $init['theme'], $is_running);
5120a0c6
MW
129
130 // If $init array is empty no need to execute rest of code since there are no textareas to theme with TinyMCE
131 if (count($init) < 1) {
132 return $element;
133 }
d8e137a6 134
2227c39d 135 $settings = array();
6739c75d 136 foreach ($init as $k => $v) {
a59a8ef6 137 $v = is_array($v) ? implode(',', $v) : $v;
76a1692d
MW
138 // Don't wrap the JS init in quotes for boolean values or functions.
139 if (strtolower($v) != 'true' && strtolower($v) != 'false' && $v[0] != '{') {
01a85ffd
MW
140 $v = '"'. $v. '"';
141 }
142 $settings[] = $k. ' : '. $v;
6739c75d 143 }
2b031c84 144 $tinymce_settings = implode(",\n ", $settings);
6739c75d 145
76a1692d 146 if (module_exist('img_assist')) {
71e75abb
TS
147 $img_assist_js_on = base_path() . url('img_assist/add&editor=tinymce') .'&textarea=';
148 $img_assist_js_off = base_path() . url('img_assist/add') .'&textarea=';
149 $img_assist_on = base_path() . url('img_assist/add&editor=tinymce') .'&textarea=edit['. $textarea_name .']';
150 $img_assist_off = base_path() . url('img_assist/add') .'&textarea=edit['. $textarea_name .']';
93c073b0
MW
151 }
152
277d4328
MW
153 $enable = t('enable rich-text');
154 $disable = t('disable rich-text');
155
01a85ffd 156$tinymce_invoke = <<<EOD
0bdcb567 157<script type="text/javascript">
6f760c55 158 tinyMCE.init({
6739c75d 159 $tinymce_settings
6f760c55 160 });
65badaba 161</script>
277d4328
MW
162EOD;
163
164$js_toggle = <<<EOD
0bdcb567 165<script type="text/javascript">
277d4328
MW
166 function mceToggle(id, linkid) {
167 element = document.getElementById(id);
168 link = document.getElementById(linkid);
169 img_assist = document.getElementById('img_assist-link-'+ id);
170
171 if (tinyMCE.getEditorId(element.name) == null) {
172 tinyMCE.addMCEControl(element, element.name);
173 element.togg = 'on';
174 link.innerHTML = '$disable';
175 link.href = "javascript:mceToggle('" +id+ "', '" +linkid+ "');";
176 if (img_assist)
65badaba 177 img_assist.href = "$img_assist_js_on"+ element.name;
277d4328
MW
178 link.blur();
179 }
180 else {
181 tinyMCE.removeMCEControl(tinyMCE.getEditorId(element.name));
182 element.togg = 'off';
183 link.innerHTML = '$enable';
184 link.href = "javascript:mceToggle('" +id+ "', '" +linkid+ "');";
185 if (img_assist)
65badaba 186 img_assist.href = "$img_assist_js_off"+ element.name;
277d4328
MW
187 link.blur();
188 }
189 }
6f760c55
MW
190</script>
191EOD;
192
75d3842c 193$status = isset($user->tinymce_status) ? $user->tinymce_status : variable_get('tinymce_default_state', 0);
277d4328
MW
194$link_text = $status == 1 ? $disable : $enable;
195$no_wysiwyg = t('Your current web browser does not support WYSIWYG editing.');
01a85ffd 196$wysiwyg_link = <<<EOD
0bdcb567 197<script type="text/javascript">
6a17f63a
MW
198 img_assist = document.getElementById('img_assist-link-edit-$textarea_name');
199 if (img_assist) {
200 img_assist.href = tinyMCE.getEditorId('edit-$textarea_name') == null ? "$img_assist_on" : "$img_assist_off";
201 }
01a85ffd 202 if (typeof(document.execCommand) == 'undefined') {
e473c3ca 203 img_assist.href = "$img_assist_off";
0bdcb567 204 document.write('<div style="font-size:x-small">$no_wysiwyg</div>');
01a85ffd
MW
205 }
206 else {
0bdcb567 207 document.write("<div><a href=\"javascript:mceToggle('edit-$textarea_name', 'wysiwyg4$textarea_name');\" id=\"wysiwyg4$textarea_name\">$link_text</a></div>");
01a85ffd
MW
208 }
209</script>
210EOD;
211
65badaba 212 // We only load the TinyMCE js file once per request
76a1692d 213 if (!$is_running) {
dd7d7335 214 $is_running = TRUE;
1689159f
MW
215 $tinymce_mod_path = drupal_get_path('module', 'tinymce');
216 if (is_dir($tinymce_mod_path.'/imagemanager/')) {
9a6185a0 217 // if tinymce imagemanager is installed
71e75abb 218 drupal_add_js($tinymce_mod_path .'/imagemanager/jscripts/mcimagemanager.js');
9a6185a0 219 }
1689159f 220 // TinyMCE Compressor
64a13268 221 if (file_exists($tinymce_mod_path . '/tinymce/jscripts/tiny_mce/tiny_mce_gzip.php')) {
71e75abb 222 drupal_add_js($tinymce_mod_path . '/tinymce/jscripts/tiny_mce/tiny_mce_gzip.php');
1689159f
MW
223 }
224 else {
225 // For some crazy reason IE will only load this JS file if the absolute reference is given to it.
71e75abb 226 drupal_add_js($tinymce_mod_path . '/tinymce/jscripts/tiny_mce/tiny_mce.js');
1689159f 227 }
277d4328
MW
228 drupal_set_html_head($js_toggle);
229 // We have to do this becuase of some unfocused CSS in certain themes. See http://drupal.org/node/18879 for details
230 drupal_set_html_head('<style type="text/css" media="all">.mceEditor img { display: inline; }</style>');
dd7d7335 231 }
65badaba 232 // Load a TinyMCE init for each textarea.
a59a8ef6 233 if ($init) drupal_set_html_head($tinymce_invoke);
d8e137a6 234
5120a0c6
MW
235 // Make sure to append to #suffix so it isn't completely overwritten
236 $element['#suffix'] .= $wysiwyg_link;
6f760c55 237 }
5120a0c6
MW
238
239 return $element;
6f760c55
MW
240}
241
242/**
243 * Implementation of hook_user().
244 */
245function tinymce_user($type, &$edit, &$user, $category = NULL) {
dd7d7335 246 if ($type == 'form' && $category == 'account' && user_access('access tinymce')) {
9670911b 247 $user_status = $edit['tinymce_status'] != NULL ? $edit['tinymce_status'] : ($user->tinymce_status != NULL ? $user->tinymce_status : variable_get('tinymce_default_state', 0));
32dcf62b 248 $form['tinymce'] = array('#type' => 'fieldset', '#title' => t('Rich-text settings'), '#weight' => 5, '#collapsible' => TRUE, '#collapsed' => TRUE);
d8e137a6 249 $form['tinymce']['tinymce_status'] = array('#type' => 'radios', '#title' => t('Default status'), '#default_value' => $user_status, '#options' => array(t('Off'), t('On')), '#description' => t('Should rich-text editing be enabled or disabled by default in textarea fields?'));
a48b5273 250 return array('tinymce' => $form);
6f760c55
MW
251 }
252 if ($type == 'validate') {
01a85ffd 253 return array('tinymce_status' => $edit['tinymce_status']);
6f760c55
MW
254 }
255}
256
257/**
6739c75d
MW
258 * @addtogroup themeable
259 * @{
260 */
261
262/**
ae7b55ca 263 * Customize a TinyMCE theme.
6739c75d
MW
264 *
265 * @param init
ae7b55ca
MW
266 * An array of settings TinyMCE should invoke a theme. You may override any
267 * of the TinyMCE settings. Details here:
6739c75d
MW
268 *
269 * http://tinymce.moxiecode.com/wrapper.php?url=tinymce/docs/using.htm
ae7b55ca
MW
270 *
271 * @param textarea_name
272 * The name of the textarea TinyMCE wants to enable.
273 *
274 * @param theme_name
2227c39d
MW
275 * The default tinymce theme name to be enabled for this textarea. The
276 * sitewide default is 'simple', but the user may also override this.
dd7d7335
MW
277 *
278 * @param is_running
279 * A boolean flag that identifies id TinyMCE is currently running for this
2227c39d 280 * request life cycle. It can be ignored.
6739c75d 281 */
dd7d7335 282function theme_tinymce_theme($init, $textarea_name, $theme_name, $is_running) {
9670911b 283 switch ($textarea_name) {
2227c39d 284 // Disable tinymce for these textareas
1161cf9b 285 case 'log': // book and page log
2227c39d 286 case 'img_assist_pages':
4048ba98 287 case 'caption': // signature
097b5629 288 case 'pages':
5120a0c6 289 case 'access_pages': //TinyMCE profile settings.
af1fa2b0
TS
290 case 'user_mail_welcome_body': // user config settings
291 case 'user_mail_approval_body': // user config settings
292 case 'user_mail_pass_body': // user config settings
293 case 'synonyms': // taxonomy terms
294 case 'description': // taxonomy terms
2227c39d
MW
295 unset($init);
296 break;
297
298 // Force the 'simple' theme for some of the smaller textareas.
9670911b
MW
299 case 'signature':
300 case 'site_mission':
301 case 'site_footer':
f3d0d7eb
TS
302 case 'site_offline_message':
303 case 'page_help':
304 case 'user_registration_help':
305 case 'user_picture_guidelines':
9670911b 306 $init['theme'] = 'simple';
a59a8ef6
MW
307 foreach ($init as $k => $v) {
308 if (strstr($k, 'theme_advanced_')) unset($init[$k]);
309 }
2227c39d 310 break;
9670911b
MW
311 }
312
2227c39d 313 // Add some extra features when using the advanced theme.
ae7b55ca
MW
314 switch ($theme_name) {
315 case 'advanced':
a59a8ef6 316 //$init['extended_valid_elements'] = array('a[href|target|name|title|onclick]');
2227c39d 317 break;
ae7b55ca 318 }
2227c39d
MW
319
320 // Always return $init; !!
321 return $init;
6739c75d
MW
322}
323
324/** @} End of addtogroup themeable */
325
326/**
6f760c55
MW
327 * Grab the themes available to TinyMCE.
328 *
329 * TinyMCE themes control the functionality and buttons that are available to a
330 * user. Themes are only looked for within the default TinyMCE theme directory.
331 *
a59a8ef6
MW
332 * NOTE: This function is not used in this release. We are only using advanced theme.
333 *
6f760c55
MW
334 * @return
335 * An array of theme names.
336 */
337function _tinymce_get_themes() {
338 static $themes = array();
339
340 if (!$themes) {
341 $theme_loc = drupal_get_path('module', 'tinymce') .'/tinymce/jscripts/tiny_mce/themes/';
342 if (is_dir($theme_loc) && $dh = opendir($theme_loc)) {
343 while (($file = readdir($dh)) !== false) {
ae24db96 344 if (!in_array($file, array('.', '..', 'CVS')) && is_dir($theme_loc . $file)) {
6f760c55
MW
345 $themes[$file] = $file;
346 }
347 }
348 closedir($dh);
349 asort($themes);
350 }
351 }
352
353 return $themes;
354}
355
a59a8ef6
MW
356/**
357 * Return plugin metadata from the plugin registry.
358 *
359 * We also scrape each plugin's *.js file for the human friendly name and help
360 * text URL of each plugin.
361 *
362 * @return
363 * An array for each plugin.
364 */
365function _tinymce_get_buttons($skip_metadata = TRUE) {
366 include_once(drupal_get_path('module', 'tinymce'). '/plugin_reg.php');
367 $plugins = _tinymce_plugins();
368 if ($skip_metadata == FALSE && is_array($plugins)) {
369 foreach ($plugins as $name => $plugin) {
370 $file = drupal_get_path('module', 'tinymce'). '/tinymce/jscripts/tiny_mce/plugins/'. $name .'/editor_plugin_src.js';
371 // Grab the plugin metadata by scanning the *.js file.
372 if (file_exists($file)) {
a48b5273 373 $lines = file($file);
a59a8ef6
MW
374 $has_longname = FALSE;
375 $has_infourl = FALSE;
376 foreach ($lines as $line) {
377 if ($has_longname && $has_infourl) break;
378 if (strstr($line, 'longname')) {
379 $start = strpos($line, "'") + 1;
380 $end = strrpos($line, "'") - $start;
381 $metadata[$name]['longname'] = substr($line, $start, $end);
382 $has_longname = TRUE;
383 }
384 elseif (strstr($line, 'infourl')) {
385 $start = strpos($line, "'") + 1;
386 $end = strrpos($line, "'") - $start;
387 $metadata[$name]['infourl'] = substr($line, $start, $end);
388 $has_infourl = TRUE;
389 }
390 }
391 }
392
393 // Find out the buttons a plugin has.
394 foreach ($plugin as $k => $v) {
395 if (strstr($k, 'theme_advanced_buttons')) {
396 $metadata[$name]['buttons'] = array_merge((array) $metadata[$name]['buttons'], $plugin[$k]);
397 }
398 }
399 }
400 return $metadata;
401 }
402
403 return $plugins;
404}
01a85ffd
MW
405/********************************************************************
406 * Module Functions :: Public
407 ********************************************************************/
408
409/**
410 * Controller for tinymce administrative settings.
411 */
412function tinymce_admin($arg = NULL) {
d8e137a6 413
01a85ffd
MW
414 $edit = $_POST['edit'];
415 $op = $_POST['op'];
416
417 $op = $arg && !$op ? $arg : $op;
418
419 switch ($op) {
420 case 'add':
421 $breadcrumb[] = array('path' => 'admin', 'title' => t('administer'));
277d4328
MW
422 $breadcrumb[] = array('path' => 'admin/settings/tinymce', 'title' => t('tinymce'));
423 $breadcrumb[] = array('path' => 'admin/settings/tinymce/add', 'title' => t('Add new tinymce profile'));
01a85ffd
MW
424 menu_set_location($breadcrumb);
425 $output = tinymce_profile_form($edit);
426 break;
427
428 case 'edit':
429 drupal_set_title(t('Edit tinymce profile'));
277d4328 430 $output = tinymce_profile_form(tinymce_profile_load(urldecode(arg(4))));
01a85ffd
MW
431 break;
432
433 case 'delete':
277d4328 434 tinymce_profile_delete(urldecode(arg(4)));
01a85ffd 435 drupal_set_message(t('Deleted profile'));
277d4328 436 drupal_goto('admin/settings/tinymce');
01a85ffd
MW
437 break;
438
439 case t('Create profile');
440 case t('Update profile');
441 if (tinymce_profile_validate($edit)) {
442 tinymce_profile_save($edit);
443 $edit['old_name'] ? drupal_set_message(t('Your tinymce profile has been updated.')) : drupal_set_message(t('Your tinymce profile has been created.'));
277d4328 444 drupal_goto('admin/settings/tinymce');
01a85ffd
MW
445 }
446 else {
447 $output = tinymce_profile_form($edit);
448 }
449 break;
450
451 case t('Save settings'):
452 variable_set('tinymce_default_state', $edit['tinymce_default_state']);
e5e7216e 453 variable_set('tinymce_safari_message', $edit['tinymce_safari_message']);
01a85ffd 454 drupal_set_message(t('Settings updated'));
277d4328 455 drupal_goto('admin/settings/tinymce');
01a85ffd
MW
456 break;
457
458 default:
459 drupal_set_title(t('TinyMCE settings (%revision)', array('%revision' => '$Revision$')));
460 //Check if TinyMCE is installed.
461 $tinymce_loc = drupal_get_path('module', 'tinymce') .'/tinymce/';
462 if (!is_dir($tinymce_loc)) {
463 drupal_set_message(t('Could not find the TinyMCE engine installed at <strong>%tinymce-directory</strong>. Please <a href="http://tinymce.moxiecode.com/">download TinyMCE</a>, uncompress it and copy the folder into %tinymce-path.', array('%tinymce-path' => drupal_get_path('module', 'tinymce'), '%tinymce-directory' => $tinymce_loc)), 'error');
464 }
465 $output = tinymce_profile_overview();
466 }
467
a808fa67 468 print theme('page', $output);
01a85ffd
MW
469}
470
471/**
472 * Return an array of initial tinymce config options from the current role.
473 */
474function tinymce_config($profile) {
9670911b 475 global $user;
7248584b 476
a59a8ef6 477 // Drupal theme path.
7248584b
TS
478 $themepath = path_to_theme() . '/';
479 $host = base_path();
01a85ffd 480
195b5d64 481 $settings = $profile->settings;
01a85ffd
MW
482
483 // Build a default list of TinyMCE settings.
9670911b
MW
484
485 // Is tinymce on by default?
75d3842c 486 $status = isset($user->tinymce_status) ? $user->tinymce_status : variable_get('tinymce_default_state', 0);
ef6204c6 487
76a1692d
MW
488 $init['mode'] = $status == 1 ? 'exact' : 'none';
489 $init['theme'] = $settings['theme'] ? $settings['theme'] : 'simple';
7248584b 490 $init['document_base_url'] = "$host";
1da6d2bb 491 $init['language'] = $settings['language'] ? $settings['language'] : 'en';
e5e7216e 492 $init['safari_warning'] = variable_get('tinymce_safari_message', 0) ? 'true' : 'false';
ef6204c6 493 $init['entity_encoding'] = 'raw';
76a1692d 494 $init['verify_html'] = $settings['verify_html'] ? $settings['verify_html'] : 'false';
76a1692d 495 $init['preformatted'] = $settings['preformatted'] ? $settings['preformatted'] : 'false';
a59a8ef6 496 $init['convert_fonts_to_styles'] = $settings['convert_fonts_to_styles'] ? $settings['convert_fonts_to_styles'] : 'false';
7248584b 497
93c073b0 498 if ($init['theme'] == 'advanced') {
a59a8ef6 499 $init['plugins'] = array();
76a1692d
MW
500 $init['theme_advanced_toolbar_location'] = $settings['toolbar_loc'] ? $settings['toolbar_loc'] : 'bottom';
501 $init['theme_advanced_toolbar_align'] = $settings['toolbar_align'] ? $settings['toolbar_align'] : 'left';
23044442
MW
502 $init['theme_advanced_path_location'] = $settings['path_loc'] ? $settings['path_loc'] : 'bottom';
503 $init['theme_advanced_resizing'] = $settings['resizing'] ? $settings['resizing'] : 'true';
76a1692d 504 $init['theme_advanced_blockformats'] = $settings['block_formats'] ? $settings['block_formats'] : 'p,address,pre,h1,h2,h3,h4,h5,h6';
a59a8ef6 505
5120a0c6 506 if (is_array($settings['buttons'])) {
a59a8ef6
MW
507 // This gives us the $plugins variable.
508 $plugins = _tinymce_get_buttons();
509
510 // Find the enabled buttons and the mce row they belong on. Also map the
511 // plugin metadata for each button.
512 $plugin_tracker = array();
513 foreach ($plugins as $rname => $rplugin) { // Plugin name
514 foreach ($rplugin as $mce_key => $mce_value) { // TinyMCE key
515 foreach ($mce_value as $k => $v) { // Buttons
5120a0c6 516 if ($settings['buttons'][$rname . '-' . $v]) {
c6bfd92a
TS
517 // Font isn't a true plugin, rather it's buttons made available by the advanced theme
518 if (!in_array($rname, $plugin_tracker) && $rname != 'font') $plugin_tracker[] = $rname;
a59a8ef6
MW
519 $init[$mce_key][] = $v;
520 }
521 }
522 }
17e0f529
TS
523 // Some advanced plugins only have an $rname and no buttons
524 if ($settings['buttons'][$rname]) {
525 if (!in_array($rname, $plugin_tracker)) $plugin_tracker[] = $rname;
526 }
a59a8ef6
MW
527 }
528
529 // Add the rest of the TinyMCE config options to the $init array for each button.
530 if (is_array($plugin_tracker)) {
531 foreach ($plugin_tracker as $pname) {
532 if ($pname != 'default') $init['plugins'][] = $pname;
533 foreach ($plugins[$pname] as $mce_key => $mce_value) {
17e0f529
TS
534 // Don't overwrite buttons or extended_valid_elements
535 if ($mce_key == 'extended_valid_elements') {
536 // $mce_value is an array for extended_valid_elements so just grab the first element in the array (never more than one)
537 $init[$mce_key][] = $mce_value[0];
538 }
539 else if (!strstr($mce_key, 'theme_advanced_buttons')) {
a59a8ef6
MW
540 $init[$mce_key] = $mce_value;
541 }
542 }
543 }
544 }
545
546 // Cleanup
547 foreach ($init as $mce_key => $mce_value) {
548 if (is_array($mce_value)) $mce_value = array_unique($mce_value);
549 $init[$mce_key] = $mce_value;
550 }
551
552 // Shuffle buttons around so that row 1 always has the most buttons,
553 // followed by row 2, etc. Note: These rows need to be set to NULL otherwise
554 // TinyMCE loads it's own buttons inherited from the theme.
555 if (!$init['theme_advanced_buttons1']) $init['theme_advanced_buttons1'] = array();
556 if (!$init['theme_advanced_buttons2']) $init['theme_advanced_buttons2'] = array();
557 if (!$init['theme_advanced_buttons3']) $init['theme_advanced_buttons3'] = array();
558
559 $min_btns = 5; // Minimum number of buttons per row.
d5f8e20a 560 $num1 = count($init['theme_advanced_buttons1']);
a59a8ef6
MW
561 $num2 = count($init['theme_advanced_buttons2']);
562 $num3 = count($init['theme_advanced_buttons3']);
563
564 if ($num3 < $min_btns) {
565 $init['theme_advanced_buttons2'] = array_merge($init['theme_advanced_buttons2'], $init['theme_advanced_buttons3']);
566 $init['theme_advanced_buttons3'] = array();
d5f8e20a 567 $num2 = count($init['theme_advanced_buttons2']);
a59a8ef6
MW
568 }
569 if ($num2 < $min_btns) {
570 $init['theme_advanced_buttons1'] = array_merge($init['theme_advanced_buttons1'], $init['theme_advanced_buttons2']);
d5f8e20a
TS
571 // Squish the rows together, since row 2 is empty
572 $init['theme_advanced_buttons2'] = $init['theme_advanced_buttons3'];
573 $init['theme_advanced_buttons3'] = array();
574 $num1 = count($init['theme_advanced_buttons1']);
a59a8ef6 575 }
d5f8e20a
TS
576 if ($num1 < $min_btns) {
577 $init['theme_advanced_buttons1'] = array_merge($init['theme_advanced_buttons1'], $init['theme_advanced_buttons2']);
578 // Squish the rows together, since row 2 is empty
579 $init['theme_advanced_buttons2'] = $init['theme_advanced_buttons3'];
580 $init['theme_advanced_buttons3'] = array();
581 }
582
a59a8ef6 583 }
93c073b0 584 }
01a85ffd 585
ad6e88a9 586 if ($settings['css_classes']) $init['theme_advanced_styles'] = $settings['css_classes'];
01a85ffd
MW
587
588 if ($settings['css_setting'] == 'theme') {
26444876 589 $css = $themepath . 'style.css';
01a85ffd 590 if (file_exists($css)) {
26444876 591 $init['content_css'] = $host . $css;
01a85ffd 592 }
9a6185a0 593 }
26444876
JR
594 else if ($settings['css_setting'] == 'self') {
595 $init['content_css'] = str_replace(array('%h', '%t'), array($host, $themepath), $settings['css_path']);
596 }
a59a8ef6 597
01a85ffd
MW
598 return $init;
599}
600
6f760c55 601/**
01a85ffd
MW
602 * Remove a profile from the database.
603 */
604function tinymce_profile_delete($name) {
195b5d64
MW
605 db_query("DELETE FROM {tinymce_settings} WHERE name = '%s'", $name);
606 db_query("DELETE FROM {tinymce_role} WHERE name = '%s'", $name);
01a85ffd
MW
607}
608
609/**
610 * Return an HTML form for profile configuration.
611 */
612function tinymce_profile_form($edit) {
d8e137a6 613 $edit = (object) $edit;
01a85ffd
MW
614
615 // Only display the roles that currently don't have a tinymce profile. One
616 // profile per role.
4048ba98 617 $orig_roles = user_roles(FALSE, 'access tinymce');
01a85ffd 618 $roles = $orig_roles;
277d4328 619 if (arg(3) == 'add') {
195b5d64 620 $result = db_query('SELECT DISTINCT(rid) FROM {tinymce_role}');
01a85ffd 621 while ($data = db_fetch_object($result)) {
195b5d64 622 unset($roles[$data->rid]);
01a85ffd 623 }
5120a0c6 624 if (!$orig_roles) {
32dcf62b 625 drupal_set_message(t('You must <a href="%access-control-url">assign</a> at least one role with the \'access tinymce\' permission before creating a profile.', array('%access-control-url' => url('admin/access'))), 'error');
5120a0c6
MW
626 }
627 else if (!$roles) {
4048ba98 628 drupal_set_message(t('You will not be allowed to create a new profile since all user roles have already been assigned profiles. Either remove an existing tinymce profile from at least one role or assign another role the \'access tinymce\' permission.'), 'error');
01a85ffd
MW
629 }
630 else if (count($orig_roles) != count($roles)) {
631 drupal_set_message(t('Not all user roles are shown since they already have tinymce profiles. You must first unassign profiles in order to add them to a new one.'));
632 }
633 $btn = t('Create profile');
634 }
635 else {
a48b5273 636 $form['old_name'] = array('#type' => 'hidden', '#value' => $edit->name);
01a85ffd
MW
637 $btn = t('Update profile');
638 }
639
a48b5273 640 $form['basic'] = array('#type' => 'fieldset', '#title' => t('Basic setup'), '#collapsible' => TRUE, '#collapsed' => TRUE);
32dcf62b
MW
641 $form['basic']['name'] = array('#type' => 'textfield', '#title' => t('Profile name'), '#default_value' => $edit->name, '#size' => 40, '#maxlength' => 128, '#description' => t('Enter a name for this profile. This name is only visible within the tinymce administration page.'), '#required' => TRUE);
642 $form['basic']['rids'] = array('#type' => 'checkboxes', '#title' => t('Roles allowed to use this profile'), '#default_value' => array_keys((array) $edit->rids), '#options' => $roles, '#description' => t('Check at least one role. Only roles with \'access tinymce\' permission will be shown here.'), '#required' => TRUE);
643 // This line upgrades previous versions of TinyMCE for user who previously selected a theme other than advanced.
644 if ($edit->settings['theme'] != 'advanced') $edit->settings['theme'] = 'advanced';
a48b5273 645 $form['basic']['theme'] = array('#type' => 'hidden', '#value' => $edit->settings['theme'] ? $edit->settings['theme'] : 'advanced');
1da6d2bb 646 $languages = drupal_map_assoc(array('ar', 'ca', 'cs', 'cy', 'da', 'de', 'el', 'en', 'es', 'fa', 'fi', 'fr', 'fr_ca', 'he', 'hu', 'is', 'it', 'ja', 'ko', 'nb', 'nl', 'nn', 'pl', 'pt', 'pt_br', 'ru', 'ru_KOI8-R', 'ru_UTF-8', 'sk', 'sv', 'th', 'zh_cn', 'zh_tw', 'zh_tw_utf8'));
32dcf62b 647 $form['basic']['language'] = array('#type' => 'select', '#title' => t('Language'), '#default_value' => $edit->settings['language'] ? $edit->settings['language'] : 'en', '#options' => $languages, '#description' => t('The language for the TinyMCE interface. Language codes based on the <a href="http://www.loc.gov/standards/iso639-2/englangn.html">ISO-639-2</a> format.'));
c3fb581d
TS
648
649 $form['visibility'] = array('#type' => 'fieldset', '#title' => t('Visibility'), '#collapsible' => TRUE, '#collapsed' => TRUE);
d6185d4c
TS
650 $access = user_access('use PHP for block visibility');
651
652 // If the visibility is set to PHP mode but the user doesn't have this block permission, don't allow them to edit nor see this PHP code
653 if ($edit->settings['access'] == 2 && !$access) {
654 $form['visibility'] = array();
655 $form['visibility']['access'] = array('#type' => 'value', '#value' => 2);
656 $form['visibility']['access_pages'] = array('#type' => 'value', '#value' => $edit->settings['access_pages']);
657 }
658 else {
659 $options = array(t('Show on every page except the listed pages.'), t('Show on only the listed pages.'));
660 $description = t("Enter one page per line as Drupal paths. The '*' character is a wildcard. Example paths are '%blog' for the blog page and %blog-wildcard for every personal blog. %front is the front page.", array('%blog' => theme('placeholder', 'blog'), '%blog-wildcard' => theme('placeholder', 'blog/*'), '%front' => theme('placeholder', '<front>')));
d8e137a6 661
d6185d4c
TS
662 if ($access) {
663 $options[] = t('Show if the following PHP code returns <code>TRUE</code> (PHP-mode, experts only).');
664 $description .= t('If the PHP-mode is chosen, enter PHP code between %php. Note that executing incorrect PHP-code can break your Drupal site.', array('%php' => theme('placeholder', '<?php ?>')));
665 }
666 $form['visibility']['access'] = array('#type' => 'radios', '#title' => t('Show tinymce on specific pages'), '#default_value' => isset($edit->settings['access']) ? $edit->settings['access'] : 1, '#options' => $options);
667 $form['visibility']['access_pages'] = array('#type' => 'textarea', '#title' => t('Pages'), '#default_value' => isset($edit->settings['access_pages']) ? $edit->settings['access_pages'] : tinymce_help('admin/settings/tinymce#pages'), '#description' => $description);
668 }
d8e137a6 669
c3fb581d 670 $form['buttons'] = array('#type' => 'fieldset', '#title' => t('Buttons and plugins'), '#collapsible' => TRUE, '#collapsed' => TRUE, '#tree' => TRUE, '#theme' => 'tinymce_profile_form_buttons');
d8e137a6 671
a59a8ef6
MW
672 $metadata = _tinymce_get_buttons(FALSE);
673 // Generate the button list.
674 foreach($metadata as $name => $meta) {
675 if (is_array($meta['buttons'])) {
676 foreach ($meta['buttons'] as $button) {
677 if ($name != 'default') {
678 $img_src = drupal_get_path('module', 'tinymce'). "/tinymce/jscripts/tiny_mce/plugins/$name/images/$name.gif";
d8e137a6 679
5120a0c6
MW
680 //correct for plugins that have more than one button
681 if (!file_exists($img_src)) {
682 $img_src = drupal_get_path('module', 'tinymce'). "/tinymce/jscripts/tiny_mce/plugins/$name/images/$button.gif";
683 }
a59a8ef6
MW
684 }
685 else {
686 $img_src = drupal_get_path('module', 'tinymce'). "/tinymce/jscripts/tiny_mce/themes/advanced/images/$button.gif";
687 }
d8e137a6 688
71e75abb 689 $b = file_exists($img_src) ? '<img src="'. base_path() . $img_src .'" title="'. $button .'" style="border: 1px solid grey; vertical-align: middle;" />' : $button;
a59a8ef6
MW
690
691 if ($name == 'default') {
692 $title = $b;
693 }
694 else {
695 $title = $metadata[$name]['longname'] ? $metadata[$name]['longname'] : $name;
696 if ($metadata[$name]['infourl']) {
697 $title = '<a href="'. $metadata[$name]['infourl'] .'" target="_blank">'. $title .'</a>';
698 }
5120a0c6 699 $title = $b . ' &#8211; '. $title;
a59a8ef6 700 }
5120a0c6 701 $form_value = $edit->settings['buttons'][$name . '-' . $button];
475be68a 702 $form['buttons'][$name . '-' . $button] = array('#type' => 'checkbox', '#title' => $title, '#default_value' => $form_value);
a59a8ef6
MW
703 }
704 }
705 else {
706 $title = $metadata[$name]['longname'] ? $metadata[$name]['longname'] : $name;
707 if ($metadata[$name]['infourl']) {
708 $title = '<a href="'. $metadata[$name]['infourl'] .'" target="_blank">'. $title .'</a>';
709 }
5120a0c6 710 $form_value = $edit->settings['buttons'][$name];
475be68a 711 $form['buttons'][$name] = array('#type' => 'checkbox', '#title' => $title, '#default_value' => $form_value);
a59a8ef6
MW
712 }
713 }
5120a0c6 714
a48b5273
MW
715 $form['appearance'] = array('#type' => 'fieldset', '#title' => t('Editor appearance'), '#collapsible' => TRUE, '#collapsed' => TRUE);
716 $form['appearance']['toolbar_loc'] = array('#type' => 'select', '#title' => t('Toolbar location'), '#default_value' => $edit->settings['toolbar_loc'], '#options' => array('bottom' => 'bottom', 'top' => 'top'), '#description' => t('Show toolbar at the top or bottom of the editor area?'));
717 $form['appearance']['toolbar_align'] = array('#type' => 'select', '#title' => t('Toolbar alignment'), '#default_value' => $edit->settings['toolbar_align'], '#options' => array('center' => 'center', 'left' => 'left', 'right' => 'right'), '#description' => t('Align tool icons left, center, or right within the toolbar.'));
d8e137a6 718 $form['appearance']['path_loc'] = array('#type' => 'select', '#title' => t('Path location'), '#default_value' => $edit->settings['path_loc'] ? $edit->settings['path_loc'] : 'bottom', '#options' => array('none' => 'none', 'top' => 'top', 'bottom' => 'bottom'), '#description' => t('Path to html elements (i.e. "body>table>tr>td"). Show at top, bottom, or not at all.'));
35c9f82d 719 $form['appearance']['resizing'] = array('#type' => 'select', '#title' => t('Enable resizing button'), '#default_value' => isset($edit->settings['resizing']) ? 'true' : 'false', '#options' => array('false' => 'false', 'true' => 'true'), '#description' => t(' This option gives you the ability to enable/disable the resizing button. If enabled the <strong>Path location toolbar</strong> must be set to "top" or "bottom" in order to display the resize icon.'));
a48b5273 720 $form['appearance']['block_formats'] = array('#type' => 'textfield', '#title' => t('Block formats'), '#default_value' => $edit->settings['block_formats'] ? $edit->settings['block_formats'] : 'p,address,pre,h1,h2,h3,h4,h5,h6', '#size' => 40, '#maxlength' => 250, '#description' => t('Comma separated list of HTML block formats. You can only remove elements, not add.'));
d8e137a6 721
c3fb581d 722 $form['output'] = array('#type' => 'fieldset', '#title' => t('Cleanup and output'), '#collapsible' => TRUE, '#collapsed' => TRUE);
a48b5273
MW
723 $form['output']['verify_html'] = array('#type' => 'select', '#title' => t('Verify HTML'), '#default_value' => $edit->settings['verify_html'], '#options' => array('true' => 'true', 'false' => 'false'), '#description' => t('Should the HTML contents be verified or not? Verifying will strip &lt;head&gt tags, so choose false if you will be editing full page HTML.'));
724 $form['output']['preformatted'] = array('#type' => 'select', '#title' => t('Preformatted'), '#default_value' => $edit->settings['preformatted'], '#options' => array('false' => 'false', 'true' => 'true'), '#description' => t('If this option is set to true, the editor will insert TAB characters on tab and preserve other whitespace characters just like a PRE HTML element does.'));
725 $form['output']['convert_fonts_to_styles'] = array('#type' => 'select', '#title' => t('Convert &lt;font&gt; tags to styles'), '#default_value' => $edit->settings['convert_fonts_to_styles'], '#options' => array('true' => 'true', 'false' => 'false'), '#description' => t('If you set this option to true, font size, font family, font color and font background color will be replaced by inline styles.'));
726
727 $form['css'] = array('#type' => 'fieldset', '#title' => t('CSS'), '#collapsible' => TRUE, '#collapsed' => TRUE);
d8e137a6 728 $form['css']['css_setting'] = array('#type' => 'select', '#title' => t('Editor CSS'), '#default_value' => $edit->settings['css_setting'] ? $edit->settings['css_setting'] : 'theme', '#options' => array('theme' => 'use theme css', 'self' => 'define css', 'none' => 'tinyMCE default'), '#description' => t('Defines the CSS to be used in the editor area.<br />use theme css - load style.css from current site theme.<br/>define css - enter path for css file below.<br />tinyMCE default - uses default CSS from editor.'));
a48b5273 729 $form['css']['css_path'] = array('#type' => 'textfield', '#title' => t('CSS path'), '#default_value' => $edit->settings['css_path'], '#size' => 40, '#maxlength' => 255, '#description' => t('Enter path to CSS file (example: "css/editor.css").<br />Macros: %h (host name: http://www.example.com/), %t (path to theme: theme/yourtheme/)<br />Be sure to select "define css" above.'));
7f1a7900 730 $form['css']['css_classes'] = array('#type' => 'textfield', '#title' => t('CSS classes'), '#default_value' => $edit->settings['css_classes'], '#size' => 40, '#maxlength' => 255, '#description' => t('Adds CSS classes to the "styles" droplist. Format is: &lt;title&gt;=&lt;class&gt;;<br/> Example: Header 1=header1;Header 2=header2;Header 3=header3 (note: no trailing \';\')<br />Leave blank to automatically import list of CSS classes from style sheet.'));
a48b5273
MW
731
732 $form['submit'] = array('#type' => 'submit', '#value' => $btn);
d8e137a6 733
a48b5273
MW
734 $output .= drupal_get_form('tinymce_profile_form', $form);
735
736 return $output;
737}
738
739/**
740 * Layout for the buttons in the tinymce profile form
741 */
742function theme_tinymce_profile_form_buttons($form) {
743 $buttons = array();
d8e137a6 744
a48b5273
MW
745 // Flatten forms array
746 foreach (element_children($form) as $key) {
747 $buttons[] = form_render($form[$key]);
748 }
a59a8ef6 749
5120a0c6
MW
750 //split checkboxes into rows with 3 columns
751 $total = count($buttons);
752 $rows = array();
753 for ($i = 0; $i < $total; $i++) {
754 $row = array();
755 $row[] = array('data' => $buttons[$i]);
756 $row[] = array('data' => $buttons[++$i]);
757 $row[] = array('data' => $buttons[++$i]);
758 $rows[] = $row;
a59a8ef6 759 }
5120a0c6
MW
760
761 $output = theme('table', array(), $rows, array('width' => '100%'));
a59a8ef6 762
a48b5273 763 return $output;
01a85ffd
MW
764}
765
766/**
76a1692d 767 * Load all profiles. Just load one profile if $name is passed in.
01a85ffd
MW
768 */
769function tinymce_profile_load($name = '') {
770 static $profiles = array();
771
772 if (!$profiles) {
65badaba 773 $roles = user_roles();
01a85ffd
MW
774 $result = db_query('SELECT * FROM {tinymce_settings}');
775 while ($data = db_fetch_object($result)) {
776 $data->settings = unserialize($data->settings);
195b5d64 777 $result2 = db_query("SELECT rid FROM {tinymce_role} WHERE name = '%s'", $data->name);
01a85ffd 778 $role = array();
195b5d64
MW
779 while ($r = db_fetch_object($result2)) {
780 $role[$r->rid] = $roles[$r->rid];
01a85ffd
MW
781 }
782 $data->rids = $role;
93c073b0 783
01a85ffd
MW
784 $profiles[$data->name] = $data;
785 }
786 }
93c073b0
MW
787
788 return ($name ? $profiles[$name] : $profiles);
01a85ffd
MW
789}
790
791/**
792 * Controller for tinymce profiles.
793 */
794function tinymce_profile_overview() {
795 $output = '';
01a85ffd
MW
796
797 $profiles = tinymce_profile_load();
798 if ($profiles) {
3b4c16b2 799 $output .= t('<p><a href="%create-profile-url">Create new profile</a></p>', array('%create-profile-url' => url('admin/settings/tinymce/add')));
65badaba 800 $roles = user_roles();
01a85ffd
MW
801 $header = array(t('Profile'), t('Roles'), t('Operations'));
802 foreach ($profiles as $p) {
277d4328 803 $rows[] = array(array('data' => $p->name, 'valign' => 'top'), array('data' => implode("<br />\n", $p->rids)), array('data' => l(t('edit'), 'admin/settings/tinymce/edit/'. urlencode($p->name)) . ' '. l(t('delete'), 'admin/settings/tinymce/delete/'. urlencode($p->name)), 'valign' => 'top'));
01a85ffd
MW
804 }
805 $output .= theme('table', $header, $rows). '<p>&nbsp;</p>';
806 }
807 else {
3b4c16b2 808 drupal_set_message(t('No profiles found. Click here to <a href="%create-profile-url">create a new profile</a>.', array('%create-profile-url' => url('admin/settings/tinymce/add'))));
01a85ffd
MW
809 }
810
a48b5273
MW
811 $form['settings'] = array('#type' => 'fieldset', '#title' => t('Default settings'), '#collapsible' => TRUE);
812 $form['settings']['tinymce_default_state'] = array('#type' => 'radios', '#title' => t('Default tinymce state'), '#default_value' => variable_get('tinymce_default_state', 0), '#options' => array(t('Off'), t('On')), '#description' => t('Should tinymce be enabled or disabled by default when it\'s first loaded from a textarea? Note: The user may override this setting in their profile.'));
e5e7216e
MW
813 $form['settings']['tinymce_safari_message'] = array(
814 '#type' => 'radios', '#title' => t('Safari browser warning'), '#default_value' => variable_get('tinymce_safari_message', 0), '#options' => array(t('Disabled'), t('Enabled')),
815 '#description' => t('TinyMCE support for the Safari web browser is experimental and a warning message is displayed when that browser is detected. You can disable this message here.')
816 );
a48b5273 817 $form['settings']['submit'] = array('#type' => 'submit', '#value' => t('Save settings'));
01a85ffd 818
a48b5273 819 $output .= drupal_get_form('settings', $form);
d8e137a6 820
a48b5273 821 return $output;
01a85ffd
MW
822}
823
824/**
825 * Save a profile to the database.
826 */
827function tinymce_profile_save($edit) {
828 db_query("DELETE FROM {tinymce_settings} WHERE name = '%s' or name = '%s'", $edit['name'], $edit['old_name']);
195b5d64 829 db_query("DELETE FROM {tinymce_role} WHERE name = '%s' or name = '%s'", $edit['name'], $edit['old_name']);
a48b5273
MW
830 db_query("INSERT INTO {tinymce_settings} (name, settings) VALUES ('%s', '%s')", $edit['name'], serialize($edit));
831 foreach ($edit['rids'] as $rid => $value) {
e297a3c0 832 db_query("INSERT INTO {tinymce_role} (name, rid) VALUES ('%s', %d)", $edit['name'], $rid);
195b5d64 833 }
01a85ffd
MW
834}
835
836/**
837 * Profile validation.
838 */
839function tinymce_profile_validate($edit) {
840 $errors = array();
841
842 if (!$edit['name']) {
195b5d64 843 $errors['name'] = t('You must give a profile name.');
01a85ffd
MW
844 }
845
846 if (!$edit['rids']) {
847 $errors['rids'] = t('You must select at least one role.');
848 }
849
850 foreach ($errors as $name => $message) {
851 form_set_error($name, $message);
852 }
853
854 return count($errors) == 0;
855}
856
857/********************************************************************
858 * Module Functions :: Private
859 ********************************************************************/
860
861/**
862 * Determine if TinyMCE has permission to be used on the current page.
6f760c55
MW
863 *
864 * @return
865 * TRUE if can render, FALSE if not allowed.
866 */
01a85ffd 867function _tinymce_page_match($edit) {
c3fb581d
TS
868 $page_match = FALSE;
869
6f760c55 870 //Kill TinyMCE if we're editing a textarea with PHP in it!
9670911b
MW
871 if ($_POST['edit']['format'] == 2) {
872 return FALSE;
6f760c55
MW
873 }
874 else {
875 // PHP input formats are #2 in the filters table.
876 preg_match("|^node/(\d+)(/edit)$|", $_GET['q'], $match);
877 if (intval($match[1]) > 0) {
3b4c16b2 878 if (db_result(db_query('SELECT format FROM {node_revisions} WHERE nid = %d AND vid = %d AND format = 2', $match[1], $match[1]))) {
6f760c55
MW
879 return FALSE;
880 }
881 }
882 }
883
c3fb581d
TS
884 if ($edit->settings['access_pages']) {
885 // If the PHP option wasn't selected
886 if ($edit->settings['access'] < 2) {
6f760c55 887 $path = drupal_get_path_alias($_GET['q']);
c3fb581d
TS
888 $regexp = '/^('. preg_replace(array('/(\r\n?|\n)/', '/\\\\\*/', '/(^|\|)\\\\<front\\\\>($|\|)/'), array('|', '.*', '\1'. preg_quote(variable_get('site_frontpage', 'node'), '/') .'\2'), preg_quote($edit->settings['access_pages'], '/')) .')$/';
889 $page_match = !($edit->settings['access'] xor preg_match($regexp, $path));
890 }
891 else {
892 $page_match = drupal_eval($edit->settings['access_pages']);
6f760c55 893 }
6f760c55 894 }
c3fb581d
TS
895 // No pages were specified to block so show on all
896 else {
897 $page_match = TRUE;
898 }
d8e137a6 899
c3fb581d 900 return $page_match;
6f760c55 901}