$ckconfig_file, '%file' => 'sites/all/libraries/ckeditor/ckeditor.js')));
drupal_set_message(t('The CKEditor component is not installed correctly. Please go to the !ckeditorlink to download the latest version. After that you must extract the files to %ckeditorpath or %librarypath and make sure that the file %ckeditorfile or %ckeditorlibrary exist. Refer to the !readme for more information.', array('!ckeditorlink' => l(t('CKEditor homepage'), 'http://ckeditor.com/download'), '!readme' => l(t('README.txt'), $base_url . '/' . drupal_get_path('module', 'ckeditor') . '/README.txt', array('absolute' => TRUE)), '%ckeditorpath' => 'sites/all/modules/ckeditor/ckeditor', '%ckeditorsubdir' => $editor_path . '/editor', '%ckeditorfile' => 'sites/all/modules/ckeditor/ckeditor/ckeditor.js', '%ckeditorlibrary' => 'sites/all/libraries/ckeditor/ckeditor.js', '%librarypath' => 'sites/all/libraries/ckeditor')), 'error');
drupal_set_message(t('If you have CKEditor already installed please edit @editg and update CKEditor path.', array('@editg' => l(t('CKEditor Global Profile'), 'admin/config/content/ckeditor/editg'))), 'warning');
return '';
}
if (module_exists('wysiwyg')) {
drupal_set_message(t('WYSIWYG module was detected. Using both modules at the same time may cause problems. It is recommended to turn the WYSIWYG module off (@wysiwygdisablelink).', array('@wysiwygdisablelink' => l(t('click here to disable'), 'ckeditor/disable/wysiwyg'))), 'warning');
}
//find profile other than Global
$result = db_select('ckeditor_settings', 's')->fields('s', array('name'))->condition('name', 'CKEditor Global Profile', '<>')->range(0, 1)->execute()->fetchAssoc();
if (!$result) {
drupal_set_message(t('No CKEditor profiles found. At this moment, nobody is able to use CKEditor. Create new profile below.'), 'error');
}
return ckeditor_profile_overview();
}
/**
* Controller for ckeditor profiles.
*/
function ckeditor_profile_overview() {
$output = '';
$profiles = ckeditor_profile_load();
if ($profiles) {
$access_ckeditor_roles = user_roles(FALSE, 'access ckeditor');
$header = array(t('Profile'), t('Input format'), t('Operations'));
foreach ($profiles as $p) {
if ($p->name !== "CKEditor Global Profile") {
$rows[] = array(
array('data' => $p->name, 'valign' => 'top'),
array('data' => implode("
\n", $p->input_formats)),
array('data' =>
l(t('edit'), 'admin/config/content/ckeditor/edit/' . urlencode($p->name)) . ' ' .
l(t('clone'), 'admin/config/content/ckeditor/clone/' . urlencode($p->name)) . ' ' .
l(t('delete'), 'admin/config/content/ckeditor/delete/' . urlencode($p->name)), 'valign' => 'top'
)
);
}
}
$output .= '
' . l(t('Create new profile'), 'admin/config/content/ckeditor/add') . '
'; } else { drupal_set_message(t('No profiles found. Click here to %create.', array('%create' => l(t('create a new profile'), url('admin/config/content/ckeditor/add'))))); } $rows = array(); if (!isset($profiles['CKEditor Global Profile'])) { drupal_set_message(t('Global profile not found. Click here to %create.', array('%create' => l(t('create the global profile'), url('admin/config/content/ckeditor/addg'))))); } else { $output .= "' . t('The CKEditor security system protects you from executing malicious code that is already in your database. In plain text areas database content is harmless because it is not executed, but the CKEditor WYSIWYG editor evaluates HTML like a web browser and content needs to be filtered before it is loaded.') . '
', '#collapsible' => TRUE, '#collapsed' => TRUE ); $form['security']['filters'] = array( '#type' => 'fieldset', '#title' => t('Security filters'), '#description' => t('Please choose carefully all filters that protect your content (probably not all filters listed below are security filters).'), '#tree' => TRUE, ); $all_filters = filter_get_filters(); if (!isset($profile->settings['ss'])) { $profile->settings['filters']['filter/0'] = 1; } if (array_key_exists('filter_htmlcorrector', $all_filters)) { $form['security']['filters']['filter_htmlcorrector'] = array( '#type' => 'checkbox', '#title' => t("@data", array('@data' => $all_filters['filter_htmlcorrector']['title'])), '#default_value' => !empty($profile->settings['filters']['filter_htmlcorrector']), '#description' => t("@data", array('@data' => $all_filters['filter_htmlcorrector']['description'])), ); } if (array_key_exists('filter_html', $all_filters)) { $form['security']['filters']['filter_html'] = array( '#type' => 'checkbox', '#title' => t("@data", array('@data' => $all_filters['filter_html']['title'])), '#default_value' => !empty($profile->settings['filters']['filter_html']), '#description' => t("@data", array('@data' => $all_filters['filter_html']['description'])), ); } $form['security']['ss'] = array( '#type' => 'radios', '#title' => t('Security settings'), '#default_value' => isset($profile->settings['ss']) ? $profile->settings['ss'] : '2', '#options' => array( '2' => t('Always run security filters for CKEditor.'), '1' => t('Run security filters only when CKEditor is set to start automatically.'), ), //'#description' => t('There are two ways of starting CKEditor: automatically and manually (via toggle or in a popup). If you decide to apply security filters only when CKEditor starts automatically, you will not be protected when toggling manually from plain text area to CKEditor or when using CKEditor in a popup mode. So choose this option only, if you can detect various attacks (mainly XSS) by yourself just by looking at the HTML code.'), '#description' => t('There are two ways of starting CKEditor: automatically and manually (via toggle). If you decide to apply security filters only when CKEditor starts automatically, you will not be protected when toggling manually from plain text area to CKEditor. So choose this option only, if you can detect various attacks (mainly XSS) by yourself just by looking at the HTML code.'), ); $form['appearance'] = array( '#type' => 'fieldset', '#title' => t('Editor appearance'), '#collapsible' => TRUE, '#collapsed' => TRUE, ); $form['appearance']['default'] = array( '#type' => 'radios', '#title' => t('Default state'), '#default_value' => !empty($profile->settings['default']) ? $profile->settings['default'] : 't', '#options' => array( 't' => t('Enabled'), 'f' => t('Disabled') ), //'#description' => t('Default editor state. If disabled, rich text editor may still be enabled using toggle or popup window.'), '#description' => t('Default editor state. If disabled, rich text editor may still be enabled using toggle.'), ); $form['appearance']['show_toggle'] = array( '#type' => 'radios', '#title' => t('Show disable/enable rich text editor toggle'), '#default_value' => !empty($profile->settings['show_toggle']) ? $profile->settings['show_toggle'] : 't', '#options' => array( 't' => t('Show'), 'f' => t('Hide') ), //'#description' => t('Whether or not to show the disable/enable rich text editor toggle below the textarea. Works only if CKEditor is not running in a popup window (see below).'), '#description' => t('Whether or not to show the disable/enable rich text editor toggle below the textarea.'), ); /* $form['appearance']['popup'] = array( '#type' => 'radios', '#title' => t('Use CKEditor in a popup window'), '#default_value' => !empty($profile->settings['popup']) ? $profile->settings['popup'] : 'f', '#options' => array( 'f' => t('No'), 't' => t('Yes') ), '#description' => t('If this option is enabled a link to a popup window will be used instead of a textarea replace.'), ); */ $form['appearance']['skin'] = array( '#type' => 'select', '#title' => t('Skin'), '#default_value' => !empty($profile->settings['skin']) ? $profile->settings['skin'] : 'kama', '#options' => $skin_options, '#description' => t('Choose a default skin.'), ); $ui_colors = array( "default" => t('CKEditor default'), "custom" => t('Select manually') ); if (function_exists('color_get_palette')) { // apparently $theme is not initialized (?) if (empty($theme)) { init_theme(); } $palette = @color_get_palette($theme, FALSE); //[#652274] $color_palette['default'] = '#D3D3D3'; if (!empty($palette)) { if (!empty($palette['base'])) { $color_palette['color_base'] = $palette['base']; $ui_colors["color_base"] = t('Color module: base'); } if (!empty($palette['top'])) { $color_palette['color_top'] = $palette['top']; $ui_colors["color_top"] = t('Color module: top'); } if (!empty($palette['bottom'])) { $color_palette['color_bottom'] = $palette['bottom']; $ui_colors["color_bottom"] = t('Color module: bottom'); } } drupal_add_js(array('ckeditor_uicolor' => $color_palette), 'setting'); } $editor_path = ckeditor_path(FALSE); $module_drupal_path = drupal_get_path('module', 'ckeditor'); drupal_add_js('window.CKEDITOR_BASEPATH = "' . base_path() . $editor_path . '/"', array('type' => 'inline', 'weight' => -100)); drupal_add_js($editor_path . '/ckeditor.js', array('type' => 'file', 'preprocess' => FALSE)); drupal_add_js($module_drupal_path . '/ckeditor.config.js', 'file'); drupal_add_js($module_drupal_path . '/includes/ckeditor.admin.js', 'file'); $form['appearance']['uicolor'] = array( '#type' => 'select', '#title' => t('User Interface color'), '#default_value' => !empty($profile->settings['uicolor']) ? $profile->settings['uicolor'] : 'default', '#options' => $ui_colors, '#description' => t('Works only with "!skin" skin.', array( '!skin' => 'Kama' )), ); $form['appearance']['uicolor_textarea'] = array( '#type' => 'textarea', '#title' => '', '#default_value' => 'Click on the UI Color Picker button to set your color preferences.', '#attributes' => array('style' => 'display:none', 'class' => array('ckeditor_ui_demo')), '#resizable' => FALSE, '#wysiwyg' => FALSE ); $form['appearance']['uicolor_user'] = array( '#type' => 'hidden', '#default_value' => !empty($profile->settings['uicolor_user']) ? $profile->settings['uicolor_user'] : 'default', ); $form['appearance']['toolbar'] = array( '#type' => 'textarea', '#title' => t('Toolbar'), '#default_value' => !empty($profile->settings['toolbar']) ? $profile->settings['toolbar'] : '', '#description' => t('Set the toolbar definition. The instruction is available in the CKEditor documentation.',
'br' => '
',
'div' => '
',
'br' => '
',
'div' => '
@codeWarning: If you make something wrong here, CKEditor may fail to load.', array('!ckeditor_config' => drupal_get_path('module', 'ckeditor') . "/ckeditor.config.js", '!docs' => 'http://docs.cksource.com/ckeditor_api/symbols/CKEDITOR.config.html', '@code' => "config.fontSize_sizes = '16/16px;24/24px;48/48px;'\nconfig.font_names = 'Arial;Times New Roman;Verdana'")), '#wysiwyg' => FALSE, ); $form['submit'] = array( '#type' => 'submit', '#value' => t('Save') ); return $form; } /** * Form validation for a profile. */ function ckeditor_admin_profile_form_validate($form, &$form_state) { $edit = & $form_state['values']; /* if ($edit['default'] == 't' && $edit['popup'] == 't') { form_set_error('popup', t('If CKEditor is enabled by default, popup window must be disabled.')); } if ($edit['show_toggle'] == 't' && $edit['popup'] == 't') { form_set_error('popup', t('If toggle is enabled, popup window must be disabled.')); } */ if (!$edit['name']) { form_set_error('name', t('You must give a profile name.')); } elseif (!preg_match('/^[A-Za-z0-9_]+$/', $edit['name'])) { form_set_error('name', t('Enter valid profile name. Only alphanumeric and underscore characters are allowed.')); } elseif ($edit['name'] == 'CKEditor Global Profile') { form_set_error('name', t('This profile name is reserved. Please choose a different name.')); } elseif (!isset($edit['_profile']) || ($edit['_profile']->name != $edit['name'])) { $result = ckeditor_profile_load($edit['name']); if (!empty($result)) { form_set_error('name', t('The profile name must be unique. A profile with this name already exists.')); } } if (!preg_match('/^\d+%?$/', $edit['width'])) { form_set_error('width', t('Enter valid width. Example: 400 or 100%.')); } if (!empty($edit['css_path'])) { if ($edit['css_mode'] != 'self') { form_set_error('css_path', t('CSS path is not empty. Please set the "Editor CSS" option to "define css" mode.')); } elseif (FALSE !== strpos($edit['css_path'], '"')) { form_set_error('css_path', t('Double quotes are not allowed in CSS path.')); } elseif (substr($edit['css_path'], 0, 1) == "'" && substr($edit['css_path'], -1) == "'") { form_set_error('css_path', t('Enter valid path, do not surround it with quotes.')); } } if (!empty($edit['styles_path'])) { if ($edit['css_style'] != 'self') { form_set_error('styles_path', t('Path to predefined styles is not empty. Please set the "Predefined styles" option to "define path to ckeditor.styles.js" mode.')); } elseif (FALSE !== strpos($edit['styles_path'], '"')) { form_set_error('styles_path', t('Double quotes are not allowed in path.')); } elseif (substr($edit['styles_path'], 0, 1) == "'" && substr($edit['styles_path'], -1) == "'") { form_set_error('styles_path', t('Enter valid path, do not surround it with quotes.')); } } if (!empty($edit['font_format'])) { if (!preg_match("/^((p|div|pre|address|h1|h2|h3|h4|h5|h6);)*(p|div|pre|address|h1|h2|h3|h4|h5|h6)$/", $edit['font_format'])) { form_set_error('font_format', t('Enter valid, semicolon separated, list of HTML font formats (no semicolon at the end of list expected).')); } } // @todo DOWNLOAD API if (!empty($edit['UserFilesAbsolutePath']) && empty($edit['UserFilesPath'])) { form_set_error('UserFilesPath', t('Path to uploaded files is required.')); } if (!empty($edit['UserFilesPath']) && empty($edit['UserFilesAbsolutePath'])) { form_set_error('UserFilesPath', t('Absolute path to uploaded files is required.')); } $load_methods = _ckeditor_load_methods(); if (!isset($load_methods[$edit['ckeditor_load_method']])) { form_set_error('ckeditor_load_method', t('Set valid load method.')); } if (!preg_match('#\d+#', $edit['ckeditor_load_time_out'])) { form_set_error('ckeditor_load_time_out', t('Enter valid load timeout in seconds.')); } if (!preg_match('#^\s*\[(?:\s*(?:\{\s*[\w:\'" ,]*\s*\[(?:\s*([\'\"\"])(?:\w+|-)\1\s*[,]?\s*)+\]\s*\}|([\'\"\"])\/\2)\s*[,]?\s*)+\]\s*$#U', $edit['toolbar']) && !preg_match('#^\s*\[(?:\s*(?:\[(?:\s*([\'\"\"])(?:\w+|-)\1\s*[,]?\s*)+\]|([\'\"\"])\/\2)\s*[,]?\s*)+\]\s*$#', $edit['toolbar'])) { form_set_error('toolbar', t('Enter valid toolbar configuration.')); } } /** * Form submit for a profile */ function ckeditor_admin_profile_form_submit($form, &$form_state) { $edit = & $form_state['values']; if (isset($edit['_profile'])) { ckeditor_profile_delete($edit['_profile']->name); drupal_set_message(t('Your CKEditor profile has been updated.')); } else { drupal_set_message(t('Your CKEditor profile has been created.')); } $settings = ckeditor_admin_values_to_settings($edit); db_insert('ckeditor_settings') ->fields(array( "name" => $edit['name'], "settings" => $settings )) ->execute(); if (!empty($edit['input_formats'])) { foreach (array_keys($edit['input_formats']) as $format) { if ($edit['input_formats'][$format] != '0') { db_insert('ckeditor_input_format')->fields(array("name" => $edit['name'], "format" => $format))->execute(); } } } $form_state['redirect'] = 'admin/config/content/ckeditor'; } /** * Form builder for a clone profile */ function ckeditor_admin_profile_clone_form($form, $form_state, $oldprofile) { return ckeditor_admin_profile_form($form, $form_state, $oldprofile); } /** * Form validation for a clone profile */ function ckeditor_admin_profile_clone_form_validate($form_state, $oldprofile) { ckeditor_admin_profile_form_validate($form_state, $oldprofile); } /** * Form submit for a clone profile */ function ckeditor_admin_profile_clone_form_submit($form, &$form_state) { $edit = & $form_state['values']; drupal_set_message(t('Your CKEditor profile has been created.')); $settings = ckeditor_admin_values_to_settings($edit); db_insert('ckeditor_settings') ->fields(array( "name" => $edit['name'], "settings" => $settings )) ->execute(); if (!empty($edit['input_formats'])) { foreach (array_keys($edit['input_formats']) as $format) { if ($edit['input_formats'][$format] != 0) { db_insert('ckeditor_input_format')->fields(array("name" => $edit['name'], "format" => $format))->execute(); } } } $form_state['redirect'] = 'admin/config/content/ckeditor'; } /** * Form builder for a profile delete */ function ckeditor_admin_profile_delete_form($form, $form_state, $profile) { $form = array(); $form['_profile'] = array( '#type' => 'value', '#value' => $profile, ); $form['question'] = array( '#type' => 'item', '#markup' => t('Are you sure that you want to delete the CKEditor profile %profile?', array('%profile' => $profile->name)), ); $form['delete'] = array( '#type' => 'submit', '#id' => 'delete', '#value' => t('Delete'), ); $form['back'] = array( '#type' => 'submit', '#id' => 'back', '#value' => t('Cancel'), ); return $form; } /** * Submit form for a profile delete */ function ckeditor_admin_profile_delete_form_submit($form, &$form_state) { $v = & $form_state['values']; if ($form_state['clicked_button']['#id'] == 'delete') { ckeditor_profile_delete($v['_profile']->name); drupal_set_message(t('Deleted CKEditor profile.')); } $form_state['redirect'] = 'admin/config/content/ckeditor'; } /** * Converts an array of form values to a serialized array that does not * contain Drupal Form API values */ function ckeditor_admin_values_to_settings($values) { $plugins = array(); if (isset($values['loadPlugins'])) { $plugins = $values['loadPlugins']; } unset($values['name'], $values['input_formats'], $values['_profile'], $values['op'], $values['submit'], $values['form_build_id'], $values['form_token'], $values['form_id'], $values['loadPlugins']); module_load_include('inc', 'ckeditor', 'includes/ckeditor.lib'); $plugin_list = ckeditor_load_plugins(); $values['loadPlugins'] = array(); if (!empty($plugins)) { foreach (array_keys($plugins) as $plugin) { if ($plugins[$plugin] != '0') { $values['loadPlugins'][$plugin] = $plugin_list[$plugin]; } } } return serialize($values); } /** * Remove a profile from the database. */ function ckeditor_profile_delete($name) { db_delete('ckeditor_settings') ->condition('name', $name) ->execute(); db_delete('ckeditor_input_format') ->condition('name', $name) ->execute(); } /* * List of CKEditor librares to load */ function _ckeditor_load_methods() { module_load_include('module', 'ckeditor'); $result = array('ckeditor.js' => 'ckeditor.js'); if (file_exists(ckeditor_path(TRUE) . '/ckeditor_basic.js')) { $result['ckeditor_basic.js'] = 'ckeditor_basic.js'; } if (file_exists(ckeditor_path(TRUE) . '/ckeditor_source.js')) { $result['ckeditor_source.js'] = 'ckeditor_source.js (' . t('for developers only') . ')'; } return $result; } /* * Disable WYSIWYG module */ function ckeditor_disable_wysiwyg() { module_disable(array('wysiwyg')); drupal_set_message(t('WYSIWYG module disabled.')); drupal_goto('admin/config/content/ckeditor'); }