home | career | drupal | java | mac | mysql | perl | php | scala | uml | unix

Drupal example source code file (ckeditor.module)

This example Drupal source code file (ckeditor.module) is included in the DevDaily.com "Drupal Source Code Warehouse" project. The intent of this project is to help you "Learn Drupal by Example".

PHP - Drupal tags/keywords

array, ckeditor, directory, element, empty, file, foreach, function, host, id, if, php, settings, string

The ckeditor.module Drupal example source code

<?php
// $Id: ckeditor.module,v 1.4.2.31 2010/09/27 12:49:01 dczepierga Exp $
/**
 * CKEditor - The text editor for Internet - http://ckeditor.com
 * Copyright (c) 2003-2009, CKSource - Frederico Knabben. All rights reserved.
 *
 * == 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
 * CKEditor Module for Drupal 6.x
 *
 * This module allows Drupal to replace textarea fields with CKEditor.
 *
 * 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 ckeditor.config.js or fckconfig.js
 */
define('CKEDITOR_FORCE_SIMPLE_TOOLBAR_NAME', 'DrupalBasic') ;
define('CKEDITOR_ENTERMODE_P', 1);
define('CKEDITOR_ENTERMODE_BR', 2);
define('CKEDITOR_ENTERMODE_DIV', 3);

global $_ckeditor_configuration;
global $_ckeditor_ids;

$_ckeditor_configuration = array();
$_ckeditor_ids = array();

/**
* Implementation of hook_form_alter()
*/
function ckeditor_form_alter(&$form, $form_state, $form_id) {
  // [#659278], [#666560], [#666616]
  if (substr($form_id, -10) == '_node_form') {
    $nodetype = $form['type']['#value'];
    if (!empty($form['body_field']['teaser_js']['#teaser'])) {
      $setting['ckeditor']['teaser'] = $form['body_field']['teaser_js']['#teaser'];
      drupal_add_js($setting, 'setting');
    }
  }
}

/**
 * Implementation of hook_help().
 *
 * This function delegates 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_user().
 *
 * This function delegates 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' && user_access('access ckeditor')) || $type == 'validate') {
    module_load_include('inc', 'ckeditor', 'includes/ckeditor.user');
    return ckeditor_user_delegate($type, $edit, $user, $category);
  }
  return NULL;
}

/**
 * Implementation of hook_perm().
 * Administer -> User management -> Permissions
 */
function ckeditor_perm() {
  $arr = array('administer ckeditor', 'access ckeditor');
  if (file_exists(drupal_get_path('module', 'ckeditor') . "/ckfinder")) {
    $arr[] = 'allow CKFinder file uploads';
  }
  return $arr;
}

/**
 * Implementation of hook_elements().
 * Replace textarea with CKEditor using callback function (ckeditor_process_textarea)
 */
function ckeditor_elements() {
  $type = array();
  $type['textfield'] = array(
    '#process' => array(
      'ckeditor_process_input'
    ),
  );
  // only roles with permission get the ckeditor
  if (user_access('access ckeditor')) {
    $type['textarea'] = array('#process' => array('ckeditor_process_textarea'));
    $type['form'] = array('#after_build' => array('ckeditor_process_form'));
    $type['hidden'] = array('#process' => array('ckeditor_process_hidden'));
  }
  return $type;
}

function ckeditor_process_hidden($element, $edit, $form_state, $complete_form) {
  if (!empty($element['#value']) && in_array($element['#value'], array('panels_edit_display_form', 'panels_panel_context_edit_content'))) {
    $fake_element = array('#id' => 'edit-body');
    ckeditor_process_textarea($fake_element);
  }
  return $element;
}

