'' . $ckconfig_file . '
',
'!file' => 'libraries/ckeditor/ckeditor.js
'
)
));
drupal_set_message(t(
'The CKEditor component is not installed correctly. Please go to the !ckeditorlink in order to download the latest version. After that you must extract the files to the !ckeditorpath or !librarypath directory and make sure that the !ckeditorfile or !ckeditorlibrary file exists. Refer to the !readme file for more information.',
array(
'!ckeditorlink' => l(t('CKEditor homepage'), 'http://ckeditor.com/download'),
'!readme' => l(t('README.txt'), drupal_get_path('module', 'ckeditor') . '/README.txt', array('absolute' => TRUE)),
'!ckeditorpath' => '' . $editor_path . '
',
'!ckeditorsubdir' => '' . $editor_path . '/editor
',
'!ckeditorfile' => '' . $editor_path . '/ckeditor.js
',
'!ckeditorlibrary' => 'libraries/ckeditor/ckeditor.js
',
'!librarypath' => 'libraries/ckeditor
'
)
), 'error');
drupal_set_message(t(
'If you have CKEditor already installed, edit the !editg and update the CKEditor path.',
array(
'!editg' => l(t('CKEditor Global Profile'), 'admin/settings/ckeditor/editg')
)
), 'warning');
return FALSE;
}
if (module_exists('wysiwyg')) {
drupal_set_message(t(
'The 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/' . drupal_get_token('ckeditorDisableWysiwyg'))
)
), 'warning');
}
$access_ckeditor_roles = user_roles(FALSE, 'access ckeditor');
if (!$access_ckeditor_roles) {
drupal_set_message(t(
'There is currently no role with the "access ckeditor" permission. Visit the !acl administration section.',
array(
'!acl' => l(t('Permissions'), 'admin/user/permissions')
)
), 'warning');
}
else {
$result = db_query_range("SELECT name FROM {ckeditor_settings} WHERE name<>'CKEditor Global Profile'", 0, 1);
$has_profiles = FALSE;
//find profile other than Global
if (($obj = db_fetch_object($result))) {
$has_profiles = TRUE;
}
//find roles with profiles
$result = db_query("SELECT rid FROM {ckeditor_role}");
$rids = array();
while (($obj = db_fetch_object($result))) {
$rids[] = $obj->rid;
}
$rids = array_unique($rids);
if (!$has_profiles) {
drupal_set_message(t('No CKEditor profiles found. Right now nobody is able to use CKEditor. Create a new profile below.'), 'error');
}
else {
//not all roles with access ckeditor has their CKEditor profile assigned
$diff = array_diff(array_keys($access_ckeditor_roles), $rids);
if ($diff) {
$list = "
' . l(t('Create a new profile'), 'admin/settings/ckeditor/add') . '
'; } else { drupal_set_message(t( 'No profiles found. Click here to !create.', array( '!create' => l(t('create a new profile'), 'admin/settings/ckeditor/add') ) )); } $rows = array(); if (!isset($profiles['CKEditor Global Profile'])) { drupal_set_message(t( 'The global profile can not be found. Click here to !create.', array( '!create' => l(t('create the global profile'), 'admin/settings/ckeditor/addg') ) )); } else { $output .= "'. t('The CKEditor security system protects you from executing malicious code that is already in your database. In plain textareas database content is harmless because it is not executed, but the CKEditor WYSIWYG editor interprets HTML like a web browser and thus the content needs to be filtered before it is loaded.') .'
', '#collapsible' => TRUE, '#collapsed' => TRUE ); $all = filter_list_all(); $form['security']['filters'] = array( '#type' => 'fieldset', '#title' => t('Security filters'), '#description' => t('Please choose all filters that protect your content (probably not all filters listed below are security filters).'), '#tree' => TRUE, ); //don't bother administrator with filters that definitely are not security filters $modules_with_filters_to_skip = array('amazon_filter', 'asy', 'bbcode', 'biblio', 'blockquote', 'bookpost', 'chessboard', 'citation_filter', 'codefilter', 'collapse_text', 'contextlinks', 'coolfilter', 'dialectic', 'dript', 'dme', 'drutex', 'embedfilter', 'ext_link_page', 'extlink', 'elf', 'flickr', 'flickrstickr', 'footnotes', 'formdefaults', 'freelinking', 'gallery', 'geogebra', 'geshifilter', 'gotwo', 'googtube', 'gotcha', 'gtspam', 'hidden_content', 'img_assist', 'image_filter', 'imagebrowser', 'inlinetags', 'insert_view', 'insertframe', 'insertnode', 'interwiki', 'jlightbox', 'jsmath', 'language_sections', 'link_node', 'lootz', 'markdown', 'marksmarty', 'mobile_codes', 'mykml', 'nofollowlist', 'oagwt', 'paging', 'pathfilter', 'pearwiki_filter', 'php', 'pirate', 'reptag', 'scrippet', 'scripturefilter', 'signwriter', 'slideshowpro', 'smartlinebreakconverter', 'smartypants', 'smileys', 'spamspan', 'spam_tokens', 'spoiler', 'table_altrow', 'tablemanager', 'tableofcontents', 'textile', 'tooltips', 'twikifilter', 'typogrify', 'unwrap', 'urlclass', 'urlicon', 'url_replace_filter', 'username_highlighter', 'video_filter', 'quote'); if (!isset($profile->settings['ss'])) { $profile->settings['filters']['filter/0'] = 1; } foreach ($all as $id => $filter) { if (in_array(strtolower($filter->module), $modules_with_filters_to_skip)) { continue; } //skip line break converter and email -> link if ($filter->module == 'filter' && in_array($filter->delta, array(1, 2))) { continue; } $form['security']['filters'][$id] = array( '#type' => 'checkbox', '#title' => check_plain($filter->name), '#default_value' => !empty($profile->settings['filters'][$id]), '#description' => check_plain(module_invoke($filter->module, 'filter', 'description', $filter->delta)), ); } $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 textarea to CKEditor or when using CKEditor in the popup mode. Choose this option only if you can detect various attacks (mainly XSS) by yourself just by looking at the HTML code.'), ); $form['ckeditor_exclude_settings'] = array( '#type' => 'fieldset', '#title' => t('Visibility settings'), '#collapsible' => TRUE, '#collapsed' => TRUE, '#description' => t('The following settings are combined with the visibility settings of the global profile.'), ); $form['ckeditor_exclude_settings']['min_rows'] = array( '#type' => 'textfield', '#title' => t('Minimum rows'), '#default_value' => !empty($profile->settings['min_rows']) ? $profile->settings['min_rows'] : '1', '#description' => t("CKEditor will be triggered if the textarea has more rows than the number given here. Enter '1' if you do not want to use this feature."), ); $form['ckeditor_exclude_settings']['excl_mode'] = array( '#type' => 'radios', '#title' => t('Use inclusion or exclusion mode'), '#default_value' => (empty($profile->settings['excl_mode']) || in_array($profile->settings['excl_mode'], array(0, 2))) ? 0 : 1, '#options' => array( '0' => t('Exclude'), '1' => t('Include') ), '#description' => t('Choose the way of disabling/enabling CKEditor on selected fields/paths (see below). Use Exclude to disable CKEditor on selected fields/paths. Use Include if you want to load CKEditor only on selected paths/fields.'), ); /** * get excluded fields - so we can have normal textareas too * split the phrase by any number of commas or space characters, * which include " ", \r, \t, \n and \f */ $form['ckeditor_exclude_settings']['excl'] = array( '#type' => 'textarea', '#title' => t('Fields to exclude/include'), '#cols' => 60, '#rows' => 5, '#prefix' => 'blog
called edit-body
in the garland theme, on any page.') .
'edit-user-
on pages starting with node/add/
') .
'div
instead of iframe
.")
);
}
$form['appearance']['width'] = array(
'#type' => 'textfield',
'#title' => t('Editor width'),
'#default_value' => !empty($profile->settings['width']) ? $profile->settings['width'] : '100%',
'#description' => t("Editor interface width in pixels or percent. Examples: 400, 100%."),
'#size' => 40,
'#maxlength' => 128,
);
$form['appearance']['lang'] = array(
'#type' => 'select',
'#title' => t('Language'),
'#default_value' => !empty($profile->settings['lang']) ? $profile->settings['lang'] : 'en',
'#options' => $lang_options,
'#description' => t('The language for the CKEditor user interface.')
);
$form['appearance']['auto_lang'] = array(
'#type' => 'radios',
'#title' => t('Auto-detect language'),
'#default_value' => !empty($profile->settings['auto_lang']) ? $profile->settings['auto_lang'] : 't',
'#options' => array(
't' => t('Enabled'),
'f' => t('Disabled')
),
'#description' => t('Automatically detect the user language.')
);
$form['appearance']['language_direction'] = array(
'#type' => 'select',
'#title' => t('Language direction'),
'#default_value' => !empty($profile->settings['language_direction']) ? $profile->settings['language_direction'] : 'default',
'#options' => array(
'default' => t('Get from current locale (default)'),
'ltr' => t('Left-To-Right'),// language like English
'rtl' => t('Right-To-Left') // languages like Arabic
),
'#description' => t(
'Choose the language direction used in the editing area. Even when CKEditor automatically detects the user language and adjusts its user interface, the editing area is not automatically changed into the LTR or RTL mode. To be able to type LTR (like English) and RTL (like Arabic, Hebrew, Persian) content at the same time, please make sure that the !bidiltr and !bidirtl buttons are enabled in the toolbar.',
array(
'!bidiltr' => 'BidiLtr',
'!bidirtl' => 'BidiRtl'
)
)
);
$form['acf'] = array(
'#type' => 'fieldset',
'#title' => t('Advanced content filter'),
'#description' => t('Configure input data filtering in CKEditor. See !link for more information about ACF.', array(
'!link' => l(t('this blog post'), 'http://ckeditor.com/blog/Upgrading-to-CKEditor-4.1')
)),
'#collapsible' => TRUE,
'#collapsed' => TRUE
);
$form['acf']['allowed_content'] = array(
'#type' => 'radios',
'#title' => t('Advanced content filter'),
'#description' => t('Enabled: CKEditor will only allow tags/attributes/styles provided by CKEditor features. Disallowed content will be removed directly by CKEditor. When configured properly, it helps to ensure a true WYSIWYG experience.').'<strong>
',
'!a' => '<a>
',
'!img' => '<img>
',
'!b' => '<b>
'
)).''.
t('Example: !rules', array(
'!rules' => "object[width,height];param[name,value];embed[*];
"
)).'
',
'br' => '
',
'div' => '
',
'br' => '
',
'div' => '
p;div;pre;address;h1;h2;h3;h4;h5;h6
'
)
)
);
if (!empty($profile->settings['formatting']['custom_formatting_options']))
foreach ($profile->settings['formatting']['custom_formatting_options'] as $k => $v) {
if ($v === 0) {
unset($profile->settings['formatting']['custom_formatting_options'][$k]);
}
}
$form['output']['custom_formatting'] = array(
'#type' => 'radios',
'#title' => t('Use custom formatting options'),
'#default_value' => !empty($profile->settings['custom_formatting']) ? $profile->settings['custom_formatting'] : 'f',
'#options' => array(
't' => t('Yes'),
'f' => t('No'),
),
);
$form['output']['formatting'] = array(
'#type' => 'fieldset',
'#title' => t('Custom formatting options'),
'#tree' => TRUE,
);
$form['output']['formatting']['custom_formatting_options'] = array(
'#type' => 'checkboxes',
'#default_value' => isset($profile->settings['formatting']['custom_formatting_options']) ? array_keys((array) $profile->settings['formatting']['custom_formatting_options']) : array('indent' => 'indent', 'breakBeforeOpen' => 'breakBeforeOpen', 'breakAfterOpen' => 'breakAfterOpen', 'breakAfterClose' => 'breakAfterClose'),
'#options' => array(
'indent' => t('Indent the element contents.'),
'breakBeforeOpen' => t('Break line before the opening tag.'),
'breakAfterOpen' => t('Break line after the opening tag.'),
'breakBeforeClose' => t('Break line before the closing tag.'),
'breakAfterClose' => t('Break line after the closing tag.'),
'pre_indent' => t('Indent the <pre>
element contents.'),
),
);
$form['css'] = array(
'#type' => 'fieldset',
'#title' => t('CSS'),
'#collapsible' => TRUE,
'#collapsed' => TRUE
);
$form['css']['css_mode'] = array(
'#type' => 'select',
'#title' => t('Editor CSS'),
'#default_value' => !empty($profile->settings['css_mode']) ? $profile->settings['css_mode'] : 'theme',
'#options' => array(
'theme' => t('Use theme CSS'),
'self' => t('Define CSS'),
'none' => t('CKEditor default')
),
'#description' => t(
'Defines the CSS to be used in the editor area.!title_theme_css – load the !style_css file from the current site theme.!title_define_css – enter the CSS file path below.!title_ckeditor_default – use the default editor CSS.',
array(
'!title_theme_css' => 'style.css
'
)
)
);
$form['css']['css_path'] = array(
'#type' => 'textfield',
'#title' => t('CSS file path'),
'#default_value' => !empty($profile->settings['css_path']) ? $profile->settings['css_path'] : "",
'#size' => 40,
'#maxlength' => 255,
'#description' => t(
'Enter the path to the CSS file (Example: !example1) or a list of CSS files separated with a comma (Example: !example2). Make sure you select the Define CSS option above.',
array(
'!example1' => '"css/editor.css"
',
'!example2' => '"/themes/garland/style.css,http://example.com/style.css"
',
)) .
'%h
',
'!t' => '%t
',
'!host' => base_path(),
'!theme' => base_path() . path_to_theme() .'/'
)
)
);
$form['css']['css_style'] = array(
'#type' => 'select',
'#title' => t('Predefined styles'),
'#default_value' => !empty($profile->settings['css_style']) ? $profile->settings['css_style'] : 'theme',
'#options' => array(
'theme' => t('Use theme ckeditor.styles.js'),
'self' => t('Define path to ckeditor.styles.js'),
'default' => t('CKEditor default')
),
'#description' => t(
'Define the location of the !ckeditor_styles_js_file file. It is used by the Style drop-down list available in the default toolbar. Copy the !ckeditor_styles_js_path file into your theme directory (!theme) and adjust it to your needs.',
array(
'!ckeditor_styles_js_file' => 'ckeditor.styles.js
',
'!ckeditor_styles_js_path' => '' . ckeditor_path(TRUE) .'/ckeditor.styles.js
',
'!theme' => '' . path_to_theme() . '/ckeditor.styles.js
'
)
)
);
$form['css']['styles_path'] = array(
'#type' => 'textfield',
'#title' => t('Predefined styles path'),
'#default_value' => !empty($profile->settings['styles_path']) ? $profile->settings['styles_path'] : "",
'#size' => 40,
'#maxlength' => 255,
'#description' => t(
'Enter the path to a file with predefined styles (Example: !example1). Make sure you select the Define path to ckeditor.styles.js option above.',
array(
'!example1' => '/ckeditor.styles.js
'
)
) .
'%h
',
'!t' => '%t
',
'!m' => '%m
',
'!host' => '' . base_path() . '
',
'!theme' => '' . base_path() . path_to_theme() . '/
',
'!module' => '' . drupal_get_path('module', 'ckeditor') . '
'
)
)
);
$form['ckeditor_upload_settings'] = array(
'#type' => 'fieldset',
'#title' => t('File browser settings'),
'#collapsible' => TRUE,
'#collapsed' => TRUE,
'#description' => t(
'Set the file browser settings. A file browser will allow you to browse the files stored on the server and embed them as links, images, or Flash movies. CKEditor is compatible with such Drupal modules as !imce, !ib, !webfm or !elfinder. CKEditor can be also integrated with !ckfinder, an advanced Ajax file manager.',
array(
'!imce' => l(t('IMCE'), 'http://drupal.org/project/imce'),
'!ib' => l(t('Image Browser'), 'http://drupal.org/project/imagebrowser'),
'!webfm' => l(t('Web File Manager'), 'http://drupal.org/project/webfm'),
'!ckfinder' => l(t('CKFinder'), 'http://cksource.com/ckfinder'),
'!elfinder' => l(t('elFinder'), 'http://drupal.org/project/elfinder')
)
)
);
$filebrowsers = array(
'none' => t('None'),
'ckfinder' => t('CKFinder'),
);
$filebrowsers_dialogs = array(
'' => t('Same as in the Link dialog window'),
'ckfinder' => t('CKFinder'),
);
if (module_exists('imce')) {
$filebrowsers['imce'] = t('IMCE');
$filebrowsers_dialogs['imce'] = t('IMCE');
}
if (module_exists('tinybrowser')) {
$filebrowsers['tinybrowser'] = t('TinyBrowser');
$filebrowsers_dialogs['tinybrowser'] = t('TinyBrowser');
}
if (module_exists('imagebrowser')) {
$filebrowsers['ib'] = t('Image Browser');
$filebrowsers_dialogs['ib'] = t('Image Browser');
}
if (module_exists('webfm_popup')) {
$filebrowsers['webfm'] = t('Web File Manager');
$filebrowsers_dialogs['webfm'] = t('Web File Manager');
}
if (module_exists('elfinder')) {
$filebrowsers['elfinder'] = t('elFinder');
$filebrowsers_dialogs['elfinder'] = t('elFinder');
}
$form['ckeditor_upload_settings']['filebrowser'] = array(
'#type' => 'select',
'#title' => t('File browser type (Link dialog window)'),
'#default_value' => !empty($profile->settings['filebrowser']) ? $profile->settings['filebrowser'] : 'none',
'#options' => $filebrowsers,
'#description' => t('Select the file browser that you would like to use to upload files.'),
);
$form['ckeditor_upload_settings']['filebrowser_image'] = array(
'#type' => 'select',
'#title' => t('File browser type (Image dialog window)'),
'#default_value' => !empty($profile->settings['filebrowser_image']) ? $profile->settings['filebrowser_image'] : 'none',
'#options' => $filebrowsers_dialogs,
'#description' => t('Select the file browser that you would like to use to upload images.'),
);
$form['ckeditor_upload_settings']['filebrowser_flash'] = array(
'#type' => 'select',
'#title' => t('File browser type (Flash dialog window)'),
'#default_value' => !empty($profile->settings['filebrowser_flash']) ? $profile->settings['filebrowser_flash'] : 'none',
'#options' => $filebrowsers_dialogs,
'#description' => t('Select the file browser that you would like to use to upload Flash movies.'),
);
$current_user_files_path = empty($profile->settings['UserFilesPath']) ? "%b%f/" : $profile->settings['UserFilesPath'];
$current_user_files_path = strtr($current_user_files_path, array("%f" => file_directory_path(), "%u" => "UID", "%b" => base_path(), "%n" => "UNAME"));
$current_user_files_absolute_path = empty($profile->settings['UserFilesAbsolutePath']) ? "%d%b%f/" : $profile->settings['UserFilesAbsolutePath'];
$current_user_files_absolute_path = strtr($current_user_files_absolute_path, array("%f" => file_directory_path(), "%u" => "UID", "%b" => base_path(), "%d" => $_SERVER['DOCUMENT_ROOT'], "%n" => "UNAME"));
if (variable_get('file_downloads', '') != FILE_DOWNLOADS_PRIVATE) {
$form['ckeditor_upload_settings']['UserFilesPath'] = array(
'#type' => 'textfield',
'#prefix' => '',
'#description' => t('The path to the local directory (on the server) which points to the path defined above. If left empty, CKEditor will try to discover the right path.') .
'%u
',
'!n' => '%n
',
'!d' => '%d
',
'!b' => '%b
',
'!f' => '%f
',
'!files' => '' . file_directory_path() . '
',
'!base' => '' . base_path() . '
',
'!root' => '' . $_SERVER['DOCUMENT_ROOT'] . '
'
)
) .
'' . $current_user_files_absolute_path . '
'
)
)
);
}
if (variable_get('file_downloads', '') == FILE_DOWNLOADS_PRIVATE) {
$form['ckeditor_upload_settings']['private_path_descrption'] = array(
'#value' => 'ckeditor_basic.js
'
)
)
);
$form['advanced']['ckeditor_load_time_out'] = array(
'#type' => 'textfield',
'#title' => t('Loading timeout'),
'#default_value' => !empty($profile->settings['ckeditor_load_time_out']) ? $profile->settings['ckeditor_load_time_out'] : "0",
'#size' => 40,
'#maxlength' => 255,
'#description' => t('The time to wait (in seconds) to load the full editor code after the page is loaded, if the !ckeditor_basic_js file is used. If set to zero, the editor is loaded on demand.',
array(
'!ckeditor_basic_js' => 'ckeditor_basic.js
'
)
)
);
}
$form['advanced']['forcePasteAsPlainText'] = array(
'#type' => 'select',
'#title' => t('Force pasting as plain text'),
'#default_value' => !empty($profile->settings['forcePasteAsPlainText']) ? $profile->settings['forcePasteAsPlainText'] : "f",
'#options' => array(
't' => t('Enabled'),
'f' => t('Disabled')
),
'#description' => t('If enabled, HTML content will be automatically changed to plain text when pasting.'),
);
$form['advanced']['html_entities'] = array(
'#type' => 'radios',
'#title' => t('HTML Entities'),
'#default_value' => !empty($profile->settings['html_entities']) ? $profile->settings['html_entities'] : 't',
'#description' => t('Convert all applicable characters to HTML entities.'),
'#options' => array(
'f' => t('No'),
't' => t('Yes')
),
);
$form['advanced']['scayt_autoStartup'] = array(
'#type' => 'radios',
'#title' => t('Spellchecker'),
'#default_value' => !empty($profile->settings['scayt_autoStartup']) ? $profile->settings['scayt_autoStartup'] : 'f',
'#description' => t('If enabled, turns on SCAYT (Spell Check As You Type) automatically after loading the editor.'),
'#options' => array(
'f' => t('No'),
't' => t('Yes')
),
);
$form['advanced']['theme_config_js'] = array(
'#type' => 'radios',
'#title' => t('Load !ckeditor_config_js from the theme path',
array(
'!ckeditor_config_js' => 'ckeditor.config.js
'
)
),
'#default_value' => !empty($profile->settings['theme_config_js']) ? $profile->settings['theme_config_js'] : 'f',
'#options' => array(
't' => t('Yes'),
'f' => t('No')
),
'#description' => t('When enabled, the editor will try to load the !ckeditor_config_js file from the theme directory.',
array(
'!ckeditor_config_js' => 'ckeditor.config.js
'
)
),
);
$form['advanced']['js_conf'] = array(
'#type' => 'textarea',
'#title' => t('Custom JavaScript configuration'),
'#default_value' => !empty($profile->settings['js_conf']) ? $profile->settings['js_conf'] : "",
'#cols' => 60,
'#rows' => 5,
'#description' => t(
'In order to change CKEditor configuration globally, you should modify the !ckeditor_config configuration file. Sometimes it is required to change the CKEditor configuration for a single profile only. Use this box to define settings that are unique for this profile. Available options are listed in the !docs. Add the following code snippet to change the fonts available in the CKEditor Font and Size drop-down lists: @codeWarning: If you make a mistake here, CKEditor may not load correctly.', array( '!ckeditor_config' => '
' . drupal_get_path('module', 'ckeditor') . "/ckeditor.config.js
",
'!docs' => l(t('CKEditor documentation'), '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;
}
/**
* Profile validation.
*/
function ckeditor_admin_profile_form_validate($form, &$form_state) {
$edit =& $form_state['values'];
//include mode and all other fields are empty, invalid
if ($edit['excl_mode'] == 1 && empty($edit['excl'])) {
form_set_error('excl_mode', t('Include mode selected, but no paths given. Enter at least one path where CKEditor should appear.'));
}
else {
ckeditor_admin_profile_validate_fieldpaths('excl', $edit['excl']);
}
ckeditor_admin_profile_validate_fieldpaths('simple_incl', $edit['simple_incl']);
if (!preg_match('/^\d+$/', trim($edit['min_rows']))) {
form_set_error('min_rows', t('Minimum rows must be a valid number.'));
}
if ($edit['default'] == 't' && $edit['popup'] == 't') {
form_set_error('popup', t('If CKEditor is enabled by default, the popup window must be disabled.'));
}
if ($edit['show_toggle'] == 't' && $edit['popup'] == 't') {
form_set_error('popup', t('If toggle is enabled, the 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 a 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 a valid width value. Examples: 400, 100%.'));
}
if (!empty($edit['css_path'])) {
if ($edit['css_mode'] != 'self') {
form_set_error('css_path', t('The CSS path is not empty. Please set the Editor CSS option to the Define CSS mode.'));
}
elseif (FALSE !== strpos($edit['css_path'], '"')) {
form_set_error('css_path', t('Double quotes are not allowed in the CSS path.'));
}
elseif (substr($edit['css_path'], 0, 1) == "'" && substr($edit['css_path'], -1) == "'") {
form_set_error('css_path', t('Enter a valid CSS path, do not surround it with quotes.'));
}
}
if (!empty($edit['styles_path'])) {
if ($edit['css_style'] != 'self') {
form_set_error('styles_path', t('The path to predefined styles is not empty. Please set the Predefined styles option to the 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 the styles path.'));
}
elseif (substr($edit['styles_path'], 0, 1) == "'" && substr($edit['styles_path'], -1) == "'") {
form_set_error('styles_path', t('Enter a valid styles 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 a valid, semicolon-separated list of HTML font formats (no semicolon at the end of the list is expected).'));
}
}
if (variable_get('file_downloads', '') !== FILE_DOWNLOADS_PRIVATE) {
if (!empty($edit['UserFilesAbsolutePath']) && empty($edit['UserFilesPath'])) {
form_set_error('UserFilesPath', t('The path to uploaded files is required.'));
}
if (!empty($edit['UserFilesPath']) && empty($edit['UserFilesAbsolutePath'])) {
form_set_error('UserFilesPath', t('An absolute path to uploaded files is required.'));
}
}
if (ckeditor_get_version(TRUE) == 3) {
$load_methods=_ckeditor_load_methods();
if (!isset($load_methods[$edit['ckeditor_load_method']])) {
form_set_error('ckeditor_load_method', t('Set a valid loading method.'));
}
if (!preg_match('#\d+#', $edit['ckeditor_load_time_out'])) {
form_set_error('ckeditor_load_time_out', t('Enter a valid loading 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 a valid toolbar configuration.'));
}
}
function ckeditor_admin_profile_form_submit($form, &$form_state) {
$edit =& $form_state['values'];
if (isset($edit['_profile'])) {
db_query("DELETE FROM {ckeditor_settings} WHERE name = '%s'", $edit['_profile']->name);
db_query("DELETE FROM {ckeditor_role} WHERE name = '%s'", $edit['_profile']->name);
drupal_set_message(t('Your CKEditor profile was updated.'));
}
else {
drupal_set_message(t('Your CKEditor profile was created.'));
}
$settings = ckeditor_admin_values_to_settings($edit);
db_query("INSERT INTO {ckeditor_settings} (name, settings) VALUES ('%s', '%s')", $edit['name'], $settings);
ckeditor_rebuild_selectors($edit['name']);
if (!empty($edit['rids'])) {
foreach (array_keys($edit['rids']) as $rid) {
if ($edit['rids'][$rid]!=0) {
db_query("INSERT INTO {ckeditor_role} (name, rid) VALUES ('%s', %d)", $edit['name'], $rid);
}
}
}
$form_state['redirect'] = 'admin/settings/ckeditor';
}
function ckeditor_admin_global_profile_form($form_state, $mode = 'add') {
module_load_include('inc', 'ckeditor', 'includes/ckeditor.lib');
if ($mode == 'edit') {
$profile = ckeditor_profile_load('CKEditor Global Profile');
$form['_profile'] = array(
'#type' => 'value',
'#value' => $profile,
);
}
else {
$profile = new stdClass();
}
if ($mode == 'add') {
$data = ckeditor_profile_load('CKEditor Global Profile');
if (!empty($data)) {
drupal_set_message(t('The global profile already exists. Only one global profile is allowed.'), 'error');
drupal_not_found();
}
$btn = t('Create a global profile');
}
else {
$btn = t('Update the global profile');
}
$toolbar_wizard = !empty($profile->settings['toolbar_wizard']) ? $profile->settings['toolbar_wizard'] : 't';
drupal_add_js(array('ckeditor_toolbar_wizard' => $toolbar_wizard), 'setting');
$form['common'] = array(
'#type' => 'fieldset',
'#title' => t('Main setup'),
'#collapsible' => TRUE,
'#collapsed' => TRUE
);
$roles = ckeditor_sorted_roles();
$rids = $rtext = array();
foreach ($roles as $rid => $name) {
$rids[] = $rid;
$rtext[] = ''. $rid .' - '. $name;
}
$form['common']['rank'] = array(
'#type' => 'textfield',
'#title' => t('Role precedence'),
'#default_value' => implode('>', $rids),
'#description' => t('A user with multiple roles gets the permissions of the highest one. Sort role IDs according to their precedence from higher to lower by putting the ">" character in between.'),
);
if ($rids) {
$form['common']['rank']['#description'] .= '%b
',
'!m' => '%m
',
'!l' => '%l
',
'!path' => '' . ckeditor_path(FALSE) . '
',
'!base' => '' . base_path() . '
',
'!files' => '' . base_path() . $module_drupal_path . '
',
'!library' => '' . base_path() . 'libraries/
'
)
),
'#required' => TRUE
);
$form['ckeditor_advanced_settings']['ckeditor_local_path'] = array(
'#type' => 'textfield',
'#title' => t('Local path to CKEditor'),
'#default_value' => isset($profile->settings['ckeditor_local_path'])?$profile->settings['ckeditor_local_path']:'',
'#size' => 40,
'#maxlength' => 128,
'#description' => t(
'The path to the local directory (on the server) that points to the path defined above. Enter either an absolute server path or a path relative to the !indexphp file. If left empty, the CKEditor module will try to find the right path.',
array(
'!indexphp' => 'index.php
'
)
) .
'' . ckeditor_path(TRUE) . '
'
)
)
);
$form['ckeditor_advanced_settings']['ckeditor_plugins_path'] = array(
'#type' => 'textfield',
'#title' => t('Path to the CKEditor plugins directory'),
'#default_value' => !empty($profile->settings['ckeditor_plugins_path']) ? $profile->settings['ckeditor_plugins_path'] : '%m/plugins',
'#size' => 40,
'#maxlength' => 128,
'#description' => t('Path to the CKEditor plugins directory relative to the document root.') .
'%b
',
'!m' => '%m
',
'!l' => '%l
',
'!base' => '' . base_path() . '
',
'!files' => '' . base_path() . $module_drupal_path . '
' ,
'!library' => '' . base_path() . 'libraries/
'
)
) .
'' . ckeditor_plugins_path() . '
'
)
)
);
$form['ckeditor_advanced_settings']['ckeditor_plugins_local_path'] = array(
'#type' => 'textfield',
'#title' => t('Local path to the CKEditor plugins directory'),
'#default_value' => isset($profile->settings['ckeditor_plugins_local_path'])?$profile->settings['ckeditor_plugins_local_path']:'',
'#size' => 40,
'#maxlength' => 128,
'#description' => t(
'The path to the local directory (on the server) that points to the path defined above. Enter either an absolute server path or a path relative to the !indexphp file. If left empty, the CKEditor module will try to find the right path.index.php
'
)
) .
'' . ckeditor_plugins_path(TRUE) . '
'
)
)
);
$form['ckeditor_advanced_settings']['ckfinder_path'] = array(
'#type' => 'textfield',
'#title' => t('Path to CKFinder'),
'#default_value' => !empty($profile->settings['ckfinder_path']) ? $profile->settings['ckfinder_path'] : '%m/ckfinder',
'#size' => 40,
'#maxlength' => 128,
'#description' => t(
'The path to CKFinder (AJAX based file manager downloaded from !ckfindercom) relative to the document root.',
array(
'!ckfindercom' => l(t('ckfinder.com'), 'http://cksource.com/ckfinder')
)
) .
'%b
',
'!m' => '%m
',
'!l' => '%l
',
'!base' => '' . base_path() . '
',
'!files' => '' . base_path() . $module_drupal_path . '
',
'!library' => '' . base_path() . 'libraries/
'
)
) .
'' . ckfinder_path() . '
'
)
)
);
$form['ckeditor_advanced_settings']['show_fieldnamehint'] = array(
'#type' => 'radios',
'#title' => t('Show field name hint below each rich text editor'),
'#default_value' => !empty($profile->settings['show_fieldnamehint']) ? $profile->settings['show_fieldnamehint'] : 't',
'#options' => array(
't' => t('Yes'),
'f' => t('No')
),
'#description' => t('This only applies to users with the "administer ckeditor" permissions.'),
);
if (variable_get('file_downloads', '') == FILE_DOWNLOADS_PRIVATE) {
$form['ckeditor_advanced_settings']['ckeditor_allow_download_private_files'] = array(
'#type' => 'checkbox',
'#title' => t('Enable access to files located in the private folder'),
'#default_value' => !empty($profile->settings['ckeditor_allow_download_private_files']),
'#return_value' => 't',
'#description' => t(
'Use this option with care. If checked, CKEditor will allow anyone knowing the URL to view a file located inside of the private path (!private_path), but only if there is no information about the file in the Drupal database. If the path below is specified, anyone will have access only to that location.',
array(
'!private_path' => '' . realpath(file_directory_path()) . '
'
)
),
'#required' => FALSE
);
$current_private_dir = !empty($profile->settings['private_dir']) ? $profile->settings['private_dir'] : '';
$form['ckeditor_advanced_settings']['private_dir'] = array(
'#type' => 'textfield',
'#title' => t('Location of files uploaded with CKEditor in the private folder'),
'#default_value' => !empty($profile->settings['private_dir']) ? $profile->settings['private_dir'] : '',
'#size' => 40,
'#maxlength' => 255,
'#description' => t('The path relative to the location of the private directory where CKEditor should store uploaded files.') .
'' . realpath(file_directory_path()) . DIRECTORY_SEPARATOR . '
'
)
) .
'%u
',
'!n' => '%n
'
)
) .
'' . $current_private_dir . ' (' . str_replace('/', DIRECTORY_SEPARATOR, file_create_path(str_replace(array('%u', '%n'), array('UID', 'UNAME'), $current_private_dir))) . ')
'
)
)
);
}
if (function_exists('linktocontent_node_menu') && function_exists('pathfilter_filter')) {
$form['ckeditor_advanced_settings']['linktoc'] = array(
'#type' => 'select',
'#options' => array('p' => t('Link to paths only'), 'n' => t('Link using internal: links'), 'pn' => t('Allow the user to select between paths and internal links')),
'#title' => t('Path Filter & Link To Content integration'),
'#default_value' => empty($profile->settings['linktoc']) ? 'p' : $profile->settings['linktoc'],
'#description' => t(
'With the !plink extension it is possible to use internal: links. By default the !link extension is linking to nodes using paths.',
array(
'!plink' => l(t('Path Filter'), 'http://drupal.org/project/pathfilter'),
'!link' => l(t('Link To Content'), 'http://drupal.org/project/linktocontent')
)
)
);
}
$form['ckeditor_advanced_settings']['ckeditor_aggregate'] = array(
'#type' => 'radios',
'#title' => t('Aggregate ckeditor.js
'),
'#default_value' => !empty($profile->settings['ckeditor_aggregate']) ? $profile->settings['ckeditor_aggregate'] : 'f',
'#options' => array(
't' => t('Enabled'),
'f' => t('Disabled')
),
'#description' => t('When enabled, ckeditor.js
will be aggregated if JavaScript aggregation is enabled. Not recommended.'),
);
$form['ckeditor_advanced_settings']['toolbar_wizard'] = array(
'#type' => 'radios',
'#title' => t('Use toolbar Drag&Drop feature'),
'#default_value' => !empty($profile->settings['toolbar_wizard']) ? $profile->settings['toolbar_wizard'] : 't',
'#options' => array(
't' => t('Enabled'),
'f' => t('Disabled')
),
'#description' => t('When enabled, the toolbar can be built by using the drag-and-drop feature. Otherwise you will need to enter the toolbar configuration manually to the text box.'),
);
$form['submit'] = array(
'#type' => 'submit',
'#value' => $btn
);
return $form;
}
function ckeditor_admin_global_profile_form_validate($form, &$form_state) {
$edit =& $form_state['values'];
if (!preg_match('#^\s*\[(?:\s*(?:\{\s*[\w:\'" ,]*\s*\[(?:\s*([\'\"\"])(?:\w+|-)\1\s*[,]?\s*)+\]\s*\}|([\'\"\"])\/\2)\s*[,]?\s*)+\]\s*$#U', $edit['simple_toolbar']) && !preg_match('#^\s*\[(?:\s*(?:\[(?:\s*([\'\"\"])(?:\w+|-)\1\s*[,]?\s*)+\]|([\'\"\"])\/\2)\s*[,]?\s*)+\]\s*$#', $edit['simple_toolbar'])) {
form_set_error('simple_toolbar', t('Enter a valid toolbar configuration.'));
}
//include mode and all other fields are empty, invalid
if ($edit['excl_mode'] == 1 && empty($edit['excl'])) {
form_set_error('excl_mode', t('Include mode selected, but no paths given. Enter at least one path where CKEditor should appear.'));
}
else {
ckeditor_admin_profile_validate_fieldpaths('excl', $edit['excl']);
}
ckeditor_admin_profile_validate_fieldpaths('simple_incl', $edit['simple_incl']);
}
function ckeditor_admin_global_profile_form_submit($form, &$form_state) {
module_load_include('inc', 'ckeditor', 'includes/ckeditor.lib');
$edit =& $form_state['values'];
$edit['name'] = 'CKEditor Global Profile';
if (isset($edit['rank'])) {
$edit['rank'] = explode('>', str_replace(' ', '', $edit['rank']));
}
if (isset($edit['_profile'])) {
db_query("DELETE FROM {ckeditor_settings} WHERE name = '%s'", $edit['_profile']->name);
db_query("DELETE FROM {ckeditor_role} WHERE name = '%s'", $edit['_profile']->name);
}
//strip whitespaces
if (empty($edit['ckeditor_local_path'])) {
$edit['ckeditor_local_path'] = '';
}
else {
$edit['ckeditor_local_path'] = trim($edit['ckeditor_local_path']);
}
//strip slash from the end
if (empty($edit['ckeditor_path'])) {
$edit['ckeditor_path'] = '';
}
$edit['ckeditor_path'] = trim(rtrim($edit['ckeditor_path'], "/"));
if ($edit['ckeditor_path'] && 0 !== strpos($edit['ckeditor_path'], "/") && 0 !== strpos($edit['ckeditor_path'], "%")) {
//ensure that slash is at the beginning
$edit['ckeditor_path'] = "/". $edit['ckeditor_path'];
}
//no slash at the end
$edit['ckeditor_local_path'] = trim(rtrim($edit['ckeditor_local_path'], "/"));
//strip whitespaces
if (empty($edit['ckeditor_plugins_local_path'])) {
$edit['ckeditor_plugins_local_path'] = '';
}
else {
$edit['ckeditor_plugins_local_path'] = trim($edit['ckeditor_plugins_local_path']);
}
//strip slash from the end
if (empty($edit['ckeditor_plugins_path'])) {
$edit['ckeditor_plugins_path'] = '';
}
$edit['ckeditor_plugins_path'] = trim(rtrim($edit['ckeditor_plugins_path'], "/"));
if ($edit['ckeditor_plugins_path'] && 0 !== strpos($edit['ckeditor_plugins_path'], "/") && 0 !== strpos($edit['ckeditor_plugins_path'], "%")) {
//ensure that slash is at the beginning
$edit['ckeditor_plugins_path'] = "/". $edit['ckeditor_plugins_path'];
}
//no slash at the end
$edit['ckeditor_plugins_path'] = trim(rtrim($edit['ckeditor_plugins_path'], "/"));
//strip slash from the end
if (empty($edit['ckfinder_path'])) {
$edit['ckfinder_path'] = '';
}
$edit['ckfinder_path'] = trim(rtrim($edit['ckfinder_path'], "/"));
if ($edit['ckfinder_path'] && 0 !== strpos($edit['ckfinder_path'], "/") && 0 !== strpos($edit['ckfinder_path'], "%")) {
//ensure that slash is at the beginning
$edit['ckfinder_path'] = "/" . $edit['ckfinder_path'];
}
$settings = ckeditor_admin_values_to_settings($edit);
db_query("INSERT INTO {ckeditor_settings} (name, settings) VALUES ('%s', '%s')", $edit['name'], $settings);
ckeditor_rebuild_selectors($edit['name']);
drupal_set_message(t('The CKEditor Global Profile was saved.'));
$form_state['redirect'] = 'admin/settings/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['rids'], $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);
}
function ckeditor_admin_profile_validate_fieldpaths($fieldname, $paths) {
$myerrors = array();
$rules = preg_split('/[\s,]+/', $paths);
foreach ($rules as $rule) {
$rule = trim($rule);
if (!empty($rule) && strpos($rule, '.') === FALSE && strpos($rule, '/') === FALSE && strpos($rule, '-') === FALSE) {
$myerrors[] = t(
'Rule %rule is ambiguous: please append .* if %rule is a path or prepend *. if %rule is a field.',
array(
'%rule' => $rule
)
);
}
}
if (!empty($myerrors)) {
form_set_error($fieldname, check_plain(implode('