'XSS Filter', 'description' => 'XSS Filter.', 'page callback' => 'ckeditor_filter_xss', 'file' => 'includes/ckeditor.page.inc', 'access callback' => TRUE, 'type' => MENU_CALLBACK, ); $items['ckeditor/disable/wysiwyg/%'] = array( 'title' => 'Disable the WYSIWYG module', 'description' => 'Disable WYSIWYG module.', 'page callback' => 'ckeditor_disable_wysiwyg', 'page arguments' => array(3), 'file' => 'includes/ckeditor.admin.inc', 'access arguments' => array('administer ckeditor'), 'access callback' => TRUE, 'type' => MENU_CALLBACK, ); $items['admin/config/content/ckeditor'] = array( 'title' => 'CKEditor', 'description' => 'Configure the rich text editor.', 'page callback' => 'ckeditor_admin_main', 'file' => 'includes/ckeditor.admin.inc', 'access arguments' => array('administer ckeditor'), 'type' => MENU_NORMAL_ITEM, ); $items['admin/config/content/ckeditor/add'] = array( 'title' => 'Add a new CKEditor profile', 'description' => 'Configure the rich text editor.', 'page callback' => 'drupal_get_form', 'page arguments' => array('ckeditor_admin_profile_form'), 'file' => 'includes/ckeditor.admin.inc', 'access arguments' => array('administer ckeditor'), 'type' => MENU_CALLBACK, ); $items['admin/config/content/ckeditor/clone/%ckeditor_profile'] = array( 'title' => 'Clone the CKEditor profile', 'description' => 'Configure the rich text editor.', 'page callback' => 'drupal_get_form', 'page arguments' => array('ckeditor_admin_profile_clone_form', 5), 'file' => 'includes/ckeditor.admin.inc', 'access arguments' => array('administer ckeditor'), 'type' => MENU_CALLBACK, ); $items['admin/config/content/ckeditor/edit/%ckeditor_profile'] = array( 'title' => 'Edit the CKEditor profile', 'description' => 'Configure the rich text editor.', 'page callback' => 'drupal_get_form', 'page arguments' => array('ckeditor_admin_profile_form', 5), 'file' => 'includes/ckeditor.admin.inc', 'access arguments' => array('administer ckeditor'), 'type' => MENU_CALLBACK, ); $items['admin/config/content/ckeditor/delete/%ckeditor_profile'] = array( 'title' => 'Delete the CKEditor profile', 'description' => 'Configure the rich text editor.', 'page callback' => 'drupal_get_form', 'page arguments' => array('ckeditor_admin_profile_delete_form', 5), 'file' => 'includes/ckeditor.admin.inc', 'access arguments' => array('administer ckeditor'), 'type' => MENU_CALLBACK, ); $items['admin/config/content/ckeditor/addg'] = array( 'title' => 'Add the CKEditor Global profile', 'description' => 'Configure the rich text editor.', 'page callback' => 'drupal_get_form', 'page arguments' => array('ckeditor_admin_global_profile_form', 'add'), 'file' => 'includes/ckeditor.admin.inc', 'access arguments' => array('administer ckeditor'), 'type' => MENU_CALLBACK, ); $items['admin/config/content/ckeditor/editg'] = array( 'title' => 'Edit the CKEditor Global profile', 'description' => 'Configure the rich text editor.', 'page callback' => 'drupal_get_form', 'page arguments' => array('ckeditor_admin_global_profile_form', 'edit'), 'file' => 'includes/ckeditor.admin.inc', 'access arguments' => array('administer ckeditor'), 'type' => MENU_CALLBACK, ); return $items; } /** * Implementation of hook_permission(). * * People -> Permissions */ function ckeditor_permission() { $arr = array(); $arr['administer ckeditor'] = array( 'title' => t('Administer CKEditor access'), 'description' => t('Allow users to change CKEditor settings.') ); $arr['customize ckeditor'] = array( 'title' => t('Customize CKEditor appearance'), 'description' => t('Allow users to customize CKEditor appearance.') ); if (file_exists(ckfinder_path())) { $arr['allow CKFinder file uploads'] = array( 'title' => t('CKFinder access'), 'description' => t('Allow users to use CKFinder.') ); } return $arr; } /** * Implementation of hook_help(). * * This function delegates the execution to ckeditor_help_delegate() in includes/ckeditor.page.inc to * lower the amount of code in ckeditor.module. */ function ckeditor_help($path, $arg) { module_load_include('inc', 'ckeditor', 'includes/ckeditor.page'); return module_invoke('ckeditor', 'help_delegate', $path, $arg); } /** * Implementation of hook_init(). */ function ckeditor_init() { drupal_add_css(drupal_get_path('module', 'ckeditor') . '/ckeditor.css'); } /** * Implementation of hook_form_alter() */ function ckeditor_form_alter(&$form, $form_state, $form_id) { module_load_include('inc', 'ckeditor', 'includes/ckeditor.user'); if ( $form_id == 'user_profile_form') { ckeditor_user_customize($form, $form_state, $form_id); } } /** * Implementation of hook_element_info_alter(). * * Replace the textarea with CKEditor using a callback function (ckeditor_pre_render_text_format). */ function ckeditor_element_info_alter(&$types) { $types['text_format']['#pre_render'][] = 'ckeditor_pre_render_text_format'; } /** * This function creates the HTML objects required for CKEditor. * * @param $element * A fully populated form element to add the editor to. * @return * The same $element with extra CKEditor markup and initialization. */ function ckeditor_pre_render_text_format($element) { static $init = FALSE; if (!isset($element['#format'])) { return $element; } module_load_include('inc', 'ckeditor', 'includes/ckeditor.lib'); if ( $init === FALSE ) { $input_formats = ckeditor_profiles_compile(); drupal_add_js(array('ckeditor' => array('input_formats' => $input_formats, 'plugins' => array())), 'setting'); $init = TRUE; } if (isset($element['value'])) { if (isset($element['summary'])) { $element['value'] = ckeditor_load_by_field($element['value'], $element['format']['format'], TRUE, $element['summary']['#id']); $element['summary'] = ckeditor_load_by_field($element['summary'], $element['format']['format'], FALSE); } else { $element['value'] = ckeditor_load_by_field($element['value'], $element['format']['format']); } } else { $element = ckeditor_load_by_field($element, $element['#format']); } return $element; } /** * Implementation of hook_user(). * * This function delegates the execution to ckeditor_user_delegate() in includes/ckeditor.user.inc to * lower the amount of code in ckeditor.module. */ function ckeditor_user($type, $edit, &$user, $category = NULL) { if (($type == 'form' && $category == 'account') || $type == 'validate') { module_load_include('inc', 'ckeditor', 'includes/ckeditor.user'); return ckeditor_user_delegate($type, $edit, $user, $category); } return NULL; } /** * Load all profiles. Just load one profile if $name is passed in. */ function ckeditor_profile_load($name = '', $clear = FALSE) { static $profiles = array(); global $user; if (empty($profiles) || $clear === TRUE) { $result = db_select('ckeditor_settings', 's')->fields('s')->execute(); foreach ($result as $data) { $data->settings = unserialize($data->settings); $data->input_formats = array(); $profiles[$data->name] = $data; } $input_formats = filter_formats($user); $result = db_select('ckeditor_input_format', 'f')->fields('f')->execute(); foreach ($result as $data) { if (isset($input_formats[$data->format])) { $profiles[$data->name]->input_formats[$data->format] = $input_formats[$data->format]->name; } } } return ($name ? (isset($profiles[urldecode($name)]) ? $profiles[urldecode($name)] : FALSE) : $profiles); } /** * Read the CKEditor path from the Global profile. * * @return * Path to CKEditor folder. */ function ckeditor_path($local = FALSE, $refresh = FALSE) { static $cke_path; static $cke_local_path; if ($refresh || (!$cke_path)) { $mod_path = drupal_get_path('module', 'ckeditor'); $lib_path = 'sites/all/libraries'; $global_profile = ckeditor_profile_load('CKEditor Global Profile', $refresh); //default: path to ckeditor subdirectory in the ckeditor module directory (starting from the document root) //e.g. for http://example.com/drupal it will be /drupal/sites/all/modules/ckeditor/ckeditor $cke_path = $mod_path . '/ckeditor'; //default: path to ckeditor subdirectory in the ckeditor module directory (relative to index.php) //e.g.: sites/all/modules/ckeditor/ckeditor $cke_local_path = $mod_path . '/ckeditor'; if ($global_profile) { $gs = $global_profile->settings; if (isset($gs['ckeditor_path'])) { $tmp_path = $gs['ckeditor_path']; $tmp_path = strtr($tmp_path, array("%b" => base_path(), "%m" => $mod_path, "%l" => $lib_path)); $tmp_path = str_replace('\\', '/', $tmp_path); $tmp_path = str_replace('//', '/', $tmp_path); $cke_path = $tmp_path; if (empty($gs['ckeditor_local_path'])) { //fortunately wildcards are used, we can easily get the right server path if (FALSE !== strpos($gs['ckeditor_path'], "%m")) { $gs['ckeditor_local_path'] = strtr($gs['ckeditor_path'], array("%m" => $mod_path)); } if (FALSE !== strpos($gs['ckeditor_path'], "%l")) { $gs['ckeditor_local_path'] = strtr($gs['ckeditor_path'], array("%l" => 'sites/all/libraries')); } } } //ckeditor_path is defined, but wildcards are not used, we need to try to find out where is //the document root located and append ckeditor_path to it. if (!empty($gs['ckeditor_local_path'])) { $cke_local_path = $gs['ckeditor_local_path']; } elseif (!empty($gs['ckeditor_path'])) { module_load_include('inc', 'ckeditor', 'includes/ckeditor.lib'); $local_path = ckeditor_resolve_url($gs['ckeditor_path'] . "/"); if (FALSE !== $local_path) { $cke_local_path = $local_path; } } } } if ($local) { return $cke_local_path; } else { return $cke_path; } } /** * Read the CKEditor plugins path from the Global profile. * * @return * Path to CKEditor plugins folder. */ function ckeditor_plugins_path($local = FALSE, $refresh = FALSE) { static $cke_plugins_path; static $cke_plugins_local_path; if ($refresh || (!$cke_plugins_path)) { $mod_path = drupal_get_path('module', 'ckeditor'); $lib_path = 'sites/all/libraries'; $global_profile = ckeditor_profile_load('CKEditor Global Profile', $refresh); //default: path to ckeditor subdirectory in the ckeditor module directory (starting from the document root) //e.g. for http://example.com/drupal it will be /drupal/sites/all/modules/ckeditor/ckeditor $cke_plugins_path = base_path() . $mod_path . '/plugins'; //default: path to plugins subdirectory in the ckeditor module directory (relative to index.php) //e.g.: sites/all/modules/ckeditor/plugins $cke_plugins_local_path = $mod_path . '/plugins'; if ($global_profile) { $gs = $global_profile->settings; if (isset($gs['ckeditor_plugins_path'])) { $tmp_path = $gs['ckeditor_plugins_path']; $tmp_path = strtr($tmp_path, array("%b" => base_path(), "%m" => $mod_path, "%l" => $lib_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 '/' } $cke_plugins_path = $tmp_path; if (empty($gs['ckeditor_plugins_local_path'])) { //fortunately wildcards are used, we can easily get the right server path if (FALSE !== strpos($gs['ckeditor_plugins_path'], "%m")) { $gs['ckeditor_plugins_local_path'] = strtr($gs['ckeditor_plugins_path'], array("%m" => $mod_path)); } if (FALSE !== strpos($gs['ckeditor_plugins_path'], "%b")) { $gs['ckeditor_plugins_local_path'] = strtr($gs['ckeditor_plugins_path'], array("%b" => ".")); } if (FALSE !== strpos($gs['ckeditor_plugins_path'], "%l")) { $gs['ckeditor_plugins_local_path'] = strtr($gs['ckeditor_plugins_path'], array("%l" => "sites/all/libraries")); } } } //ckeditor_plugins_path is defined, but wildcards are not used, we need to try to find out where is //the document root located and append ckeditor_plugins_path to it. if (!empty($gs['ckeditor_plugins_local_path'])) { $cke_plugins_local_path = $gs['ckeditor_plugins_local_path']; } elseif (!empty($gs['ckeditor_plugins_path'])) { module_load_include('inc', 'ckeditor', 'includes/ckeditor.lib'); $local_path = ckeditor_resolve_url($gs['ckeditor_plugins_path'] . "/"); if (FALSE !== $local_path) { $cke_plugins_local_path = $local_path; } } } } if ($local) { return $cke_plugins_local_path; } else { return $cke_plugins_path; } } /** * Read the CKFinder path from the Global profile. * * @return * Path to CKFinder folder. */ function ckfinder_path($refresh = FALSE) { static $ckf_path; if ($refresh || (!$ckf_path)) { $mod_path = drupal_get_path('module', 'ckeditor'); $lib_path = 'sites/all/libraries'; $global_profile = ckeditor_profile_load('CKEditor Global Profile', $refresh); //default: path to ckeditor subdirectory in the ckeditor module directory (starting from the document root) //e.g. for http://example.com/drupal it will be /drupal/sites/all/modules/ckeditor/ckeditor $ckf_path = $mod_path . '/ckfinder'; if ($global_profile) { $gs = $global_profile->settings; if (isset($gs['ckfinder_path'])) { $tmp_path = $gs['ckfinder_path']; $tmp_path = strtr($tmp_path, array("%b" => base_path(), "%m" => $mod_path, "%l" => $lib_path)); $tmp_path = str_replace('\\', '/', $tmp_path); $tmp_path = str_replace('//', '/', $tmp_path); $ckf_path = $tmp_path; } } } return $ckf_path; } /** * Implementation of hook_features_api(). * * Allow exporting of CKEditor profiles by the Features module. */ function ckeditor_features_api() { return array( 'ckeditor_profile' => array( 'name' => t('CKEditor profiles'), 'default_hook' => 'ckeditor_profile_defaults', 'default_file' => FEATURES_DEFAULTS_INCLUDED, 'file' => drupal_get_path('module', 'ckeditor') . '/includes/ckeditor.features.inc', ) ); } /** * Implementation of hook_file_download(). * Support for private downloads. * CKEditor does not implement any kind of potection on private files. */ function ckeditor_file_download($uri) { if ($path = file_create_url($uri)) { $result = db_query("SELECT f.* FROM {file_managed} f WHERE uri = :uri", array(':uri' => $uri)); foreach ($result as $record) { return NULL; } //No info in DB? Probably a file uploaded with FCKeditor / CKFinder $global_profile = ckeditor_profile_load("CKEditor Global Profile"); //Assume that files inside of ckeditor directory belong to the CKEditor. If private directory is set, let the decision about protection to the user. $private_dir_db = $private_dir = isset($global_profile->settings['private_dir']) ? trim($global_profile->settings['private_dir'], '\/') : ''; $private_dir_db = str_replace(array('\\%u', '\\%n'), array('', ''), $private_dir_db); $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('private://', '#') . $private_dir . '#'; if (!strstr($uri, 'private://') && !strstr($uri, 'public://')) { $path = 'private://' . $uri; } else { $path = $uri; } //check if CKEditor's "Enable access to files located in the private folder" option is disabled or enabled $allow_download_private_files = FALSE; if (isset($global_profile->settings['ckeditor_allow_download_private_files']) && $global_profile->settings['ckeditor_allow_download_private_files'] === 't') { $allow_download_private_files = TRUE; } //denied access to file if private upload is set and CKEditor's "Enable access to files located in the private folder" option is disabled if ($allow_download_private_files == FALSE ) return NULL; //check if file can be served by comparing regex and path to file if (preg_match($regex, $path)) { $info = image_get_info($uri); return array('Content-Type' => $info['mime_type']); } } }