function ckeditor_process_form(&$form) {
  global $_ckeditor_configuration, $_ckeditor_ids;
  static $processed_textareas = array();
  static $found_textareas = array();

  //Skip if:
  // - we're not editing an element
  // - ckeditor is not enabled (configuration is empty)
  if (arg(1) == "add" || arg(1) == "reply" || !count($_ckeditor_configuration)) {
    return $form;
  }

  $ckeditor_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'], $_ckeditor_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'];

          array_push($processed_textareas, $textarea_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);
          $ckeditor_filters = array();

          //loop through all enabled filters
          foreach ($enabled as $id => $filter) {
            //but use only that one selected in CKEditor profile
            if (in_array($id, array_keys($_ckeditor_configuration[$textarea_id]['filters'])) && $_ckeditor_configuration[$textarea_id]['filters'][$id]) {
              if (!isset($ckeditor_filters[$textarea_id])) {
                $ckeditor_filters[$textarea_id] = array();
              }
              $ckeditor_filters[$textarea_id][] = $id ."/". $format;
            }
          }

          //No filters assigned, remove xss class
          if (empty($ckeditor_filters[$textarea_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.
      ckeditor_process_form($element);
    }
  }

  //We're in a form
  if (isset($form['#action'])) {
    //some textareas associated with CKEditor has not been processed
    if (count($processed_textareas) < count($_ckeditor_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($element['#id'], $processed_textareas) && !empty($_ckeditor_configuration[$id]['filters']) && array_sum($_ckeditor_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
          $ckeditor_filters[$element['#id']][] = "filter/0/1";
          $element['#attributes']['class'] = strtr($element['#attributes']['class'], array("checkxss1" => "filterxss1", "checkxss2" => "filterxss2"));
        }
      }
    }
  }

  if (!empty($ckeditor_filters)) {
    foreach ($ckeditor_filters as $id => $filters) {
      $arr['settings'][$id]['filters'] = $filters;
    }
    drupal_add_js(array('ckeditor' => $arr), 'setting');
  }

  return $form;
}

/**
 * Allow more than 255 chars in Allowed HTML tags textfield
 */
function ckeditor_process_input($element) {
  if ($element['#id']=='edit-allowed-html-1') {
    $element['#maxlength'] = max($element['#maxlength'], 1024);
  }
  return $element;
}

/**
 * Implementation of hook_menu().
 */
