fckeditor.module in FCKeditor - WYSIWYG HTML editor 6.2
Same filename and directory in other branches
FCKeditor - The text editor for Internet - http://www.fckeditor.net Copyright (C) 2003-2008 Frederico Caldeira Knabben
== BEGIN LICENSE ==
Licensed under the terms of any of the following licenses at your choice:
- GNU General Public License Version 2 or later (the "GPL") http://www.gnu.org/licenses/gpl.html
- GNU Lesser General Public License Version 2.1 or later (the "LGPL") http://www.gnu.org/licenses/lgpl.html
- Mozilla Public License Version 1.1 or later (the "MPL") http://www.mozilla.org/MPL/MPL-1.1.html
== END LICENSE ==
FCKeditor Module for Drupal 6.x
This module allows Drupal to replace textarea fields with FCKeditor.
This HTML text editor brings to the web many of the powerful functionalities of known desktop editors like Word. It's really lightweight and doesn't require any kind of installation on the client computer.
File
fckeditor.moduleView source
<?php
/**
* FCKeditor - The text editor for Internet - http://www.fckeditor.net
* Copyright (C) 2003-2008 Frederico Caldeira Knabben
*
* == BEGIN LICENSE ==
*
* Licensed under the terms of any of the following licenses at your
* choice:
*
* - GNU General Public License Version 2 or later (the "GPL")
* http://www.gnu.org/licenses/gpl.html
*
* - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
* http://www.gnu.org/licenses/lgpl.html
*
* - Mozilla Public License Version 1.1 or later (the "MPL")
* http://www.mozilla.org/MPL/MPL-1.1.html
*
* == END LICENSE ==
*
* @file
* FCKeditor Module for Drupal 6.x
*
* This module allows Drupal to replace textarea fields with FCKeditor.
*
* This HTML text editor brings to the web many of the powerful functionalities
* of known desktop editors like Word. It's really lightweight and doesn't
* require any kind of installation on the client computer.
*/
/**
* The name of simplified toolbar which should be forced
* Be sure that this toolbar is defined in fckeditor.config.js or fckconfig.js
*/
define('FCKEDITOR_FORCE_SIMPLE_TOOLBAR_NAME', 'DrupalBasic');
global $_fckeditor_configuration;
global $_fckeditor_js_ids;
$_fckeditor_configuration = array();
$_fckeditor_js_ids = array();
function _fckeditor_ckfinder_path() {
return drupal_get_path('module', 'fckeditor') . '/ckfinder/ckfinder.php';
}
/**
* Implementation of hook_help().
*
* This function delegates execution to fckeditor_help_delegate() in fckeditor.help.inc to
* lower the amount of code in fckeditor.module
*/
function fckeditor_help($path, $arg) {
module_load_include('help.inc', 'fckeditor');
return module_invoke('fckeditor', 'help_delegate', $path, $arg);
}
/**
* Implementation of hook_user().
*
* This function delegates execution to fckeditor_user_delegate() in fckeditor.user.inc to
* lower the amount of code in fckeditor.module
*/
function fckeditor_user($type, $edit, &$user, $category = NULL) {
if ($type == 'form' && $category == 'account' && user_access('access fckeditor') || $type == 'validate') {
module_load_include('user.inc', 'fckeditor');
return fckeditor_user_delegate($type, $edit, $user, $category);
}
return NULL;
}
/*
* Run if there is old menu information in database
*/
function fckeditor_admin($arg = NULL) {
drupal_set_message(t('The FCKeditor module is not installed correctly. You should run the !updatephplink immediately.', array(
'!updatephplink' => l(t('database update script'), 'update.php'),
)), 'error');
return FALSE;
}
/**
* Implementation of hook_perm().
* Administer -> User management -> Permissions
*/
function fckeditor_perm() {
return array(
'administer fckeditor',
'access fckeditor',
'allow fckeditor file uploads',
);
}
/**
* Implementation of hook_elements().
* Replace textarea with FCKeditor using callback function (fckeditor_process_textarea)
*/
function fckeditor_elements() {
$type = array();
$type['textfield'] = array(
'#process' => array(
'fckeditor_process_input',
),
);
if (user_access('access fckeditor')) {
// only roles with permission get the fckeditor
if (fckeditor_is_compatible_client()) {
// it would be useless to dig deeper if we're not able or allowed to
$type['textarea'] = array(
'#process' => array(
'fckeditor_process_textarea',
),
);
$type['form'] = array(
'#after_build' => array(
'fckeditor_process_form',
),
);
}
}
return $type;
}
/**
* AJAX callback - XSS filter
*/
function fckeditor_filter_xss() {
global $user;
header('Content-Type: text/plain; charset=utf-8');
$GLOBALS['devel_shutdown'] = FALSE;
if (!isset($_POST['text']) || !is_string($_POST['text']) || !isset($_POST['token']) || !drupal_valid_token($_POST['token'], 'fckeditorAjaxCall', FALSE)) {
exit;
}
$profile = fckeditor_user_get_profile($user);
if ($profile == FALSE) {
exit;
}
$filter_format_id = filter_resolve_format((int) $_POST['input_format']);
if (!filter_access($filter_format_id)) {
exit;
}
$settings = $profile->settings;
$text = $_POST['text'];
$text = strtr($text, array(
'<!--' => '__COMMENT__START__',
'-->' => '__COMMENT__END__',
));
foreach ($settings['filters'] as $module_delta => $active) {
$module = strtok($module_delta, "/");
$delta = strtok("/");
$format = strtok("/");
if (!module_hook($module, 'filter')) {
continue;
}
// Built-in filter module, a special case where we would like to strip XSS and nothing more
if ($module == 'filter' && $delta == 0) {
preg_match_all("|</?([a-z][a-z0-9]*)(?:\\b[^>]*)>|i", $text, $matches);
if ($matches[1]) {
// Sources of inspiration:
// http://www.w3.org/TR/html4/index/elements.html
// http://www.w3.org/TR/html-markup/elements.html
// https://developer.mozilla.org/en-US/docs/Web/HTML/Element
$base_allowed_tags = array(
'a',
'abbr',
'acronym',
'address',
'area',
'article',
'aside',
'audio',
'b',
'base',
'basefont',
'bdi',
'bdo',
'big',
'blockquote',
'body',
'br',
'button',
'canvas',
'caption',
'center',
'cite',
'code',
'col',
'colgroup',
'command',
'datalist',
'dd',
'del',
'details',
'dfn',
'dialog',
'dir',
'div',
'dl',
'dt',
'em',
'fieldset',
'figcaption',
'figure',
'font',
'footer',
'form',
'h1',
'h2',
'h3',
'h4',
'h5',
'h6',
'head',
'header',
'hgroup',
'hr',
'html',
'i',
'img',
'input',
'ins',
'isindex',
'kbd',
'keygen',
'label',
'legend',
'li',
'main',
'map',
'mark',
'menu',
'menuitem',
'meter',
'nav',
'noframes',
'noscript',
'ol',
'optgroup',
'option',
'output',
'p',
'param',
'pre',
'progress',
'q',
'rp',
'rt',
'ruby',
's',
'samp',
'section',
'select',
'small',
'source',
'span',
'strike',
'strong',
'sub',
'summary',
'sup',
'table',
'tbody',
'td',
'textarea',
'tfoot',
'th',
'thead',
'time',
'title',
'tr',
'track',
'tt',
'u',
'ul',
'var',
'video',
'wbr',
);
// Get tags allowed in filter settings
$filter_allowed_tags = preg_split('/\\s+|<|>/', variable_get("allowed_html_{$filter_format_id}", ''), -1, PREG_SPLIT_NO_EMPTY);
// Combine allowed tags
$tags = array_merge($base_allowed_tags, $filter_allowed_tags);
// Tags provided by hook
$hooks_allowed_tags = module_invoke_all('fckeditor_filter_xss_allowed_tags');
if (!empty($hooks_allowed_tags) && is_array($hooks_allowed_tags)) {
foreach ($hooks_allowed_tags as $tag) {
if (!empty($tag) && is_string($tag) && !in_array($tag, $tags)) {
array_push($tags, $tag);
}
}
}
$text = filter_xss($text, $tags);
}
}
else {
$text = module_invoke($module, 'filter', 'process', $delta, $format, $text);
}
}
$text = strtr($text, array(
'__COMMENT__START__' => '<!--',
'__COMMENT__END__' => '-->',
));
echo $text;
exit;
}
function fckeditor_process_form(&$form) {
global $_fckeditor_configuration, $_fckeditor_js_ids;
static $processed_textareas = array();
static $found_textareas = array();
//Skip if:
// - we're not editing an element
// - fckeditor is not enabled (configuration is empty)
if (arg(1) == "add" || arg(1) == "reply" || !count($_fckeditor_configuration)) {
return $form;
}
$fckeditor_filters = array();
// Iterate over element children; resetting array keys to access last index.
if ($children = array_values(element_children($form))) {
foreach ($children as $index => $item) {
$element =& $form[$item];
if (isset($element['#id']) && in_array($element['#id'], array_keys($_fckeditor_js_ids))) {
$found_textareas[$element['#id']] =& $element;
}
// filter_form() always uses the key 'format'. We need a type-agnostic
// match to prevent false positives. Also, there must have been at least
// one element on this level.
if ($item === 'format' && $index > 0) {
// Make sure we either match a input format selector or input format
// guidelines (displayed if user has access to one input format only).
if (isset($element['#type']) && $element['#type'] == 'fieldset' || isset($element['format']['guidelines'])) {
// The element before this element is the target form field.
$field =& $form[$children[$index - 1]];
$textarea_id = $field['#id'];
// The following condition may fail when there are textareas with formats that do not have FCKeditor enabled.
if (isset($_fckeditor_js_ids[$textarea_id])) {
$js_id = $_fckeditor_js_ids[$textarea_id];
array_push($processed_textareas, $js_id);
//search for checkxss1/2 class
if (empty($field['#attributes']['class']) || strpos($field['#attributes']['class'], "checkxss") === FALSE) {
continue;
}
// Determine the available input formats. The last child element is a
// link to "More information about formatting options". When only one
// input format is displayed, we also have to remove formatting
// guidelines, stored in the child 'format'.
$formats = element_children($element);
foreach ($formats as $format_id) {
$format = !empty($element[$format_id]['#default_value']) ? $element[$format_id]['#default_value'] : $element[$format_id]['#value'];
break;
}
$enabled = filter_list_format($format);
$fckeditor_filters = array();
//loop through all enabled filters
foreach ($enabled as $id => $filter) {
//but use only that one selected in FCKeditor profile
if (in_array($id, array_keys($_fckeditor_configuration[$textarea_id]['filters'])) && $_fckeditor_configuration[$textarea_id]['filters'][$id]) {
if (!isset($fckeditor_filters[$js_id])) {
$fckeditor_filters[$js_id] = array();
}
$fckeditor_filters[$js_id][] = $id . "/" . $format;
}
}
drupal_add_js(array(
'fckeditor' => array(
'settings' => array(
$textarea_id => array(
'input_format' => $format,
),
),
),
), 'setting');
//No filters assigned, remove xss class
if (empty($fckeditor_filters[$js_id])) {
$field['#attributes']['class'] = preg_replace("/checkxss(1|2)/", "", $field['#attributes']['class']);
}
else {
$field['#attributes']['class'] = strtr($field['#attributes']['class'], array(
"checkxss1" => "filterxss1",
"checkxss2" => "filterxss2",
));
}
array_pop($formats);
unset($formats['format']);
}
}
// If this element is 'format', do not recurse further.
continue;
}
// Recurse into children.
fckeditor_process_form($element);
}
}
//We're in a form
if (isset($form['#action'])) {
//some textareas associated with FCKeditor has not been processed
if (count($processed_textareas) < count($_fckeditor_js_ids)) {
//loop through all found textfields
foreach (array_keys($found_textareas) as $id) {
$element =& $found_textareas[$id];
//if not processed yet (checkxss class is before final processing)
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'])) {
//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
$js_id = $_fckeditor_js_ids[$element['#id']];
$fckeditor_filters[$js_id][] = "filter/0/1";
$element['#attributes']['class'] = strtr($element['#attributes']['class'], array(
"checkxss1" => "filterxss1",
"checkxss2" => "filterxss2",
));
}
}
}
}
if (!empty($fckeditor_filters)) {
drupal_add_js(array(
'fckeditor_filters' => $fckeditor_filters,
), 'setting');
}
return $form;
}
/**
* Allow more than 255 chars in Allowed HTML tags textfield
*/
function fckeditor_process_input($element) {
if ($element['#id'] == 'edit-allowed-html-1') {
$element['#maxlength'] = max($element['#maxlength'], 1024);
}
return $element;
}
/**
* Implementation of hook_menu().
*/
function fckeditor_menu() {
$items = array();
$items['fckeditor/xss'] = array(
'title' => 'XSS Filter',
'description' => 'XSS Filter.',
'page callback' => 'fckeditor_filter_xss',
'access arguments' => array(
'access fckeditor',
),
'type' => MENU_CALLBACK,
);
$items['admin/settings/fckeditor'] = array(
'title' => 'FCKeditor',
'description' => 'Configure the rich text editor.',
'page callback' => 'fckeditor_admin_main',
'file' => 'fckeditor.admin.inc',
'access arguments' => array(
'administer fckeditor',
),
'type' => MENU_NORMAL_ITEM,
);
$items['admin/settings/fckeditor/add'] = array(
'title' => 'Add new FCKeditor profile',
'description' => 'Configure the rich text editor.',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'fckeditor_admin_profile_form',
),
'file' => 'fckeditor.admin.inc',
'access arguments' => array(
'administer fckeditor',
),
'type' => MENU_CALLBACK,
);
$items['admin/settings/fckeditor/clone/%fckeditor_profile'] = array(
'title' => 'Clone FCKeditor profile',
'description' => 'Configure the rich text editor.',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'fckeditor_admin_profile_clone_form',
4,
),
'file' => 'fckeditor.admin.inc',
'access arguments' => array(
'administer fckeditor',
),
'type' => MENU_CALLBACK,
);
$items['admin/settings/fckeditor/edit/%fckeditor_profile'] = array(
'title' => 'Edit FCKeditor profile',
'description' => 'Configure the rich text editor.',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'fckeditor_admin_profile_form',
4,
),
'file' => 'fckeditor.admin.inc',
'access arguments' => array(
'administer fckeditor',
),
'type' => MENU_CALLBACK,
);
$items['admin/settings/fckeditor/delete/%fckeditor_profile'] = array(
'title' => 'Delete FCKeditor profile',
'description' => 'Configure the rich text editor.',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'fckeditor_admin_profile_delete_form',
4,
),
'file' => 'fckeditor.admin.inc',
'access arguments' => array(
'administer fckeditor',
),
'type' => MENU_CALLBACK,
);
$items['admin/settings/fckeditor/addg'] = array(
'title' => 'Add FCKeditor Global profile',
'description' => 'Configure the rich text editor.',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'fckeditor_admin_global_profile_form',
'add',
),
'file' => 'fckeditor.admin.inc',
'access arguments' => array(
'administer fckeditor',
),
'type' => MENU_CALLBACK,
);
$items['admin/settings/fckeditor/editg'] = array(
'title' => 'Edit FCKeditor Global profile',
'description' => 'Configure the rich text editor.',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'fckeditor_admin_global_profile_form',
'edit',
),
'file' => 'fckeditor.admin.inc',
'access arguments' => array(
'administer fckeditor',
),
'type' => MENU_CALLBACK,
);
// img_assist integration
$items['img_assist/load/fckeditor'] = array(
'title' => 'Image assist',
'page callback' => 'fckeditor_wrapper_img_assist_loader',
'file' => 'fckeditor.user.inc',
'access arguments' => array(
'access img_assist',
),
'type' => MENU_CALLBACK,
);
return $items;
}
/**
* Implementation of hook_init().
*/
function fckeditor_init() {
drupal_add_css(drupal_get_path('module', 'fckeditor') . '/fckeditor.css');
}
/**
* Implementation of hook_file_download().
* Support for private downloads.
* FCKeditor does not implement any kind of potection on private files.
*/
function fckeditor_file_download($file) {
if ($path = file_create_path($file)) {
$result = db_query("SELECT f.* FROM {files} f WHERE filepath = '%s'", $path);
if (db_fetch_object($result)) {
return NULL;
}
//No info in DB? Probably a file uploaded with FCKeditor
$global_profile = fckeditor_profile_load("FCKeditor Global Profile");
//Assume that files inside of fckeditor directory belong to the FCKeditor. If private directory is set, let the decision about protection to the user.
$private_dir = isset($global_profile->settings['private_dir']) ? trim($global_profile->settings['private_dir'], '\\/') : '';
$private_dir = preg_quote($private_dir, '#');
$private_dir = strtr($private_dir, array(
'%u' => '(\\d+)',
'%n' => '([\\x80-\\xF7 \\w@.-]+)',
));
// regex for %n taken from user_validate_name() in user.module
$private_dir = trim($private_dir, '\\/');
$regex = '#^' . preg_quote(file_directory_path() . '/', '#') . $private_dir . '#';
//If path to the file points to the FCKeditor private directory, allow downloading
if (preg_match($regex, $path)) {
$ctype = ($info = @getimagesize($path)) ? $info['mime'] : (function_exists('mime_content_type') ? mime_content_type($path) : 'application/x-download');
return array(
'Content-Type: ' . $ctype,
);
}
}
}
/**
* Load all profiles. Just load one profile if $name is passed in.
*/
function fckeditor_profile_load($name = '', $clear = FALSE) {
static $profiles = array();
if (empty($profiles) || $clear === TRUE) {
$result = db_query("SELECT * FROM {fckeditor_settings}");
while ($data = db_fetch_object($result)) {
$data->settings = unserialize($data->settings);
$data->rids = array();
$profiles[$data->name] = $data;
}
$roles = user_roles();
$result = db_query("SELECT name, rid FROM {fckeditor_role}");
while ($data = db_fetch_object($result)) {
$profiles[$data->name]->rids[$data->rid] = $roles[$data->rid];
}
}
return $name ? isset($profiles[urldecode($name)]) ? $profiles[urldecode($name)] : FALSE : $profiles;
}
/**
* @param int $excl_mode 1/include, exclude otherwise
* @param string $excl_regex paths (drupal paths with ids attached)
* @param string $element_id current ID
* @param string $get_q current path
*
* @return boolean
* returns true if FCKeditor is enabled
*/
function fckeditor_is_enabled($excl_mode, $excl_regex, $element_id, $get_q) {
$front = variable_get('site_frontpage', 'node');
$excl_regex = str_replace('<front>', $front, $excl_regex);
$nodetype = fckeditor_get_nodetype($get_q);
$element_id = str_replace('.', '\\.', $element_id);
$match = !empty($excl_regex) && preg_match($excl_regex, $nodetype . '@' . $get_q . '.' . $element_id);
return $excl_mode == '0' xor $match;
}
/**
* This function create the HTML objects required for the FCKeditor
*
* @param $element
* A fully populated form elment to add the editor to
* @return
* The same $element with extra FCKeditor markup and initialization
*/
function fckeditor_process_textarea($element) {
static $is_running = FALSE;
static $num = 1;
global $user, $language, $_fckeditor_configuration, $_fckeditor_js_ids;
$enabled = TRUE;
//hack for module developers that want to disable FCKeditor on their textareas
if (key_exists('#wysiwyg', $element) && !$element['#wysiwyg']) {
return $element;
}
if (isset($element['#access']) && !$element['#access']) {
return $element;
}
//skip this one, surely nobody wants WYSIWYG here
switch ($element['#id']) {
case 'edit-log':
return $element;
break;
}
if (isset($element['#attributes']['disabled']) && $element['#attributes']['disabled'] == 'disabled') {
return $element;
}
$global_profile = fckeditor_profile_load('FCKeditor Global Profile');
if ($global_profile) {
$global_conf = $global_profile->settings;
if ($global_conf) {
$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']);
}
}
if ($enabled) {
$profile = fckeditor_user_get_profile($user, $element['#id']);
if ($profile) {
$conf = array();
$conf = $profile->settings;
if ($conf['allow_user_conf'] == 't') {
foreach (array(
'default',
'show_toggle',
'popup',
'skin',
'toolbar',
'expand',
'width',
'lang',
'auto_lang',
) as $setting) {
$conf[$setting] = fckeditor_user_get_setting($user, $profile, $setting);
}
}
if ($conf['popup'] == 't' && $conf['show_toggle'] == 't') {
$conf['show_toggle'] = 'f';
}
}
else {
$enabled = FALSE;
}
}
//old profile info, assume Filtered HTML is enabled
if (!isset($conf['ss'])) {
$conf['ss'] = 2;
$conf['filters']['filter/0'] = 1;
}
if (!isset($conf['filters'])) {
$conf['filters'] = array();
}
$themepath = fckeditor_path_to_theme() . '/';
$host = base_path();
if (!isset($element['#suffix'])) {
$element['#suffix'] = '';
}
// only replace textarea when it has enough rows and it is enabled
if ($enabled && ($element['#rows'] > $conf['min_rows'] || $conf['min_rows'] <= 1 && empty($element['#rows']))) {
$textarea_id = $element['#id'];
if (!isset($element['#attributes'])) {
$element['#attributes'] = array();
}
if (!isset($element['#attributes']['class'])) {
$element['#attributes']['class'] = 'fckeditor';
}
else {
$element['#attributes']['class'] .= ' fckeditor';
}
$js_id = 'oFCK_' . $num++;
$_fckeditor_js_ids[$element['#id']] = $js_id;
$fckeditor_on = $conf['default'] == 't' ? 1 : 0;
$xss_check = 0;
//it's not a problem when adding new content/comment
if (arg(1) != "add" && arg(1) != "reply") {
$_fckeditor_configuration[$element['#id']] = $conf;
//let FCKeditor know when perform XSS checks auto/manual
if ($conf['ss'] == 1) {
$xss_class = 'checkxss1';
}
else {
$xss_class = 'checkxss2';
}
$element['#attributes']['class'] .= ' ' . $xss_class;
$xss_check = 1;
}
//settings are saved as strings, not booleans
if ($conf['show_toggle'] == 't') {
$content = '';
if (isset($element['#post']['teaser_js'])) {
$content .= $element['#post']['teaser_js'] . '<!--break-->';
}
$content .= $element['#value'];
$wysiwyg_link = '';
$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\"" : "") . ">";
$wysiwyg_link .= $fckeditor_on ? t('Switch to plain text editor') : t('Switch to rich text editor');
$wysiwyg_link .= '</a>';
// Make sure to append to #suffix so it isn't completely overwritten
$element['#suffix'] .= $wysiwyg_link;
}
//convert contents to HTML if necessary
if ($conf['autofixplaintext'] == 't') {
module_load_include('lib.inc', 'fckeditor');
if (fckeditor_is_plaintext($element['#value'])) {
$element['#value'] = _filter_autop($element['#value']);
}
}
// setting some variables
$module_drupal_path = drupal_get_path('module', 'fckeditor');
$module_full_path = $host . $module_drupal_path;
$editor_path = fckeditor_path(FALSE);
$editor_local_path = fckeditor_path(TRUE);
// get the default drupal files path
$files_path = $host . file_directory_path();
// module_drupal_path:
// 'modules/fckeditor' (length=17)
// module_full_path:
// '/drupal5/modules/fckeditor' (length=26)
// files_path:
// '/drupal5/files' (length=14)
// configured in settings
$width = $conf['width'];
// sensible default for small toolbars
$height = intval($element['#rows']) * 14 + 140;
if (!$is_running) {
drupal_add_js($module_drupal_path . '/fckeditor.utils.js');
/* In D6 drupal_add_js() can't add external JS, in D7 use drupal_add_js(...,'external') */
drupal_set_html_head('<script type="text/javascript" src="' . $editor_path . '/fckeditor.js?I"></script>');
drupal_add_js(array(
'fckeditor' => array(
'ajaxToken' => drupal_get_token('fckeditorAjaxCall'),
),
), 'setting');
$is_running = TRUE;
}
$toolbar = $conf['toolbar'];
//$height += 100; // for larger toolbars
$force_simple_toolbar = fckeditor_is_enabled('1', empty($conf['simple_incl_regex']) ? '' : $conf['simple_incl_regex'], $element['#id'], $_GET['q']);
if (!$force_simple_toolbar) {
$force_simple_toolbar = fckeditor_is_enabled('1', empty($global_conf['simple_incl_regex']) ? '' : $global_conf['simple_incl_regex'], $element['#id'], $_GET['q']);
}
if ($force_simple_toolbar) {
$toolbar = FCKEDITOR_FORCE_SIMPLE_TOOLBAR_NAME;
}
if (!empty($conf['theme_config_js']) && $conf['theme_config_js'] == 't' && file_exists($themepath . 'fckeditor.config.js')) {
$fckeditor_config_path = $host . $themepath . 'fckeditor.config.js?' . @filemtime($themepath . 'fckeditor.config.js');
}
else {
$fckeditor_config_path = $module_full_path . "/fckeditor.config.js?" . @filemtime($module_drupal_path . "/fckeditor.config.js");
}
$js = $js_id . " = new FCKeditor( '" . $textarea_id . "' );\n" . $js_id . ".defaultState = " . ($fckeditor_on && $conf['popup'] == 'f' ? 1 : 0) . ";\n" . $js_id . ".BasePath = '" . $editor_path . "/';\n" . $js_id . ".DrupalId = '" . $js_id . "';\n" . $js_id . ".Config['PluginsPath'] = '" . $module_full_path . "/plugins/';\n" . $js_id . ".Config['CustomConfigurationsPath'] = \"" . $fckeditor_config_path . "\";\n" . $js_id . ".Config['TextareaID'] = \"" . $element['#id'] . "\";\n" . $js_id . ".Config['BodyId'] = \"" . $element['#id'] . "\";";
//if ($conf['appearance_conf'] == 'f') {
$js .= "\n" . $js_id . ".ToolbarSet = \"" . $toolbar . "\";\n" . $js_id . ".Config['SkinPath'] = " . $js_id . ".BasePath + \"editor/skins/" . $conf['skin'] . "/\";\n" . $js_id . ".Config['DefaultLanguage'] = \"" . $conf['lang'] . "\";\n" . $js_id . ".Config['AutoDetectLanguage'] = " . ($conf['auto_lang'] == "t" ? "true" : "false") . ";\n" . $js_id . ".Height = \"" . $height . "\";\n" . $js_id . ".Config['ToolbarStartExpanded'] = " . ($conf['expand'] == "t" ? "true" : "false") . ";\n" . $js_id . ".Width = \"" . $width . "\";\n";
//}
//if ($conf['output_conf'] == 'f') {
$js .= "\n" . $js_id . ".Config['EnterMode'] = '" . $conf['enter_mode'] . "';\n" . $js_id . ".Config['ShiftEnterMode'] = \"" . $conf['shift_enter_mode'] . "\";\n" . $js_id . ".Config['FontFormats'] = \"" . str_replace(",", ";", $conf['font_format']) . "\";\n" . $js_id . ".Config['FormatSource'] = " . ($conf['format_source'] == "t" ? "true" : "false") . ";\n" . $js_id . ".Config['FormatOutput'] = " . ($conf['format_output'] == "t" ? "true" : "false") . ";\n";
//}
if (defined('LANGUAGE_RTL') && $language->direction == LANGUAGE_RTL) {
$js .= $js_id . ".Config['ContentLangDirection'] = 'rtl';\n";
}
// add code for filebrowser for users that have access
if (user_access('allow fckeditor file uploads') == 1) {
$filebrowser = !empty($conf['filebrowser']) ? $conf['filebrowser'] : 'none';
if ($filebrowser == 'imce' && !module_exists('imce')) {
$filebrowser = 'none';
}
if ($filebrowser == 'ib' && !module_exists('imagebrowser')) {
$filebrowser = 'none';
}
if ($filebrowser == 'webfm' && !module_exists('webfm_popup')) {
$filebrowser = 'none';
}
if ($filebrowser == 'ckfinder' && !file_exists(_fckeditor_ckfinder_path())) {
$filebrowser = 'none';
}
$quickupload = !empty($conf['quickupload']) && $conf['quickupload'] == 't';
// load variables used by both quick upload and filebrowser
// and assure that the $_SESSION variables are loaded
if ($quickupload || $filebrowser == 'builtin') {
if (file_exists($editor_local_path . "/editor/filemanager/connectors/php/connector.php")) {
$connector_path = $editor_path . "/editor/filemanager/connectors/php/connector.php";
}
elseif (file_exists($editor_local_path . "/editor/filemanager/upload/php/connector.php")) {
$connector_path = $editor_path . "/editor/filemanager/upload/php/connector.php";
}
if (file_exists($editor_local_path . "/editor/filemanager/connectors/php/upload.php")) {
$upload_path = $editor_path . "/editor/filemanager/connectors/php/upload.php";
}
elseif (file_exists($editor_local_path . "/editor/filemanager/upload/php/upload.php")) {
$upload_path = $editor_path . "/editor/filemanager/upload/php/upload.php";
}
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,
));
}
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,
));
}
if (variable_get('file_downloads', '') == FILE_DOWNLOADS_PRIVATE) {
$private_dir = isset($global_profile->settings['private_dir']) ? trim($global_profile->settings['private_dir'], '\\/') : '';
if (!empty($private_dir)) {
$private_dir = strtr($private_dir, array(
'%u' => $user->uid,
'%n' => $user->name,
));
$_SESSION['FCKeditor']['UserFilesPath'] = url('system/files') . '/' . $private_dir . '/';
$_SESSION['FCKeditor']['UserFilesAbsolutePath'] = realpath(file_directory_path()) . DIRECTORY_SEPARATOR . $private_dir . DIRECTORY_SEPARATOR;
}
else {
$_SESSION['FCKeditor']['UserFilesPath'] = url('system/files') . '/';
$_SESSION['FCKeditor']['UserFilesAbsolutePath'] = realpath(file_directory_path()) . DIRECTORY_SEPARATOR;
}
}
}
if ($quickupload) {
$js .= $js_id . ".Config['LinkUpload'] = true;\n";
$js .= $js_id . ".Config['ImageUpload'] = true;\n";
$js .= $js_id . ".Config['FlashUpload'] = true;\n";
$js .= $js_id . ".Config['LinkUploadURL'] = '" . $upload_path . "';\n";
$js .= $js_id . ".Config['ImageUploadURL'] = '" . $upload_path . "?Type=Image';\n";
$js .= $js_id . ".Config['FlashUploadURL'] = '" . $upload_path . "?Type=Flash';\n";
}
else {
$js .= $js_id . ".Config['LinkUpload'] = false;\n";
$js .= $js_id . ".Config['ImageUpload'] = false;\n";
$js .= $js_id . ".Config['FlashUpload'] = false;\n";
}
switch ($filebrowser) {
case 'imce':
$js .= $js_id . ".Config['LinkBrowser']= true;\n";
$js .= $js_id . ".Config['ImageBrowser']= true;\n";
$js .= $js_id . ".Config['FlashBrowser']= true;\n";
$js .= $js_id . ".Config['LinkBrowserURL']= '" . $host . "index.php?q=imce&app=FCKEditor|url@txtLnkUrl,txtUrl';\n";
$js .= $js_id . ".Config['ImageBrowserURL']= '" . $host . "index.php?q=imce&app=FCKEditor|url@txtUrl|width@txtWidth|height@txtHeight';\n";
$js .= $js_id . ".Config['FlashBrowserURL']= '" . $host . "index.php?q=imce&app=FCKEditor|url@txtUrl';\n";
break;
case 'webfm':
$js .= $js_id . ".Config['LinkBrowser']= true;\n";
$js .= $js_id . ".Config['ImageBrowser']= true;\n";
$js .= $js_id . ".Config['FlashBrowser']= true;\n";
$js .= $js_id . ".Config['ImageDlgHideLink']= true;\n";
$js .= $js_id . ".Config['LinkBrowserURL']= '" . $host . "index.php?q=webfm_popup&url=txtUrl&caller=fckeditor';\n";
$js .= $js_id . ".Config['ImageBrowserURL']= '" . $host . "index.php?q=webfm_popup&url=txtUrl&caller=fckeditor';\n";
$js .= $js_id . ".Config['FlashBrowserURL']= '" . $host . "index.php?q=webfm_popup&url=txtUrl&caller=fckeditor';\n";
break;
case 'builtin':
$js .= $js_id . ".Config['LinkBrowser'] = true;\n";
$js .= $js_id . ".Config['ImageBrowser'] = true;\n";
$js .= $js_id . ".Config['FlashBrowser'] = true;\n";
$js .= $js_id . ".Config['LinkBrowserURL'] = '" . $editor_path . "/editor/filemanager/browser/default/browser.html?Connector=" . $connector_path . "&ServerPath=" . $files_path . "';\n";
$js .= $js_id . ".Config['ImageBrowserURL'] = '" . $editor_path . "/editor/filemanager/browser/default/browser.html?Type=Image&Connector=" . $connector_path . "&ServerPath=" . $files_path . "';\n";
$js .= $js_id . ".Config['FlashBrowserURL'] = '" . $editor_path . "/editor/filemanager/browser/default/browser.html?Type=Flash&Connector=" . $connector_path . "&ServerPath=" . $files_path . "';\n";
break;
case 'ib':
$js .= $js_id . ".Config['ImageBrowser']= true;\n";
$js .= $js_id . ".Config['LinkBrowser']= true;\n";
$js .= $js_id . ".Config['FlashBrowser']= false;\n";
$js .= $js_id . ".Config['ImageBrowserURL']= '" . $host . "index.php?q=imagebrowser/view/browser&app=FCKEditor';\n";
$js .= $js_id . ".Config['LinkBrowserURL']= '" . $host . "index.php?q=imagebrowser/view/browser&app=FCKEditor';\n";
$js .= $js_id . ".Config['ImageBrowserWindowWidth']= '680';";
$js .= $js_id . ".Config['ImageBrowserWindowHeight'] = '439';";
$js .= $js_id . ".Config['LinkBrowserWindowWidth']= '680';";
$js .= $js_id . ".Config['LinkBrowserWindowHeight'] = '439';";
break;
case 'ckfinder':
$js .= $js_id . ".Config['LinkBrowser'] = true;\n";
$js .= $js_id . ".Config['ImageBrowser'] = true;\n";
$js .= $js_id . ".Config['FlashBrowser'] = true;\n";
$js .= $js_id . ".Config['LinkBrowserURL'] = '" . $module_full_path . "/ckfinder/ckfinder.html';\n";
$js .= $js_id . ".Config['ImageBrowserURL'] = '" . $module_full_path . "/ckfinder/ckfinder.html?type=Images';\n";
$js .= $js_id . ".Config['FlashBrowserURL'] = '" . $module_full_path . "/ckfinder/ckfinder.html?type=Flash';\n";
break;
default:
case 'none':
$js .= $js_id . ".Config['LinkBrowser'] = false;\n";
$js .= $js_id . ".Config['ImageBrowser'] = false;\n";
$js .= $js_id . ".Config['FlashBrowser'] = false;\n";
break;
}
}
else {
$js .= $js_id . ".Config['LinkBrowser'] = false;\n";
$js .= $js_id . ".Config['ImageBrowser'] = false;\n";
$js .= $js_id . ".Config['FlashBrowser'] = false;\n";
$js .= $js_id . ".Config['LinkUpload'] = false;\n";
$js .= $js_id . ".Config['ImageUpload'] = false;\n";
$js .= $js_id . ".Config['FlashUpload'] = false;\n";
}
if (!empty($conf['js_conf'])) {
$lines = preg_split("/[\n\r]+/", $conf['js_conf']);
foreach ($lines as $l) {
if (strlen($l) > 5) {
$eqpos = strpos($l, '=');
if (FALSE !== $eqpos) {
$option = str_replace('FCKConfig.', '', substr($l, 0, $eqpos));
$js .= "\n" . $js_id . ".Config['" . trim($option) . "'] =" . substr($l, $eqpos + 1);
}
}
}
}
// add custom xml stylesheet if it exists
if (!empty($conf['css_style']) && $conf['css_style'] == 'theme') {
if (file_exists($themepath . 'fckstyles.xml')) {
$styles_xml_path = $host . $themepath . 'fckstyles.xml';
$js .= $js_id . ".Config['StylesXmlPath'] = \"" . $styles_xml_path . "\";\n";
}
}
elseif (!empty($conf['css_style']) && $conf['css_style'] == 'self') {
$conf['styles_path'] = str_replace("%h%t", "%t", $conf['styles_path']);
$js .= $js_id . ".Config['StylesXmlPath'] = \"" . str_replace(array(
'%h',
'%t',
'%m',
), array(
$host,
$host . $themepath,
$module_drupal_path,
), $conf['styles_path']) . "\";\n";
}
// add custom xml templae if it exists
if (!empty($conf['templatefile_mode']) && $conf['templatefile_mode'] == 'theme') {
if (file_exists($themepath . 'fcktemplates.xml')) {
$styles_xml_path = $host . $themepath . 'fcktemplates.xml';
$js .= $js_id . ".Config['TemplatesXmlPath'] = \"" . $styles_xml_path . "\";\n";
}
}
elseif (!empty($conf['templatefile_mode']) && $conf['templatefile_mode'] == 'self') {
$conf['templatefile_path'] = str_replace("%h%t", "%t", $conf['templatefile_path']);
$js .= $js_id . ".Config['TemplatesXmlPath'] = \"" . str_replace(array(
'%h',
'%t',
'%m',
), array(
$host,
$host . $themepath,
$module_drupal_path,
), $conf['templatefile_path']) . "\";\n";
}
// add custom stylesheet if configured
// lets hope it exists but we'll leave that to the site admin
$cssfiles = array(
$module_full_path . '/fckeditor.css',
);
switch ($conf['css_mode']) {
case 'theme':
global $language, $theme, $theme_info, $base_theme_info;
$style_css = $themepath . 'style.css';
if (!empty($theme_info->stylesheets)) {
$css_files = array();
$editorcss = "\"";
foreach ($base_theme_info as $base) {
// Grab stylesheets from base theme
if (!empty($base->stylesheets)) {
// may be empty when the base theme reference in the info file is invalid
foreach ($base->stylesheets as $type => $stylesheets) {
if ($type != "print") {
foreach ($stylesheets as $name => $path) {
if (file_exists($path)) {
$css_files[$name] = $host . $path;
}
}
}
}
}
}
if (!empty($theme_info->stylesheets)) {
// Grab stylesheets from current theme
foreach ($theme_info->stylesheets as $type => $stylesheets) {
if ($type != "print") {
foreach ($stylesheets as $name => $path) {
if (file_exists($path)) {
$css_files[$name] = $host . $path;
}
elseif (!empty($css_files[$name])) {
unset($css_files[$name]);
}
}
}
}
}
if (!empty($css_files)) {
$editorcss .= implode(",", $css_files) . ",";
}
// Grab stylesheets from color module
$color_paths = variable_get('color_' . $theme . '_stylesheets', array());
if (defined('LANGUAGE_RTL') && $language->direction == LANGUAGE_RTL) {
if (!empty($color_paths[1])) {
$editorcss .= $host . $color_paths[1] . ",";
}
}
elseif (!empty($color_paths[0])) {
$editorcss .= $host . $color_paths[0] . ",";
}
$editorcss .= $module_full_path . "/fckeditor.css\";\n";
$js .= $js_id . ".Config['EditorAreaCSS'] = " . $editorcss;
}
elseif (file_exists($style_css)) {
$js .= $js_id . ".Config['EditorAreaCSS'] = \"" . $host . $style_css . "," . $module_full_path . "/fckeditor.css\";";
}
else {
$js .= $js_id . ".Config['EditorAreaCSS'] = \"" . $module_full_path . "/fckeditor.css\";";
}
break;
case 'self':
$conf['css_path'] = str_replace("%h%t", "%t", $conf['css_path']);
$cssfiles[] = str_replace(array(
'%h',
'%t',
), array(
$host,
$host . $themepath,
), $conf['css_path']);
$js .= $js_id . ".Config['EditorAreaCSS'] = '" . implode(',', $cssfiles) . "';\n";
break;
case 'none':
$js .= $js_id . ".Config['EditorAreaCSS'] = " . $js_id . ".BasePath + 'editor/css/fck_editorarea.css,' + '" . implode(',', $cssfiles) . "';\n";
break;
}
if ($num == 2) {
$js .= 'var fckInstances = {};';
}
$js .= 'fckInstances[\'' . $textarea_id . '\'] = ' . $js_id . ";\n";
drupal_add_js('var ' . $js_id . ';if (Drupal.jsEnabled) {' . $js . '}', 'inline');
if ($conf['popup'] == 't') {
$element['#suffix'] .= ' <span class="fckeditor_popuplink">(<a href="#" onclick="FCKeditor_OpenPopup(\'' . $module_full_path . '/fckeditor.popup.html\', \'' . $js_id . '\', \'' . $element['#id'] . '\', \'' . $conf['width'] . '\'); return false;">' . t('Open rich text editor') . "</a>)</span>";
}
}
// display the field id for administrators
if (user_access('administer fckeditor') && (!isset($global_conf['show_fieldnamehint']) || $global_conf['show_fieldnamehint'] == 't')) {
module_load_include('admin.inc', 'fckeditor');
$element['#suffix'] .= '<div class="textarea-identifier description">' . t('The ID for !excludingorincludinglink this element is %fieldname.', array(
'!excludingorincludinglink' => l(t('excluding or including'), 'admin/settings/fckeditor'),
'%fieldname' => fckeditor_rule_to_string(fckeditor_rule_create(fckeditor_get_nodetype($_GET['q']), $_GET['q'], $element['#id'])),
)) . '</div>';
}
return $element;
}
/**
* sort roles according to precedence settings. previously sorted roles are followed by latest added roles.
*/
function fckeditor_sorted_roles($clear = FALSE) {
static $order;
if (isset($order) && $clear !== TRUE) {
return $order;
}
$order = array();
$roles = user_roles(0, 'access fckeditor');
$result = db_query("SELECT settings FROM {fckeditor_settings} WHERE name='FCKeditor Global Profile'");
$data = db_fetch_object($result);
if (!empty($data->settings)) {
$settings = unserialize($data->settings);
if (isset($settings['rank']) && !empty($settings['rank'])) {
foreach ($settings['rank'] as $rid) {
if (isset($roles[$rid])) {
$order[$rid] = $roles[$rid];
unset($roles[$rid]);
}
}
}
}
krsort($roles);
//sort the remaining unsorted roles by id, descending.
$order += $roles;
return $order;
}
/**
* Test if client can render the FCKeditor
* Use built-in test method in fckeditor.php
* If fckeditor.php is not found, return false (probably in such case fckeditor is not installed correctly)
*
* @return
* TRUE if the browser is reasonably capable
*/
function fckeditor_is_compatible_client() {
$editor_local_path = fckeditor_path(TRUE);
$fckeditor_main_file = $editor_local_path . '/fckeditor.php';
if (!function_exists('version_compare') || version_compare(phpversion(), '5', '<')) {
$fckeditor_target_file = $editor_local_path . '/fckeditor_php4.php';
}
else {
$fckeditor_target_file = $editor_local_path . '/fckeditor_php5.php';
}
if (file_exists($fckeditor_target_file)) {
include_once $fckeditor_target_file;
//FCKeditor 2.6.1+
if (function_exists('FCKeditor_IsCompatibleBrowser')) {
return FCKeditor_IsCompatibleBrowser();
}
elseif (class_exists('FCKeditor')) {
//FCKeditor 2.5.1 up to 2.6 with definition of FCKeditor_IsCompatibleBrowser() in fckeditor.php
if (filesize($fckeditor_main_file) > 1500) {
include_once $fckeditor_main_file;
}
//FCKeditor 2.5.0 and earlier
$fck = new FCKeditor('fake');
return $fck
->IsCompatible();
}
}
return FALSE;
}
/**
* Read FCKeditor path from Global profile
*
* @return
* path to FCKeditor folder
*/
function fckeditor_path($local = FALSE) {
static $fck_path;
static $fck_local_path;
if (!$fck_path) {
$mod_path = drupal_get_path('module', 'fckeditor');
$global_profile = fckeditor_profile_load('FCKeditor Global Profile');
//default: path to fckeditor subdirectory in the fckeditor module directory (starting from the document root)
//e.g. for http://example.com/drupal it will be /drupal/sites/all/modules/fckeditor/fckeditor
$fck_path = base_path() . $mod_path . '/fckeditor';
//default: path to fckeditor subdirectory in the fckeditor module directory (relative to index.php)
//e.g.: sites/all/modules/fckeditor/fckeditor
$fck_local_path = $mod_path . '/fckeditor';
if ($global_profile) {
$gs = $global_profile->settings;
if (isset($gs['fckeditor_path'])) {
$tmp_path = $gs['fckeditor_path'];
$tmp_path = strtr($tmp_path, array(
"%b" => base_path(),
"%m" => base_path() . $mod_path,
));
$tmp_path = str_replace('\\', '/', $tmp_path);
$tmp_path = str_replace('//', '/', $tmp_path);
$tmp_path = rtrim($tmp_path, ' \\/');
if (substr($tmp_path, 0, 1) != '/') {
$tmp_path = '/' . $tmp_path;
//starts with '/'
}
$fck_path = $tmp_path;
if (empty($gs['fckeditor_local_path'])) {
//fortunately wildcards are used, we can easily get the right server path
if (false !== strpos($gs['fckeditor_path'], "%m")) {
$gs['fckeditor_local_path'] = strtr($gs['fckeditor_path'], array(
"%m" => $mod_path,
));
}
if (false !== strpos($gs['fckeditor_path'], "%b")) {
$gs['fckeditor_local_path'] = strtr($gs['fckeditor_path'], array(
"%b" => ".",
));
}
}
}
//fckeditor_path is defined, but wildcards are not used, we need to try to find out where is
//the document root located and append fckeditor_path to it.
if (!empty($gs['fckeditor_local_path'])) {
$fck_local_path = $gs['fckeditor_local_path'];
}
elseif (!empty($gs['fckeditor_path'])) {
module_load_include('lib.inc', 'fckeditor');
$local_path = fckeditor_resolve_url($gs['fckeditor_path'] . "/");
if (FALSE !== $local_path) {
$fck_local_path = $local_path;
}
}
}
}
if ($local) {
return $fck_local_path;
}
else {
return $fck_path;
}
}
function fckeditor_user_get_setting($user, $profile, $setting) {
$default = array(
'default' => 't',
'show_toggle' => 't',
'popup' => 'f',
'skin' => 'default',
'toolbar' => 'default',
'expand' => 't',
'width' => '100%',
'lang' => 'en',
'auto_lang' => 't',
);
if ($profile->settings['allow_user_conf']) {
$status = isset($user->{'fckeditor_' . $setting}) ? $user->{'fckeditor_' . $setting} : (isset($profile->settings[$setting]) ? $profile->settings[$setting] : $default[$setting]);
}
else {
$status = isset($profile->settings[$setting]) ? $profile->settings[$setting] : $default[$setting];
}
return $status;
}
function fckeditor_user_get_profile($user, $element_id = NULL) {
$rids = array();
// Since fckeditor_profile_load() makes a db hit, only call it when we're pretty sure
// we're gonna render fckeditor.
$sorted_roles = fckeditor_sorted_roles();
foreach (array_keys($sorted_roles) as $rid) {
if (isset($user->roles[$rid])) {
$rids[] = $rid;
}
}
if ($user->uid == 1 && !sizeof($rids)) {
$r = db_fetch_object(db_query_range("SELECT r.rid FROM {fckeditor_role} r ORDER BY r.rid DESC", 1));
$rids[] = $r->rid;
}
$profile_names = array();
if (sizeof($rids)) {
$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) . ")");
while ($row = db_fetch_array($result)) {
if (!isset($profile_names[$row['rid']])) {
$profile_names[$row['rid']] = array();
}
array_push($profile_names[$row['rid']], $row['name']);
}
}
foreach ($rids as $rid) {
if (!empty($profile_names[$rid])) {
foreach ($profile_names[$rid] as $profile_name) {
$profile = fckeditor_profile_load($profile_name);
$conf = $profile->settings;
$enabled = fckeditor_is_enabled(empty($conf['excl_mode']) ? '0' : $conf['excl_mode'], empty($conf['excl_regex']) ? '' : $conf['excl_regex'], $element_id, $_GET['q']);
if ($enabled) {
return $profile;
}
}
}
}
return FALSE;
}
function fckeditor_get_nodetype($get_q) {
static $nodetype;
if (!isset($nodetype)) {
$nodetypes = node_get_types('names');
$menuitem = menu_get_item();
$nodetype = '*';
if (!empty($menuitem['page_arguments']) && is_array($menuitem['page_arguments'])) {
foreach ($menuitem['page_arguments'] as $item) {
if (!empty($item->nid) && !empty($item->type)) {
// not 100% valid check if $item is a node
$nodetype = $item->type;
break;
}
}
}
if ($nodetype == '*') {
$get_q = explode("/", $get_q, 3);
if ($get_q[0] == "node" && $get_q[1] == "add" && !empty($get_q[2])) {
$nodetype = $get_q[2];
// underscores are translated to dashes in node/add/ urls. try to translate it back
if (!isset($nodetypes[$nodetype])) {
foreach (array_keys($nodetypes) as $nt) {
if (strtr($nt, '_', '-') === $nodetype) {
$nodetype = $nt;
break;
}
}
}
}
}
// Sanity check
if (!isset($nodetypes[$nodetype])) {
$nodetype = NULL;
}
}
return $nodetype;
}
function fckeditor_path_to_theme() {
global $theme_key;
static $themepath;
if (empty($themepath) && !empty($theme_key)) {
$themepath = drupal_get_path('theme', $theme_key);
}
// fall back
if (empty($themepath)) {
return path_to_theme();
}
return $themepath;
}
Functions
Name![]() |
Description |
---|---|
fckeditor_admin | |
fckeditor_elements | Implementation of hook_elements(). Replace textarea with FCKeditor using callback function (fckeditor_process_textarea) |
fckeditor_file_download | Implementation of hook_file_download(). Support for private downloads. FCKeditor does not implement any kind of potection on private files. |
fckeditor_filter_xss | AJAX callback - XSS filter |
fckeditor_get_nodetype | |
fckeditor_help | Implementation of hook_help(). |
fckeditor_init | Implementation of hook_init(). |
fckeditor_is_compatible_client | Test if client can render the FCKeditor Use built-in test method in fckeditor.php If fckeditor.php is not found, return false (probably in such case fckeditor is not installed correctly) |
fckeditor_is_enabled | |
fckeditor_menu | Implementation of hook_menu(). |
fckeditor_path | Read FCKeditor path from Global profile |
fckeditor_path_to_theme | |
fckeditor_perm | Implementation of hook_perm(). Administer -> User management -> Permissions |
fckeditor_process_form | |
fckeditor_process_input | Allow more than 255 chars in Allowed HTML tags textfield |
fckeditor_process_textarea | This function create the HTML objects required for the FCKeditor |
fckeditor_profile_load | Load all profiles. Just load one profile if $name is passed in. |
fckeditor_sorted_roles | sort roles according to precedence settings. previously sorted roles are followed by latest added roles. |
fckeditor_user | Implementation of hook_user(). |
fckeditor_user_get_profile | |
fckeditor_user_get_setting | |
_fckeditor_ckfinder_path |
Constants
Name![]() |
Description |
---|---|
FCKEDITOR_FORCE_SIMPLE_TOOLBAR_NAME | The name of simplified toolbar which should be forced Be sure that this toolbar is defined in fckeditor.config.js or fckconfig.js |
Globals
Name![]() |
Description |
---|---|
$_fckeditor_configuration | |
$_fckeditor_js_ids |