function ckeditor_menu() {
  $items = array();

  $items['ckeditor/xss'] = array(
    'title' => 'XSS Filter',
    'description' => 'XSS Filter.',
    'page callback' => 'ckeditor_filter_xss',
    'file' => 'includes/ckeditor.page.inc',
    'access arguments' => array('access ckeditor'),
    'type' => MENU_CALLBACK,
  );

  $items['admin/settings/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/settings/ckeditor/add'] = array(
    'title' => 'Add 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/settings/ckeditor/clone/%ckeditor_profile'] = array(
    'title' => 'Clone CKEditor profile',
    'description' => 'Configure the rich text editor.',
    'page callback' => 'drupal_get_form',
    'page arguments' => array('ckeditor_admin_profile_clone_form', 4),
    'file' => 'includes/ckeditor.admin.inc',
    'access arguments' => array('administer ckeditor'),
    'type' => MENU_CALLBACK,
  );

  $items['admin/settings/ckeditor/edit/%ckeditor_profile'] = array(
    'title' => 'Edit CKEditor profile',
    'description' => 'Configure the rich text editor.',
    'page callback' => 'drupal_get_form',
    'page arguments' => array('ckeditor_admin_profile_form', 4),
    'file' => 'includes/ckeditor.admin.inc',
    'access arguments' => array('administer ckeditor'),
    'type' => MENU_CALLBACK,
  );

  $items['admin/settings/ckeditor/delete/%ckeditor_profile'] = array(
    'title' => 'Delete CKEditor profile',
    'description' => 'Configure the rich text editor.',
    'page callback' => 'drupal_get_form',
    'page arguments' => array('ckeditor_admin_profile_delete_form', 4),
    'file' => 'includes/ckeditor.admin.inc',
    'access arguments' => array('administer ckeditor'),
    'type' => MENU_CALLBACK,
  );

  $items['admin/settings/ckeditor/addg'] = array(
    'title' => 'Add 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/settings/ckeditor/editg'] = array(
    'title' => 'Edit 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_init().
 */
function ckeditor_init() {
  drupal_add_css(drupal_get_path('module', 'ckeditor') .'/ckeditor.css');
}

/**
 * Implementation of hook_file_download().
 * Support for private downloads.
 * CKEditor does not implement any kind of potection on private files.
 */
function ckeditor_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 / 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 = 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 CKEditor 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 ckeditor_profile_load($name = '', $clear = FALSE) {
  static $profiles = array();

  if (empty($profiles) || $clear === TRUE) {
    $result = db_query("SELECT * FROM {ckeditor_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 {ckeditor_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);
}

/**
 * This function create the HTML objects required for the CKEditor
 *
 * @param $element
 *   A fully populated form elment to add the editor to
 * @return
 *   The same $element with extra CKEditor markup and initialization
 */
function ckeditor_process_textarea($element) {
  static $is_running = FALSE;
  static $num = 1;
  static $processed_ids=array();
  global $user, $theme, $language, $_ckeditor_configuration, $_ckeditor_ids;
  $settings = array();
  $enabled = TRUE;
  $suffix = "";
  $class = "";
  //hack for module developers that want to disable ckeditor 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;
  }

  if (isset($processed_ids[$element['#id']])) {
    //statement for node preview purpose, when second textarea element with the same id is processing to add class which ckeditor behavior must process
    if (empty($element['#attributes']['class'])) {
      $element['#attributes']['class'] = $processed_ids[$element['#id']]['class'];
    }
    else {
      $element['#attributes']['class'] .= " ". $processed_ids[$element['#id']]['class'];
    }
    if (empty($element['#suffix'])) {
      $element['#suffix'] = $processed_ids[$element['#id']]['suffix'];
    }
    else {
      $element['#suffix'] .= $processed_ids[$element['#id']]['suffix'];
    }
    return $element;
  }
  else {
    $processed_ids[$element['#id']] = array();
  }

  module_load_include('inc', 'ckeditor', 'includes/ckeditor.lib');

  $global_profile = ckeditor_profile_load('CKEditor Global Profile');
  if ($global_profile) {
    $global_conf = $global_profile->settings;
    if ($global_conf) {
      $enabled = ckeditor_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 = ckeditor_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] = ckeditor_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 = path_to_theme() .'/';
  $host = base_path();
  if (!isset($element['#rows'])){
    $element['#rows'] = 5;
  }
  // 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'];
    $class = 'ckeditor-mod';
    $_ckeditor_ids[] = $textarea_id;
    $ckeditor_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") {
      $_ckeditor_configuration[$element['#id']] = $conf;

      //let ckeditor know when perform XSS checks auto/manual
      if ($conf['ss'] == 1) {
        $xss_class = 'checkxss1';
      }
      else {
        $xss_class = 'checkxss2';
      }

      $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-->';
      }
      if (isset($element['#value'])) {
        $content .= $element['#value'];
      }
      $wysiwyg_link = '';
      $wysiwyg_link .= "<a class=\"ckeditor_links\" style=\"display:none\" href=\"javascript:Drupal.ckeditorToggle('{$textarea_id}','". str_replace("'", "\\'", t('Switch to plain text editor')) ."','". str_replace("'", "\\'", t('Switch to rich text editor')) ."',". $xss_check .");\" id=\"switch_{$textarea_id}\">";
      $wysiwyg_link .= $ckeditor_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
      $suffix .= $wysiwyg_link;
    }
    // setting some variables
    $module_drupal_path = drupal_get_path('module', 'ckeditor');
    $module_full_path   = $host . $module_drupal_path;
    $editor_path        = ckeditor_path(FALSE);
    $editor_local_path  = ckeditor_path(TRUE);
    // get the default drupal files path
    $files_path         = $host . file_directory_path();

    // sensible default for small toolbars
    if (isset($element['#rows'])) {
      $height = intval($element['#rows']) * 14 + 140;
    } else {
      $height = 400;
    }
    if (!$is_running) {
      drupal_add_js($module_drupal_path .'/includes/ckeditor.utils.js', 'module', variable_get('preprocess_js', FALSE) ? 'header' : 'footer');
      /* In D6 drupal_add_js() can't add external JS, in D7 use drupal_add_js(...,'external') */
      if ( $conf['popup'] != 't' ) {
        if (isset($conf['ckeditor_load_method'])) {
          drupal_set_html_head('<script type="text/javascript" src="'. $editor_path . '/' . $conf['ckeditor_load_method'] . '?I"></script>');
          if ($conf['ckeditor_load_method'] == 'ckeditor_basic.js') {
            drupal_set_html_head('<script type="text/javascript">CKEDITOR.loadFullCoreTimeout = ' . $conf['ckeditor_load_time_out'] . ';</script>');
            drupal_add_js(array('ckeditor' => array('load_timeout' => TRUE)), 'setting');
          }
        }
        else {
          drupal_set_html_head('<script type="text/javascript" src="'. $editor_path .'/ckeditor.js?I"></script>');
        }
      }
      else {
        drupal_set_html_head('<script type="text/javascript" src="'. $editor_path .'/ckeditor_basic.js?I"></script>');
      }
      drupal_add_js(array('ckeditor' => array('module_path' => $module_full_path)), 'setting');
      if ($conf['popup'] == 't') {
        drupal_add_js(array('ckeditor' => array('editor_path' => $editor_path)), 'setting');
      }
      if (module_exists('paging')) {
        drupal_add_js(array('ckeditor' => array('pagebreak' => TRUE)), 'setting');
      }
      if (module_exists('linktocontent_node')) {
        drupal_add_js(array('ckeditor' => array('linktocontent_node' => TRUE)), 'setting');
      }
      if (module_exists('linktocontent_menu')) {
        drupal_add_js(array('ckeditor' => array('linktocontent_menu' => TRUE)), 'setting');
      }
      if (module_exists('pagebreak')) {
        drupal_add_js(array('ckeditor' => array('pagebreak' => TRUE)), 'setting');
      }
      if (function_exists('linktocontent_node_menu')) {
        if (!empty($global_conf['linktoc']) && $global_conf['linktoc']!='p') {
          drupal_add_js(array('ckeditor' => array('linktocontent_node_path_filter' => TRUE)), 'setting');
          if ($global_conf['linktoc'] == 'pn') {
            drupal_add_js(array('ckeditor' => array('linktocontent_node_select_type' => TRUE)), 'setting');
          }
        }
      }
      $is_running = TRUE;
    }

    $toolbar = $conf['toolbar'];
    //$height += 100; // for larger toolbars

    $force_simple_toolbar = ckeditor_is_enabled('1', empty($conf['simple_incl_regex']) ? '' : $conf['simple_incl_regex'], $element['#id'], $_GET['q']);
    if (!$force_simple_toolbar) {
      $force_simple_toolbar = ckeditor_is_enabled('1', empty($global_conf['simple_incl_regex']) ? '' : $global_conf['simple_incl_regex'], $element['#id'], $_GET['q']);
    }
    if ($force_simple_toolbar) {
      $toolbar = CKEDITOR_FORCE_SIMPLE_TOOLBAR_NAME;
    }

    if (!empty($conf['theme_config_js']) && $conf['theme_config_js'] == 't' && file_exists($themepath .'ckeditor.config.js')) {
      $ckeditor_config_path = $host . $themepath .'ckeditor.config.js?'. @filemtime($themepath .'ckeditor.config.js');
    }
    else {
      $ckeditor_config_path = $module_full_path ."/ckeditor.config.js?". @filemtime($module_drupal_path ."/ckeditor.config.js");
    }

    $settings[$textarea_id]['customConfig'] = $ckeditor_config_path;
    $settings[$textarea_id]['defaultLanguage'] = $conf['lang'];
    $settings[$textarea_id]['toolbar'] = $toolbar;
    $settings[$textarea_id]['enterMode'] = constant("CKEDITOR_ENTERMODE_" . strtoupper($conf['enter_mode']));
    $settings[$textarea_id]['shiftEnterMode'] = constant("CKEDITOR_ENTERMODE_" . strtoupper($conf['shift_enter_mode']));
    $settings[$textarea_id]['toolbarStartupExpanded'] = ( $conf['expand']=='t' );
    $settings[$textarea_id]['customConfig'] = $ckeditor_config_path;
    $settings[$textarea_id]['width'] = $conf['width'];
    $settings[$textarea_id]['height'] = $height;
    $settings[$textarea_id]['skin'] = $conf['skin'];
    $settings[$textarea_id]['format_tags'] = $conf['font_format'];
    if (isset($conf['language_direction'])) {
      switch ($conf['language_direction']) {
        case 'default':
          if (defined('LANGUAGE_RTL') && $language->direction == LANGUAGE_RTL) {
            $settings[$textarea_id]['contentsLangDirection'] = 'rtl';
          }
          break;
        case 'ltr':
          $settings[$textarea_id]['contentsLangDirection'] = 'ltr';
          break;
        case 'rtl':
          $settings[$textarea_id]['contentsLangDirection'] = 'rtl';
          break;
      }
    }
    if (isset($conf['scayt_autoStartup']) && $conf['scayt_autoStartup'] == 't') {
      $settings[$textarea_id]['scayt_autoStartup'] = TRUE;
    } else {
      $settings[$textarea_id]['scayt_autoStartup'] = FALSE;
    }
    if ($conf['auto_lang']=="f") {
      $settings[$textarea_id]['language'] = $conf['lang'];
    }
    if (isset($conf['forcePasteAsPlainText']) && $conf['forcePasteAsPlainText'] == 't') {
      $settings[$textarea_id]['forcePasteAsPlainText'] = TRUE;
    }
    if (isset($conf['custom_formatting']) && $conf['custom_formatting'] == 't') {
      foreach ($conf['formatting']['custom_formatting_options'] as $k => $v) {
        if ($v === 0) {
          $conf['formatting']['custom_formatting_options'][$k] = FALSE;
        } else {
          $conf['formatting']['custom_formatting_options'][$k] = TRUE;
        }
      }
      $settings[$textarea_id]['output_pre_indent'] = $conf['formatting']['custom_formatting_options']['pre_indent'];
      unset($conf['formatting']['custom_formatting_options']['pre_indent']);
      $settings[$textarea_id]['custom_formatting'] = $conf['formatting']['custom_formatting_options'];
    }
    // add code for filebrowser for users that have access
    $filebrowser = !empty($conf['filebrowser']) ? $conf['filebrowser'] : 'none';
    $filebrowser_image = !empty($conf['filebrowser_image']) ? $conf['filebrowser_image'] : $filebrowser;
    $filebrowser_flash = !empty($conf['filebrowser_flash']) ? $conf['filebrowser_flash'] : $filebrowser;

    if ($filebrowser == 'imce' && !module_exists('imce')) {
      $filebrowser = 'none';
    }

    if ($filebrowser == 'tinybrowser' && !module_exists('tinybrowser')) {
      $filebrowser = 'none';
    }

    if ($filebrowser == 'ib' && !module_exists('imagebrowser')) {
      $filebrowser = 'none';
    }
    if ($filebrowser == 'webfm' && !module_exists('webfm_popup')) {
      $filebrowser = 'none';
    }

    if ($filebrowser_image != $filebrowser) {
      if ($filebrowser_image == 'imce' && !module_exists('imce')) {
        $filebrowser_image = $filebrowser;
      }
      if ($filebrowser_image == 'tinybrowser' && !module_exists('tinybrowser')) {
        $filebrowser_image = $filebrowser;
      }
      if ($filebrowser_image == 'ib' && !module_exists('imagebrowser')) {
        $filebrowser_image = $filebrowser;
      }
      if ($filebrowser_image == 'webfm' && !module_exists('webfm_popup')) {
        $filebrowser_image = $filebrowser;
      }
    }

    if ($filebrowser_flash != $filebrowser) {
      if ($filebrowser_flash == 'imce' && !module_exists('imce')) {
        $filebrowser_flash = $filebrowser;
      }
      if ($filebrowser_image == 'tinybrowser' && !module_exists('tinybrowser')) {
        $filebrowser_flash = $filebrowser;
      }
      if ($filebrowser_flash == 'ib' && !module_exists('imagebrowser')) {
        $filebrowser_flash = $filebrowser;
      }
      if ($filebrowser_flash == 'webfm' && !module_exists('webfm_popup')) {
        $filebrowser_flash = $filebrowser;
      }
    }

    if ($filebrowser == 'ckfinder' || $filebrowser_image == 'ckfinder' || $filebrowser_flash == 'ckfinder') {
      if (user_access('allow CKFinder file uploads')) {
        if (!empty($profile->settings['UserFilesPath'])) {
          $_SESSION['ckeditor']['UserFilesPath'] = strtr($profile->settings['UserFilesPath'], array("%f" => file_directory_path(), "%u" => $user->uid, "%b" => $host, "%n" => $user->name));
        }
        if (!empty($profile->settings['UserFilesAbsolutePath'])) {
          $_SESSION['ckeditor']['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['ckeditor']['UserFilesPath'] = url('system/files') .'/'. $private_dir .'/';
            $_SESSION['ckeditor']['UserFilesAbsolutePath'] = realpath(file_directory_path()) . DIRECTORY_SEPARATOR . $private_dir . DIRECTORY_SEPARATOR;
          }
          else {
            $_SESSION['ckeditor']['UserFilesPath'] = url('system/files') .'/';
            $_SESSION['ckeditor']['UserFilesAbsolutePath'] = realpath(file_directory_path()) . DIRECTORY_SEPARATOR;
          }
        }
      }
    }

    if (in_array('tinybrowser', array($filebrowser, $filebrowser_image, $filebrowser_flash))) {
      $popup_win_size = variable_get('tinybrowser_popup_window_size', '770x480');
      if (!preg_match('#\d+x\d+#is', $popup_win_size)) {
        $popup_win_size = '770x480';
      }
      $popup_win_size = trim($popup_win_size);
      $popup_win_size = strtolower($popup_win_size);
      $win_size = split('x', $popup_win_size);
    }

    switch ($filebrowser) {
      case 'ckfinder':
        if (user_access('allow CKFinder file uploads')) {
          $settings[$textarea_id]['filebrowserBrowseUrl'] = $module_full_path .'/ckfinder/ckfinder.html';
          $settings[$textarea_id]['filebrowserImageBrowseUrl'] = $module_full_path .'/ckfinder/ckfinder.html?Type=Images';
          $settings[$textarea_id]['filebrowserFlashBrowseUrl'] = $module_full_path .'/ckfinder/ckfinder.html?Type=Flash';
          $settings[$textarea_id]['filebrowserUploadUrl'] = $module_full_path .'/ckfinder/core/connector/php/connector.php?command=QuickUpload&type=Files';
          $settings[$textarea_id]['filebrowserImageUploadUrl'] = $module_full_path .'/ckfinder/core/connector/php/connector.php?command=QuickUpload&type=Images';
          $settings[$textarea_id]['filebrowserFlashUploadUrl'] = $module_full_path .'/ckfinder/core/connector/php/connector.php?command=QuickUpload&type=Flash';
        }
        break;
      case 'imce':
        $settings[$textarea_id]['filebrowserBrowseUrl'] = $host ."index.php?q=imce&app=ckeditor|sendto@ckeditor_fileUrl|";
        break;
      case 'webfm':
        if (user_access('access webfm')) {
          $settings[$textarea_id]['filebrowserBrowseUrl'] = $host ."index.php?q=webfm_popup";
        }
        break;
      case 'ib':
        if (user_access('browse own images')) {
          $settings[$textarea_id]['filebrowserBrowseUrl'] = $host ."index.php?q=imagebrowser/view/browser&app=ckeditor";
          $settings[$textarea_id]['filebrowserWindowWidth'] = 700;
          $settings[$textarea_id]['filebrowserWindowHeight'] = 520;
        }
        break;
      case 'tinybrowser':
        $settings[$textarea_id]['filebrowserBrowseUrl'] = $host . drupal_get_path('module','tinybrowser') . "/tinybrowser/tinybrowser.php?type=file";
        $settings[$textarea_id]['filebrowserWindowWidth'] = (int)$win_size[0] + 15;
        $settings[$textarea_id]['filebrowserWindowHeight'] = (int)$win_size[1] + 15;
        break;
    }

    if ($filebrowser_image != $filebrowser) {
      switch ($filebrowser_image) {
        case 'ckfinder':
          if (user_access('allow CKFinder file uploads')) {
            $settings[$textarea_id]['filebrowserImageBrowseUrl'] = $module_full_path .'/ckfinder/ckfinder.html?Type=Images';
            $settings[$textarea_id]['filebrowserImageUploadUrl'] = $module_full_path .'/ckfinder/core/connector/php/connector.php?command=QuickUpload&type=Images';
          }
          break;
        case 'imce':
          $settings[$textarea_id]['filebrowserImageBrowseUrl'] = $host ."index.php?q=imce&app=ckeditor|sendto@ckeditor_fileUrl|";
          break;
        case 'webfm':
          if (user_access('access webfm')) {
            $settings[$textarea_id]['filebrowserImageBrowseUrl'] = $host ."index.php?q=webfm_popup";
          }
          break;
        case 'ib':
          if (user_access('browse own images')) {
            $settings[$textarea_id]['filebrowserImageBrowseUrl'] = $host ."index.php?q=imagebrowser/view/browser&app=ckeditor";
            $settings[$textarea_id]['filebrowserImageWindowWidth'] = 680;
            $settings[$textarea_id]['filebrowserImageWindowHeight'] = 439;
          }
          break;
        case 'tinybrowser':
          $settings[$textarea_id]['filebrowserImageBrowseUrl'] = $host . drupal_get_path('module','tinybrowser') . "/tinybrowser/tinybrowser.php?type=image";
          $settings[$textarea_id]['filebrowserImageWindowWidth'] = (int)$win_size[0] + 15;
          $settings[$textarea_id]['filebrowserImageWindowHeight'] = (int)$win_size[1] + 15;
          break;
      }
    }

    if ($filebrowser_flash != $filebrowser) {
      switch ($filebrowser_flash) {
        case 'ckfinder':
          if (user_access('allow CKFinder file uploads')) {
            $settings[$textarea_id]['filebrowserFlashBrowseUrl'] = $module_full_path .'/ckfinder/ckfinder.html?Type=Images';
            $settings[$textarea_id]['filebrowserFlashUploadUrl'] = $module_full_path .'/ckfinder/core/connector/php/connector.php?command=QuickUpload&type=Images';
          }
          break;
        case 'imce':
          $settings[$textarea_id]['filebrowserFlashBrowseUrl'] = $host ."index.php?q=imce&app=ckeditor|sendto@ckeditor_fileUrl|";
          break;
        case 'webfm':
          if (user_access('access webfm')) {
            $settings[$textarea_id]['filebrowserFlashBrowseUrl'] = $host ."index.php?q=webfm_popup";
          }
          break;
        case 'ib':
          if (user_access('browse own images')) {
            $settings[$textarea_id]['filebrowserFlashBrowseUrl'] = $host ."index.php?q=imagebrowser/view/browser&app=ckeditor";
            $settings[$textarea_id]['filebrowserFlashWindowWidth'] = 680;
            $settings[$textarea_id]['filebrowserFlashWindowHeight'] = 439;
          }
          break;
        case 'tinybrowser':
          $settings[$textarea_id]['filebrowserFlashBrowseUrl'] = $host . drupal_get_path('module','tinybrowser') . "/tinybrowser/tinybrowser.php?type=media";
          $settings[$textarea_id]['filebrowserFlashWindowWidth'] = (int)$win_size[0] + 15;
          $settings[$textarea_id]['filebrowserFlashWindowHeight'] = (int)$win_size[1] + 15;
          break;
      }
    }

    if (!empty($conf['js_conf'])) {
      $lines = preg_split("/[\n\r]+/", $conf['js_conf']);
      foreach ($lines as $l) {
        //parsing lines with custom configuration
        preg_match_all('#(config\.)?(\w+)[ ]*=(.+)[;]?#is', $l, $matches);
        if (!empty($matches[0])) {
          $value=trim($matches[3][0], " ;'\"\n\r\t\0\x0B");
          if ( strcasecmp($value, 'true') == 0 ) {
            $value=TRUE;
          }
          if ( strcasecmp($value, 'false') == 0 ) {
            $value=FALSE;
          }
          $settings[$textarea_id][$matches[2][0]]=$value;
        }
      }
    }

    $settings[$textarea_id]['stylesCombo_stylesSet'] = "drupal:" . $module_full_path . '/ckeditor.styles.js';
    if (!empty($conf['css_style'])) {
      if ($conf['css_style'] == 'theme' && file_exists($themepath . 'ckeditor.styles.js')) {
        $settings[$textarea_id]['stylesCombo_stylesSet'] = "drupal:" . $host . $themepath . 'ckeditor.styles.js';
      }
      elseif (!empty($conf['css_style']) && $conf['css_style'] == 'self') {
        $conf['styles_path'] = str_replace("%h%t", "%t", $conf['styles_path']);
        $settings[$textarea_id]['stylesCombo_stylesSet'] = "drupal:" . str_replace(array('%h', '%t', '%m'), array($host, $host . $themepath, $module_drupal_path), $conf['styles_path']);
      }
    }
    // add custom stylesheet if configured
    // lets hope it exists but we'll leave that to the site admin
    $query_string = '?'. substr(variable_get('css_js_query_string', '0'), 0, 1);
    $css_files = array();
    switch ($conf['css_mode']) {
      case 'theme':
        global $language, $theme_info, $base_theme_info;

        if (!empty($theme_info->stylesheets)) {
          $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 . $query_string;
                      // Grab rtl stylesheets ( will get rtl css files when thay are named with suffix "-rtl.css" (ex: fusion baased themes) )
                      if (defined('LANGUAGE_RTL') && $language->direction == LANGUAGE_RTL && substr($path,0,-8) != "-rtl.css") {
                        $rtl_path = substr($path,0,-4)."-rtl.css";
                        if (file_exists($rtl_path)) {
                          $css_files[$name."-rtl"] = $host . $rtl_path . $query_string;
                        }
                      }
                    }
                  }
                }
              }
            }
          }
          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 . $query_string;
                    // Grab rtl stylesheets ( will get rtl css files when thay are named with suffix "-rtl.css" (ex: fusion baased themes) )
                    if (defined('LANGUAGE_RTL') && $language->direction == LANGUAGE_RTL && substr($path,0,-8) != "-rtl.css") {
                      $rtl_path = substr($path,0,-4)."-rtl.css";
                      if (file_exists($rtl_path)) {
                        $css_files[$name."-rtl"] = $host . $rtl_path . $query_string;
                      }
                    }
                  }
                  elseif (!empty($css_files[$name])) {
                    unset($css_files[$name]);
                  }
                }
              }
            }
          }
          // Grab stylesheets local.css and local-rtl.css if they exist (fusion based themes)
          if (file_exists($themepath . 'css/local.css')) {
            $css_files[] = $host . $themepath . 'css/local.css' . $query_string;
          }
          if (defined('LANGUAGE_RTL') && $language->direction == LANGUAGE_RTL && file_exists($themepath . 'css/local-rtl.css')) {
            $css_files[] = $host . $themepath . 'css/local-rtl.css' . $query_string;
          }

          // 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])) {
              $css_files[] = $host . $color_paths[1] . $query_string;
            }
          }
          elseif (!empty($color_paths[0])) {
            $css_files[] = $host . $color_paths[0] . $query_string;
          }
        }
        else {
          if (file_exists($themepath .'style.css')) {
            $css_files[] = $host . $themepath .'style.css' . $query_string;
          }
        }
        $css_files[] = $module_full_path ."/ckeditor.css" . $query_string;
        break;

      case 'self':
        if (file_exists($module_drupal_path .'/ckeditor.css')) {
          $css_files[] = $module_full_path .'/ckeditor.css' . $query_string;
        }
        foreach (explode(',', $conf['css_path']) as $css_path) {
          $css_path = trim(str_replace("%h%t", "%t", $css_path));
          $css_files[] = str_replace(array('%h', '%t'), array($host, $host . $themepath), $css_path) . $query_string;
        }
        break;

      case 'none':
        if (file_exists($module_drupal_path .'/ckeditor.css')) {
          $css_files[] = $module_full_path .'/ckeditor.css' . $query_string;
        }
        $css_files[] = $editor_path .'/contents.css' . $query_string;
        break;
    }
    if ($conf['ckeditor_load_method'] == 'ckeditor_source.js') {
      foreach ($css_files as $k => $v) {
        $css_files[$k] = $v . '&t=' . time();
      }
    }
    $settings[$textarea_id]['contentsCss'] = array_values($css_files);

    if ($ckeditor_on) {
      $autostart[$textarea_id] = TRUE;
    }

    if (!empty($conf['uicolor']) && $conf['uicolor']=="custom" && !empty($conf['uicolor_user'])) {
      $settings[$textarea_id]['uiColor'] = $conf['uicolor_user'];
    }
    if (!empty($conf['uicolor']) && strpos($conf['uicolor'], "color_") === 0) {
      if (function_exists('color_get_palette')) {
        $palette = @color_get_palette($theme, FALSE); //[#652274]
        $color = str_replace("color_", "", $conf['uicolor']);
        if (!empty($palette[$color])) {
          $settings[$textarea_id]['uiColor'] = $palette[$color];
        }
      }
    }

    drupal_add_js(array('ckeditor' => array( 'theme' => $theme )), 'setting');
    if (!empty($settings)) {
      drupal_add_js(array('ckeditor' => array('settings' => $settings)), 'setting');
    }
    if (!empty($autostart)) {
      drupal_add_js(array('ckeditor' => array('autostart' => $autostart)), 'setting');
    }

    if ($conf['popup'] == 't') {
      $suffix .= ' <span style="display:none" class="ckeditor_popuplink ckeditor_links">(<a href="#" onclick="return ckeditorOpenPopup(\''. $textarea_id .'\', \''. $element['#id'] .'\', \''. $conf['width'] .'\');">'. t('Open rich text editor') ."</a>)</span>";
    }
  }

  // display the field id for administrators
  if (user_access('administer ckeditor') && (!isset($global_conf['show_fieldnamehint']) || $global_conf['show_fieldnamehint'] == 't')) {
    module_load_include('inc', 'ckeditor', 'includes/ckeditor.admin');
    $suffix .= '<div class="textarea-identifier description">'. t('CKEditor: the ID for <a href="!excluding">excluding or including</a> this element is %fieldname.', array('!excluding' => url('admin/settings/ckeditor'), '%fieldname' => ckeditor_rule_to_string(ckeditor_rule_create(ckeditor_get_nodetype($_GET['q']), $_GET['q'], $element['#id'])))) .'</div>';
  }

  // Remember extra information and reuse it during "Preview"
  $processed_ids[$element['#id']]['suffix'] = $suffix;
  $processed_ids[$element['#id']]['class'] = $class;

  if (empty($element['#suffix'])) {
    $element['#suffix'] = $suffix;
  }
  else {
    $element['#suffix'] .= $suffix;
  }

  if (empty($element['#attributes']['class'])) {
    $element['#attributes']['class'] = $class;
  }
  else {
    $element['#attributes']['class'] .= ' '. $class;
  }
  //hack with patch jquery-ui dialog

  return $element;
}

/**
 * Read CKEditor path from 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');
    $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 = base_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" => 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 '/'
        }
        $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'], "%b")) {
            $gs['ckeditor_local_path'] = strtr($gs['ckeditor_path'], array("%b" => "."));
          }
        }
      }

      //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;
  }
}

function ckeditor_get_nodetype($get_q) {
  static $nodetype;

  if (!isset($nodetype)) {
    $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" && !empty($get_q[1]) && $get_q[1] == "add" && !empty($get_q[2])) {
        $nodetype = $get_q[2];
      }
    }
  }

  return $nodetype;
}

Other Drupal examples (source code examples)

Here is a short list of links related to this Drupal ckeditor.module source code file:

new blog posts

"Drupal" is a registered trademark of Dries Buytaert.

my drupal tutorials and examples  

Copyright 1998-2016 Alvin Alexander, alvinalexander.com
All Rights Reserved.

Beginning in 2016, a portion of the proceeds from pages under the '/drupal-code-examples/' URI will be donated to charity.