[ Index ]

PHP Cross Reference of Drupal 6 (yi-drupal)

title

Body

[close]

/sites/all/modules/fckeditor/ -> fckeditor.module (source)

   1  <?php
   2  // $Id: fckeditor.module,v 1.20.2.34.2.91 2010/03/10 07:43:32 jorrit Exp $
   3  /**
   4   * FCKeditor - The text editor for Internet - http://www.fckeditor.net
   5   * Copyright (C) 2003-2008 Frederico Caldeira Knabben
   6   *
   7   * == BEGIN LICENSE ==
   8   *
   9   * Licensed under the terms of any of the following licenses at your
  10   * choice:
  11   *
  12   *  - GNU General Public License Version 2 or later (the "GPL")
  13   *    http://www.gnu.org/licenses/gpl.html
  14   *
  15   *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
  16   *    http://www.gnu.org/licenses/lgpl.html
  17   *
  18   *  - Mozilla Public License Version 1.1 or later (the "MPL")
  19   *    http://www.mozilla.org/MPL/MPL-1.1.html
  20   *
  21   * == END LICENSE ==
  22   *
  23   * @file
  24   * FCKeditor Module for Drupal 6.x
  25   *
  26   * This module allows Drupal to replace textarea fields with FCKeditor.
  27   *
  28   * This HTML text editor brings to the web many of the powerful functionalities
  29   * of known desktop editors like Word. It's really  lightweight and doesn't
  30   * require any kind of installation on the client computer.
  31   */
  32  
  33  /**
  34   * The name of simplified toolbar which should be forced
  35   * Be sure that this toolbar is defined in fckeditor.config.js or fckconfig.js
  36   */
  37  define('FCKEDITOR_FORCE_SIMPLE_TOOLBAR_NAME', 'DrupalBasic') ;
  38  
  39  global $_fckeditor_configuration;
  40  global $_fckeditor_js_ids;
  41  
  42  $_fckeditor_configuration = array();
  43  $_fckeditor_js_ids = array();
  44  
  45  /**
  46   * Implementation of hook_help().
  47   *
  48   * This function delegates execution to fckeditor_help_delegate() in fckeditor.help.inc to
  49   * lower the amount of code in fckeditor.module
  50   */
  51  function fckeditor_help($path, $arg) {
  52    module_load_include('help.inc', 'fckeditor');
  53    return module_invoke('fckeditor', 'help_delegate', $path, $arg);
  54  }
  55  
  56  /**
  57   * Implementation of hook_user().
  58   *
  59   * This function delegates execution to fckeditor_user_delegate() in fckeditor.user.inc to
  60   * lower the amount of code in fckeditor.module
  61   */
  62  function fckeditor_user($type, $edit, &$user, $category = NULL) {
  63    if (($type == 'form' && $category == 'account' && user_access('access fckeditor')) || $type == 'validate') {
  64      module_load_include('user.inc', 'fckeditor');
  65      return fckeditor_user_delegate($type, $edit, $user, $category);
  66    }
  67    return NULL;
  68  }
  69  
  70  /*
  71   *  Run if there is old menu information in database
  72   */
  73  function fckeditor_admin($arg = NULL) {
  74    drupal_set_message(t('The FCKeditor module is not installed correctly. You should run the !updatephplink immediately.', array('!updatephplink' => l(t('database update script'), 'update.php'))), 'error');
  75    return FALSE;
  76  }
  77  
  78  /**
  79   * Implementation of hook_perm().
  80   * Administer -> User management -> Permissions
  81   */
  82  function fckeditor_perm() {
  83    return array('administer fckeditor', 'access fckeditor', 'allow fckeditor file uploads');
  84  }
  85  
  86  /**
  87   * Implementation of hook_elements().
  88   * Replace textarea with FCKeditor using callback function (fckeditor_process_textarea)
  89   */
  90  function fckeditor_elements() {
  91    $type = array();
  92    $type['textfield'] = array(
  93      '#process' => array(
  94        'fckeditor_process_input'
  95      ),
  96    );
  97    if (user_access('access fckeditor')) {
  98      // only roles with permission get the fckeditor
  99      if (fckeditor_is_compatible_client()) {
 100        // it would be useless to dig deeper if we're not able or allowed to
 101        $type['textarea'] = array('#process' => array('fckeditor_process_textarea'));
 102        $type['form'] = array('#after_build' => array('fckeditor_process_form'));
 103      }
 104    }
 105    return $type;
 106  }
 107  
 108  /**
 109   * AJAX callback - XSS filter
 110   */
 111  function fckeditor_filter_xss() {
 112    $GLOBALS['devel_shutdown'] = FALSE;
 113  
 114    if (!isset($_POST['text']) || !is_string($_POST['text']) || !is_array($_POST['filters'])) {
 115      exit;
 116    }
 117  
 118    $text = $_POST['text'];
 119    $text = strtr($text, array('<!--' => '__COMMENT__START__', '-->' => '__COMMENT__END__'));
 120  
 121    foreach ($_POST['filters'] as $module_delta) {
 122      $module = strtok($module_delta, "/");
 123      $delta = strtok("/");
 124      $format = strtok("/");
 125  
 126      if (!module_hook($module, 'filter')) {
 127        continue;
 128      }
 129  
 130      //built-in filter module, a special case where we would like to strip XSS and nothing more
 131      if ($module == 'filter' && $delta == 0) {
 132        preg_match_all("|</?([a-z][a-z0-9]*)(?:\b[^>]*)>|i", $text, $matches);
 133        if ($matches[1]) {
 134          $tags = array_unique($matches[1]);
 135          $text = filter_xss($text, $tags);
 136        }
 137      }
 138      else {
 139        $text = module_invoke($module, 'filter', 'process', $delta, $format, $text);
 140      }
 141    }
 142  
 143    $text = strtr($text, array('__COMMENT__START__' => '<!--', '__COMMENT__END__' => '-->'));
 144  
 145    echo $text;
 146    exit;
 147  }
 148  
 149  function fckeditor_process_form(&$form) {
 150    global $_fckeditor_configuration, $_fckeditor_js_ids;
 151    static $processed_textareas = array();
 152    static $found_textareas = array();
 153  
 154    //Skip if:
 155    // - we're not editing an element
 156    // - fckeditor is not enabled (configuration is empty)
 157    if (arg(1) == "add" || arg(1) == "reply" || !count($_fckeditor_configuration)) {
 158      return $form;
 159    }
 160  
 161    $fckeditor_filters = array();
 162  
 163    // Iterate over element children; resetting array keys to access last index.
 164    if (($children = array_values(element_children($form)))) {
 165      foreach ($children as $index => $item) {
 166        $element = &$form[$item];
 167  
 168        if (isset($element['#id']) && in_array($element['#id'], array_keys($_fckeditor_js_ids))) {
 169          $found_textareas[$element['#id']] = &$element;
 170        }
 171  
 172        // filter_form() always uses the key 'format'. We need a type-agnostic
 173        // match to prevent false positives. Also, there must have been at least
 174        // one element on this level.
 175        if ($item === 'format' && $index > 0) {
 176  
 177          // Make sure we either match a input format selector or input format
 178          // guidelines (displayed if user has access to one input format only).
 179          if ((isset($element['#type']) && $element['#type'] == 'fieldset') || isset($element['format']['guidelines'])) {
 180            // The element before this element is the target form field.
 181            $field = &$form[$children[$index - 1]];
 182            $textarea_id = $field['#id'];
 183            $js_id = $_fckeditor_js_ids[$textarea_id];
 184  
 185            array_push($processed_textareas, $js_id);
 186  
 187            //search for checkxss1/2 class
 188            if (empty($field['#attributes']['class']) || strpos($field['#attributes']['class'], "checkxss") === FALSE) {
 189              continue;
 190            }
 191  
 192            // Determine the available input formats. The last child element is a
 193            // link to "More information about formatting options". When only one
 194            // input format is displayed, we also have to remove formatting
 195            // guidelines, stored in the child 'format'.
 196            $formats = element_children($element);
 197  
 198            foreach ($formats as $format_id) {
 199              $format = !empty($element[$format_id]['#default_value']) ? $element[$format_id]['#default_value'] : $element[$format_id]['#value'];
 200              break;
 201            }
 202  
 203            $enabled = filter_list_format($format);
 204            $fckeditor_filters = array();
 205  
 206            //loop through all enabled filters
 207            foreach ($enabled as $id => $filter) {
 208              //but use only that one selected in FCKeditor profile
 209              if (in_array($id, array_keys($_fckeditor_configuration[$textarea_id]['filters'])) && $_fckeditor_configuration[$textarea_id]['filters'][$id]) {
 210                if (!isset($fckeditor_filters[$js_id])) {
 211                  $fckeditor_filters[$js_id] = array();
 212                }
 213                $fckeditor_filters[$js_id][] = $id ."/". $format;
 214              }
 215            }
 216  
 217            //No filters assigned, remove xss class
 218            if (empty($fckeditor_filters[$js_id])) {
 219              $field['#attributes']['class'] = preg_replace("/checkxss(1|2)/", "", $field['#attributes']['class']);
 220            }
 221            else {
 222              $field['#attributes']['class'] = strtr($field['#attributes']['class'], array("checkxss1" => "filterxss1", "checkxss2" => "filterxss2"));
 223            }
 224  
 225            array_pop($formats);
 226            unset($formats['format']);
 227          }
 228          // If this element is 'format', do not recurse further.
 229          continue;
 230        }
 231        // Recurse into children.
 232        fckeditor_process_form($element);
 233      }
 234    }
 235  
 236    //We're in a form
 237    if (isset($form['#action'])) {
 238      //some textareas associated with FCKeditor has not been processed
 239      if (count($processed_textareas) < count($_fckeditor_js_ids)) {
 240        //loop through all found textfields
 241        foreach (array_keys($found_textareas) as $id) {
 242          $element = &$found_textareas[$id];
 243          //if not processed yet (checkxss class is before final processing)
 244          if (strpos($element['#attributes']['class'], "checkxss") !== FALSE && !in_array($_fckeditor_js_ids[$element['#id']], $processed_textareas) && !empty($_fckeditor_configuration[$id]['filters']) && array_sum($_fckeditor_configuration[$id]['filters'])) {
 245            //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
 246            $js_id = $_fckeditor_js_ids[$element['#id']];
 247            $fckeditor_filters[$js_id][] = "filter/0/1";
 248            $element['#attributes']['class'] = strtr($element['#attributes']['class'], array("checkxss1" => "filterxss1", "checkxss2" => "filterxss2"));
 249          }
 250        }
 251      }
 252    }
 253  
 254    if (!empty($fckeditor_filters)) {
 255      drupal_add_js(array('fckeditor_filters' => $fckeditor_filters), 'setting');
 256    }
 257  
 258    return $form;
 259  }
 260  
 261  /**
 262   * Allow more than 255 chars in Allowed HTML tags textfield
 263   */
 264  function fckeditor_process_input($element) {
 265    if ($element['#id']=='edit-allowed-html-1') {
 266      $element['#maxlength'] = max($element['#maxlength'], 1024);
 267    }
 268    return $element;
 269  }
 270  
 271  /**
 272   * Implementation of hook_menu().
 273   */
 274  function fckeditor_menu() {
 275    $items = array();
 276  
 277    $items['fckeditor/xss'] = array(
 278      'title' => 'XSS Filter',
 279      'description' => 'XSS Filter.',
 280      'page callback' => 'fckeditor_filter_xss',
 281      'access arguments' => array('access fckeditor'),
 282      'type' => MENU_CALLBACK,
 283    );
 284  
 285    $items['admin/settings/fckeditor'] = array(
 286      'title' => 'FCKeditor',
 287      'description' => 'Configure the rich text editor.',
 288      'page callback' => 'fckeditor_admin_main',
 289      'file' => 'fckeditor.admin.inc',
 290      'access arguments' => array('administer fckeditor'),
 291      'type' => MENU_NORMAL_ITEM,
 292    );
 293  
 294    $items['admin/settings/fckeditor/add'] = array(
 295      'title' => 'Add new FCKeditor profile',
 296      'description' => 'Configure the rich text editor.',
 297      'page callback' => 'drupal_get_form',
 298      'page arguments' => array('fckeditor_admin_profile_form'),
 299      'file' => 'fckeditor.admin.inc',
 300      'access arguments' => array('administer fckeditor'),
 301      'type' => MENU_CALLBACK,
 302    );
 303  
 304    $items['admin/settings/fckeditor/clone/%fckeditor_profile'] = array(
 305      'title' => 'Clone FCKeditor profile',
 306      'description' => 'Configure the rich text editor.',
 307      'page callback' => 'drupal_get_form',
 308      'page arguments' => array('fckeditor_admin_profile_clone_form', 4),
 309      'file' => 'fckeditor.admin.inc',
 310      'access arguments' => array('administer fckeditor'),
 311      'type' => MENU_CALLBACK,
 312    );
 313  
 314    $items['admin/settings/fckeditor/edit/%fckeditor_profile'] = array(
 315      'title' => 'Edit FCKeditor profile',
 316      'description' => 'Configure the rich text editor.',
 317      'page callback' => 'drupal_get_form',
 318      'page arguments' => array('fckeditor_admin_profile_form', 4),
 319      'file' => 'fckeditor.admin.inc',
 320      'access arguments' => array('administer fckeditor'),
 321      'type' => MENU_CALLBACK,
 322    );
 323  
 324    $items['admin/settings/fckeditor/delete/%fckeditor_profile'] = array(
 325      'title' => 'Delete FCKeditor profile',
 326      'description' => 'Configure the rich text editor.',
 327      'page callback' => 'drupal_get_form',
 328      'page arguments' => array('fckeditor_admin_profile_delete_form', 4),
 329      'file' => 'fckeditor.admin.inc',
 330      'access arguments' => array('administer fckeditor'),
 331      'type' => MENU_CALLBACK,
 332    );
 333  
 334    $items['admin/settings/fckeditor/addg'] = array(
 335      'title' => 'Add FCKeditor Global profile',
 336      'description' => 'Configure the rich text editor.',
 337      'page callback' => 'drupal_get_form',
 338      'page arguments' => array('fckeditor_admin_global_profile_form', 'add'),
 339      'file' => 'fckeditor.admin.inc',
 340      'access arguments' => array('administer fckeditor'),
 341      'type' => MENU_CALLBACK,
 342    );
 343  
 344    $items['admin/settings/fckeditor/editg'] = array(
 345      'title' => 'Edit FCKeditor Global profile',
 346      'description' => 'Configure the rich text editor.',
 347      'page callback' => 'drupal_get_form',
 348      'page arguments' => array('fckeditor_admin_global_profile_form', 'edit'),
 349      'file' => 'fckeditor.admin.inc',
 350      'access arguments' => array('administer fckeditor'),
 351      'type' => MENU_CALLBACK,
 352    );
 353  
 354    // img_assist integration
 355    $items['img_assist/load/fckeditor'] = array(
 356      'title' => 'Image assist',
 357      'page callback' => 'fckeditor_wrapper_img_assist_loader',
 358      'file' => 'fckeditor.user.inc',
 359      'access arguments' => array('access img_assist'),
 360      'type' => MENU_CALLBACK,
 361    );
 362  
 363    return $items;
 364  }
 365  
 366  /**
 367   * Implementation of hook_init().
 368   */
 369  function fckeditor_init() {
 370    drupal_add_css(drupal_get_path('module', 'fckeditor') .'/fckeditor.css');
 371  }
 372  
 373  /**
 374   * Implementation of hook_file_download().
 375   * Support for private downloads.
 376   * FCKeditor does not implement any kind of potection on private files.
 377   */
 378  function fckeditor_file_download($file) {
 379    if (($path = file_create_path($file))) {
 380      $result = db_query("SELECT f.* FROM {files} f WHERE filepath = '%s'", $path);
 381      if (db_fetch_object($result)) {
 382          return NULL;
 383      }
 384  
 385      //No info in DB? Probably a file uploaded with FCKeditor
 386      $global_profile = fckeditor_profile_load("FCKeditor Global Profile");
 387  
 388      //Assume that files inside of fckeditor directory belong to the FCKeditor. If private directory is set, let the decision about protection to the user.
 389      $private_dir = isset($global_profile->settings['private_dir']) ? trim($global_profile->settings['private_dir'], '\/') : '';
 390      $private_dir = preg_quote($private_dir, '#');
 391      $private_dir = strtr($private_dir, array('%u' => '(\d+)', '%n' => '([\x80-\xF7 \w@.-]+)')); // regex for %n taken from user_validate_name() in user.module
 392      $private_dir = trim($private_dir, '\/');
 393  
 394      $regex = '#^'. preg_quote(file_directory_path() .'/', '#') . $private_dir .'#';
 395  
 396      //If path to the file points to the FCKeditor private directory, allow downloading
 397      if (preg_match($regex, $path)) {
 398        $ctype = ($info = @getimagesize($path)) ? $info['mime'] : (function_exists('mime_content_type') ? mime_content_type($path) : 'application/x-download');
 399        return array('Content-Type: '. $ctype);
 400      }
 401    }
 402  }
 403  
 404  /**
 405   * Load all profiles. Just load one profile if $name is passed in.
 406   */
 407  function fckeditor_profile_load($name = '', $clear = FALSE) {
 408    static $profiles = array();
 409  
 410    if (empty($profiles) || $clear === TRUE) {
 411      $result = db_query("SELECT * FROM {fckeditor_settings}");
 412      while (($data = db_fetch_object($result))) {
 413        $data->settings = unserialize($data->settings);
 414        $data->rids = array();
 415  
 416        $profiles[$data->name] = $data;
 417      }
 418  
 419      $roles = user_roles();
 420      $result = db_query("SELECT name, rid FROM {fckeditor_role}");
 421      while (($data = db_fetch_object($result))) {
 422        $profiles[$data->name]->rids[$data->rid] = $roles[$data->rid];
 423      }
 424    }
 425  
 426    return ($name ? (isset($profiles[urldecode($name)]) ? $profiles[urldecode($name)] : FALSE) : $profiles);
 427  }
 428  
 429  /**
 430   * @param int $excl_mode 1/include, exclude otherwise
 431   * @param string $excl_regex paths (drupal paths with ids attached)
 432   * @param string $element_id current ID
 433   * @param string $get_q current path
 434   *
 435   * @return boolean
 436   *    returns true if FCKeditor is enabled
 437   */
 438  function fckeditor_is_enabled($excl_mode, $excl_regex, $element_id, $get_q) {
 439    $front = variable_get('site_frontpage', 'node');
 440    $excl_regex = str_replace('<front>', $front, $excl_regex);
 441    $nodetype = fckeditor_get_nodetype($get_q);
 442    $element_id = str_replace('.', '\.', $element_id);
 443  
 444    $match = !empty($excl_regex) && preg_match($excl_regex, $nodetype .'@'. $get_q .'.'. $element_id);
 445  
 446    return ($excl_mode == '0' xor $match);
 447  }
 448  
 449  /**
 450   * This function create the HTML objects required for the FCKeditor
 451   *
 452   * @param $element
 453   *   A fully populated form elment to add the editor to
 454   * @return
 455   *   The same $element with extra FCKeditor markup and initialization
 456   */
 457  function fckeditor_process_textarea($element) {
 458    static $is_running = FALSE;
 459    static $num = 1;
 460    global $user, $language, $_fckeditor_configuration, $_fckeditor_js_ids;
 461    $enabled = TRUE;
 462  
 463    //hack for module developers that want to disable FCKeditor on their textareas
 464    if (key_exists('#wysiwyg', $element) && !$element['#wysiwyg']) {
 465      return $element;
 466    }
 467  
 468    if (isset($element['#access']) && !$element['#access']) {
 469      return $element;
 470    }
 471  
 472    //skip this one, surely nobody wants WYSIWYG here
 473    switch ($element['#id']) {
 474      case 'edit-log':
 475        return $element;
 476        break;
 477    }
 478  
 479    if (isset($element['#attributes']['disabled']) && $element['#attributes']['disabled'] == 'disabled') {
 480      return $element;
 481    }
 482  
 483  
 484    $global_profile = fckeditor_profile_load('FCKeditor Global Profile');
 485    if ($global_profile) {
 486      $global_conf = $global_profile->settings;
 487      if ($global_conf) {
 488        $enabled = fckeditor_is_enabled(empty($global_conf['excl_mode']) ? '0' : $global_conf['excl_mode'], empty($global_conf['excl_regex']) ? '' : $global_conf['excl_regex'], $element['#id'], $_GET['q']);
 489      }
 490    }
 491  
 492    if ($enabled) {
 493      $profile = fckeditor_user_get_profile($user, $element['#id']);
 494      if ($profile) {
 495        $conf = array();
 496        $conf = $profile->settings;
 497  
 498        if ($conf['allow_user_conf']=='t') {
 499          foreach (array('default', 'show_toggle', 'popup', 'skin', 'toolbar', 'expand', 'width', 'lang', 'auto_lang') as $setting) {
 500            $conf[$setting] = fckeditor_user_get_setting($user, $profile, $setting);
 501          }
 502        }
 503        if ($conf['popup'] == 't' && $conf['show_toggle'] == 't') {
 504          $conf['show_toggle'] = 'f';
 505        }
 506      }
 507      else {
 508        $enabled = FALSE;
 509      }
 510    }
 511  
 512    //old profile info, assume Filtered HTML is enabled
 513    if (!isset($conf['ss'])) {
 514      $conf['ss'] = 2;
 515      $conf['filters']['filter/0'] = 1;
 516    }
 517    if (!isset($conf['filters'])) {
 518      $conf['filters'] = array();
 519    }
 520  
 521    $themepath = fckeditor_path_to_theme() .'/';
 522    $host = base_path();
 523  
 524    if (!isset($element['#suffix'])) {
 525      $element['#suffix'] = '';
 526    }
 527  
 528    // only replace textarea when it has enough rows and it is enabled
 529    if ($enabled && (($element['#rows'] > $conf['min_rows']) || ($conf['min_rows'] <= 1 && empty($element['#rows'])))) {
 530      $textarea_id = $element['#id'];
 531  
 532      if (!isset($element['#attributes'])) {
 533        $element['#attributes'] = array();
 534      }
 535      if (!isset($element['#attributes']['class'])) {
 536        $element['#attributes']['class'] = 'fckeditor';
 537      }
 538      else {
 539        $element['#attributes']['class'] .= ' fckeditor';
 540      }
 541  
 542      $js_id = 'oFCK_'. $num++;
 543      $_fckeditor_js_ids[$element['#id']] = $js_id;
 544      $fckeditor_on = ($conf['default']=='t') ? 1 : 0 ;
 545  
 546      $xss_check = 0;
 547      //it's not a problem when adding new content/comment
 548      if (arg(1) != "add" && arg(1) != "reply") {
 549        $_fckeditor_configuration[$element['#id']] = $conf;
 550  
 551        //let FCKeditor know when perform XSS checks auto/manual
 552        if ($conf['ss'] == 1) {
 553          $xss_class = 'checkxss1';
 554        }
 555        else {
 556          $xss_class = 'checkxss2';
 557        }
 558  
 559        $element['#attributes']['class'] .= ' '. $xss_class;
 560        $xss_check = 1;
 561      }
 562  
 563      //settings are saved as strings, not booleans
 564      if ($conf['show_toggle'] == 't') {
 565        $content = '';
 566        if (isset($element['#post']['teaser_js'])) {
 567          $content .= $element['#post']['teaser_js'] .'<!--break-->';
 568        }
 569        $content .= $element['#value'];
 570        $wysiwyg_link = '';
 571        $wysiwyg_link .= "<a href=\"javascript:Toggle('{$textarea_id}','". str_replace("'", "\\'", t('Switch to plain text editor')) ."','". str_replace("'", "\\'", t('Switch to rich text editor')) ."',". $xss_check .");\" id=\"switch_{$textarea_id}\" ". ($fckeditor_on?"style=\"display:none\"":"") .">";
 572        $wysiwyg_link .= $fckeditor_on ? t('Switch to plain text editor') : t('Switch to rich text editor');
 573        $wysiwyg_link .= '</a>';
 574  
 575        // Make sure to append to #suffix so it isn't completely overwritten
 576        $element['#suffix'] .= $wysiwyg_link;
 577      }
 578  
 579      //convert contents to HTML if necessary
 580      if ($conf['autofixplaintext'] == 't') {
 581        module_load_include('lib.inc', 'fckeditor');
 582        if (fckeditor_is_plaintext($element['#value'])) {
 583          $element['#value'] = _filter_autop($element['#value']);
 584        }
 585      }
 586  
 587      // setting some variables
 588      $module_drupal_path = drupal_get_path('module', 'fckeditor');
 589      $module_full_path   = $host . $module_drupal_path;
 590      $editor_path        = fckeditor_path(FALSE);
 591      $editor_local_path  = fckeditor_path(TRUE);
 592      // get the default drupal files path
 593      $files_path         = $host . file_directory_path();
 594      // module_drupal_path:
 595      //  'modules/fckeditor' (length=17)
 596      // module_full_path:
 597      //  '/drupal5/modules/fckeditor' (length=26)
 598      // files_path:
 599      //  '/drupal5/files' (length=14)
 600      // configured in settings
 601      $width = $conf['width'];
 602  
 603      // sensible default for small toolbars
 604      $height = intval($element['#rows']) * 14 + 140;
 605  
 606      if (!$is_running) {
 607        drupal_add_js($module_drupal_path .'/fckeditor.utils.js');
 608        /* In D6 drupal_add_js() can't add external JS, in D7 use drupal_add_js(...,'external') */
 609        drupal_set_html_head('<script type="text/javascript" src="'. $editor_path .'/fckeditor.js?I"></script>');
 610        $is_running = TRUE;
 611      }
 612  
 613      $toolbar = $conf['toolbar'];
 614      //$height += 100; // for larger toolbars
 615  
 616      $force_simple_toolbar = fckeditor_is_enabled('1', empty($conf['simple_incl_regex']) ? '' : $conf['simple_incl_regex'], $element['#id'], $_GET['q']);
 617      if (!$force_simple_toolbar) {
 618        $force_simple_toolbar = fckeditor_is_enabled('1', empty($global_conf['simple_incl_regex']) ? '' : $global_conf['simple_incl_regex'], $element['#id'], $_GET['q']);
 619      }
 620      if ($force_simple_toolbar) {
 621        $toolbar = FCKEDITOR_FORCE_SIMPLE_TOOLBAR_NAME;
 622      }
 623  
 624      if (!empty($conf['theme_config_js']) && $conf['theme_config_js'] == 't' && file_exists($themepath .'fckeditor.config.js')) {
 625        $fckeditor_config_path = $host . $themepath .'fckeditor.config.js?'. @filemtime($themepath .'fckeditor.config.js');
 626      }
 627      else {
 628        $fckeditor_config_path = $module_full_path ."/fckeditor.config.js?". @filemtime($module_drupal_path ."/fckeditor.config.js");
 629      }
 630  
 631      $js = $js_id ." = new FCKeditor( '". $textarea_id ."' );
 632  ". $js_id .".defaultState = ". (($fckeditor_on && $conf['popup'] == 'f') ? 1 : 0) .";
 633  ". $js_id .".BasePath = '". $editor_path ."/';
 634  ". $js_id .".DrupalId = '". $js_id ."';
 635  ". $js_id .".Config['PluginsPath'] = '". $module_full_path ."/plugins/';
 636  ". $js_id .".Config['CustomConfigurationsPath'] = \"". $fckeditor_config_path ."\";
 637  ". $js_id .".Config['TextareaID'] = \"". $element['#id'] ."\";
 638  ". $js_id .".Config['BodyId'] = \"". $element['#id'] ."\";";
 639  
 640      //if ($conf['appearance_conf'] == 'f') {
 641      $js .= "\n". $js_id .".ToolbarSet = \"". $toolbar ."\";
 642  ". $js_id .".Config['SkinPath'] = ". $js_id .".BasePath + \"editor/skins/". $conf['skin'] ."/\";
 643  ". $js_id .".Config['DefaultLanguage'] = \"". $conf['lang'] ."\";
 644  ". $js_id .".Config['AutoDetectLanguage'] = ". ($conf['auto_lang']=="t"?"true":"false") .";
 645  ". $js_id .".Height = \"". $height ."\";
 646  ". $js_id .".Config['ToolbarStartExpanded'] = ". ($conf['expand']=="t"?"true":"false") .";
 647  ". $js_id .".Width = \"". $width ."\";\n";
 648      //}
 649      //if ($conf['output_conf'] == 'f') {
 650      $js .= "\n". $js_id .".Config['EnterMode'] = '". $conf['enter_mode'] ."';
 651  ". $js_id .".Config['ShiftEnterMode'] = \"". $conf['shift_enter_mode'] ."\";
 652  ". $js_id .".Config['FontFormats'] = \"". str_replace(",", ";", $conf['font_format']) ."\";
 653  ". $js_id .".Config['FormatSource'] = ". ($conf['format_source']=="t"?"true":"false") .";
 654  ". $js_id .".Config['FormatOutput'] = ". ($conf['format_output']=="t"?"true":"false") .";\n";
 655      //}
 656  
 657      if (defined('LANGUAGE_RTL') && $language->direction == LANGUAGE_RTL) {
 658        $js .= $js_id .".Config['ContentLangDirection'] = 'rtl';\n";
 659      }
 660  
 661      // add code for filebrowser for users that have access
 662      if (user_access('allow fckeditor file uploads')==1) {
 663        $filebrowser = !empty($conf['filebrowser']) ? $conf['filebrowser'] : 'none';
 664        if ($filebrowser == 'imce' && !module_exists('imce')) {
 665          $filebrowser = 'none';
 666        }
 667        if ($filebrowser == 'ib' && !module_exists('imagebrowser')) {
 668          $filebrowser = 'none';
 669        }
 670        if ($filebrowser == 'webfm' && !module_exists('webfm_popup')) {
 671          $filebrowser = 'none';
 672        }
 673        $quickupload = (!empty($conf['quickupload']) && $conf['quickupload'] == 't');
 674  
 675        // load variables used by both quick upload and filebrowser
 676        // and assure that the $_SESSION variables are loaded
 677        if ($quickupload || $filebrowser == 'builtin') {
 678          if (file_exists($editor_local_path ."/editor/filemanager/connectors/php/connector.php")) {
 679            $connector_path = $editor_path ."/editor/filemanager/connectors/php/connector.php" ;
 680          }
 681          elseif (file_exists($editor_local_path ."/editor/filemanager/upload/php/connector.php")) {
 682            $connector_path = $editor_path ."/editor/filemanager/upload/php/connector.php";
 683          }
 684  
 685          if (file_exists($editor_local_path ."/editor/filemanager/connectors/php/upload.php")) {
 686            $upload_path = $editor_path ."/editor/filemanager/connectors/php/upload.php" ;
 687          }
 688          elseif (file_exists($editor_local_path ."/editor/filemanager/upload/php/upload.php")) {
 689            $upload_path = $editor_path ."/editor/filemanager/upload/php/upload.php";
 690          }
 691  
 692          if (!empty($profile->settings['UserFilesPath'])) $_SESSION['FCKeditor']['UserFilesPath'] = strtr($profile->settings['UserFilesPath'], array("%f" => file_directory_path(), "%u" => $user->uid, "%b" => $host, "%n" => $user->name));
 693          if (!empty($profile->settings['UserFilesAbsolutePath'])) $_SESSION['FCKeditor']['UserFilesAbsolutePath'] = strtr($profile->settings['UserFilesAbsolutePath'], array("%f" => file_directory_path(), "%u" => $user->uid, "%b" => base_path(), "%d" => $_SERVER['DOCUMENT_ROOT'], "%n" => $user->name));
 694          if (variable_get('file_downloads', '') == FILE_DOWNLOADS_PRIVATE) {
 695            $private_dir = isset($global_profile->settings['private_dir']) ? trim($global_profile->settings['private_dir'], '\/') : '';
 696            if (!empty($private_dir)) {
 697              $private_dir = strtr($private_dir, array('%u' => $user->uid, '%n' => $user->name));
 698              $_SESSION['FCKeditor']['UserFilesPath'] = url('system/files') .'/'. $private_dir .'/';
 699              $_SESSION['FCKeditor']['UserFilesAbsolutePath'] = realpath(file_directory_path()) . DIRECTORY_SEPARATOR . $private_dir . DIRECTORY_SEPARATOR;
 700            }
 701            else {
 702              $_SESSION['FCKeditor']['UserFilesPath'] = url('system/files') .'/';
 703              $_SESSION['FCKeditor']['UserFilesAbsolutePath'] = realpath(file_directory_path()) . DIRECTORY_SEPARATOR;
 704            }
 705          }
 706        }
 707  
 708        if ($quickupload) {
 709          $js .= $js_id .".Config['LinkUpload'] = true;\n";
 710          $js .= $js_id .".Config['ImageUpload'] = true;\n";
 711          $js .= $js_id .".Config['FlashUpload'] = true;\n";
 712          $js .= $js_id .".Config['LinkUploadURL'] = '". $upload_path ."';\n";
 713          $js .= $js_id .".Config['ImageUploadURL'] = '". $upload_path ."?Type=Image';\n";
 714          $js .= $js_id .".Config['FlashUploadURL'] = '". $upload_path ."?Type=Flash';\n";
 715        }
 716        else {
 717          $js .= $js_id .".Config['LinkUpload'] = false;\n";
 718          $js .= $js_id .".Config['ImageUpload'] = false;\n";
 719          $js .= $js_id .".Config['FlashUpload'] = false;\n";
 720        }
 721  
 722        switch ($filebrowser) {
 723          case 'imce':
 724            $js .= $js_id .".Config['LinkBrowser']= true;\n";
 725            $js .= $js_id .".Config['ImageBrowser']= true;\n";
 726            $js .= $js_id .".Config['FlashBrowser']= true;\n";
 727            $js .= $js_id .".Config['LinkBrowserURL']= '". $host ."index.php?q=imce&app=FCKEditor|url@txtLnkUrl,txtUrl';\n";
 728            $js .= $js_id .".Config['ImageBrowserURL']= '". $host ."index.php?q=imce&app=FCKEditor|url@txtUrl|width@txtWidth|height@txtHeight';\n";
 729            $js .= $js_id .".Config['FlashBrowserURL']= '". $host ."index.php?q=imce&app=FCKEditor|url@txtUrl';\n";
 730            break;
 731  
 732          case 'webfm':
 733            $js .= $js_id .".Config['LinkBrowser']= true;\n";
 734            $js .= $js_id .".Config['ImageBrowser']= true;\n";
 735            $js .= $js_id .".Config['FlashBrowser']= true;\n";
 736            $js .= $js_id .".Config['ImageDlgHideLink']= true;\n";
 737            $js .= $js_id .".Config['LinkBrowserURL']= '". $host ."index.php?q=webfm_popup&url=txtUrl';\n";
 738            $js .= $js_id .".Config['ImageBrowserURL']= '". $host ."index.php?q=webfm_popup&url=txtUrl';\n";
 739            $js .= $js_id .".Config['FlashBrowserURL']= '". $host ."index.php?q=webfm_popup&url=txtUrl';\n";
 740            break;
 741  
 742          case 'builtin':
 743            $js .= $js_id .".Config['LinkBrowser'] = true;\n";
 744            $js .= $js_id .".Config['ImageBrowser'] = true;\n";
 745            $js .= $js_id .".Config['FlashBrowser'] = true;\n";
 746            $js .= $js_id .".Config['LinkBrowserURL'] = '". $editor_path ."/editor/filemanager/browser/default/browser.html?Connector=". $connector_path ."&ServerPath=". $files_path ."';\n";
 747            $js .= $js_id .".Config['ImageBrowserURL'] = '". $editor_path ."/editor/filemanager/browser/default/browser.html?Type=Image&Connector=". $connector_path ."&ServerPath=". $files_path ."';\n";
 748            $js .= $js_id .".Config['FlashBrowserURL'] = '". $editor_path ."/editor/filemanager/browser/default/browser.html?Type=Flash&Connector=". $connector_path ."&ServerPath=". $files_path ."';\n";
 749            break;
 750  
 751          case 'ib':
 752            $js .= $js_id .".Config['ImageBrowser']= true;\n";
 753            $js .= $js_id .".Config['LinkBrowser']= true;\n";
 754            $js .= $js_id .".Config['FlashBrowser']= false;\n";
 755            $js .= $js_id .".Config['ImageBrowserURL']= '". $host ."index.php?q=imagebrowser/view/browser&app=FCKEditor';\n";
 756            $js .= $js_id .".Config['LinkBrowserURL']= '". $host ."index.php?q=imagebrowser/view/browser&app=FCKEditor';\n";
 757            $js .= $js_id .".Config['ImageBrowserWindowWidth']= '680';";
 758            $js .= $js_id .".Config['ImageBrowserWindowHeight'] = '439';";
 759            $js .= $js_id .".Config['LinkBrowserWindowWidth']= '680';";
 760            $js .= $js_id .".Config['LinkBrowserWindowHeight'] = '439';";
 761            break;
 762  
 763          default:
 764          case 'none':
 765            $js .= $js_id .".Config['LinkBrowser'] = false;\n";
 766            $js .= $js_id .".Config['ImageBrowser'] = false;\n";
 767            $js .= $js_id .".Config['FlashBrowser'] = false;\n";
 768            break;
 769        }
 770      }
 771      else {
 772        $js .= $js_id .".Config['LinkBrowser'] = false;\n";
 773        $js .= $js_id .".Config['ImageBrowser'] = false;\n";
 774        $js .= $js_id .".Config['FlashBrowser'] = false;\n";
 775        $js .= $js_id .".Config['LinkUpload'] = false;\n";
 776        $js .= $js_id .".Config['ImageUpload'] = false;\n";
 777        $js .= $js_id .".Config['FlashUpload'] = false;\n";
 778      }
 779  
 780      if (!empty($conf['js_conf'])) {
 781        $lines = preg_split("/[\n\r]+/", $conf['js_conf']);
 782        foreach ($lines as $l) {
 783          if (strlen($l) > 5) {
 784            $eqpos = strpos($l, '=');
 785            if (FALSE !== $eqpos) {
 786              $option = str_replace('FCKConfig.', '', substr($l, 0, $eqpos));
 787              $js .= "\n". $js_id .".Config['". trim($option) ."'] =". substr($l, $eqpos + 1);
 788            }
 789          }
 790        }
 791      }
 792  
 793      // add custom xml stylesheet if it exists
 794      if (!empty($conf['css_style']) && $conf['css_style'] == 'theme') {
 795        if (file_exists($themepath .'fckstyles.xml')) {
 796          $styles_xml_path = $host . $themepath .'fckstyles.xml';
 797          $js .= $js_id .".Config['StylesXmlPath'] = \"". $styles_xml_path ."\";\n";
 798        }
 799      }
 800      elseif (!empty($conf['css_style']) && $conf['css_style'] == 'self') {
 801        $conf['styles_path'] = str_replace("%h%t", "%t", $conf['styles_path']);
 802        $js .=  $js_id .".Config['StylesXmlPath'] = \"". str_replace(array('%h', '%t', '%m'), array($host, $host . $themepath, $module_drupal_path), $conf['styles_path']) ."\";\n";
 803      }
 804  
 805      // add custom xml templae if it exists
 806      if (!empty($conf['templatefile_mode']) && $conf['templatefile_mode'] == 'theme') {
 807        if (file_exists($themepath .'fcktemplates.xml')) {
 808          $styles_xml_path = $host . $themepath .'fcktemplates.xml';
 809          $js .= $js_id .".Config['TemplatesXmlPath'] = \"". $styles_xml_path ."\";\n";
 810        }
 811      }
 812      elseif (!empty($conf['templatefile_mode']) && $conf['templatefile_mode'] == 'self') {
 813        $conf['templatefile_path'] = str_replace("%h%t", "%t", $conf['templatefile_path']);
 814        $js .=  $js_id .".Config['TemplatesXmlPath'] = \"". str_replace(array('%h', '%t', '%m'), array($host, $host . $themepath, $module_drupal_path), $conf['templatefile_path']) ."\";\n";
 815      }
 816  
 817      // add custom stylesheet if configured
 818      // lets hope it exists but we'll leave that to the site admin
 819      $cssfiles = array($module_full_path .'/fckeditor.css');
 820      switch ($conf['css_mode']) {
 821        case 'theme':
 822          global $language, $theme, $theme_info, $base_theme_info;
 823  
 824          $style_css = $themepath .'style.css';
 825          if (!empty($theme_info->stylesheets)) {
 826            $css_files = array();
 827            $editorcss = "\"";
 828            foreach ($base_theme_info as $base) { // Grab stylesheets from base theme
 829              if (!empty($base->stylesheets)) { // may be empty when the base theme reference in the info file is invalid
 830                foreach ($base->stylesheets as $type => $stylesheets) {
 831                  if ($type != "print") {
 832                    foreach ($stylesheets as $name => $path) {
 833                      if (file_exists($path)) {
 834                        $css_files[$name] = $host . $path;
 835                      }
 836                    }
 837                  }
 838                }
 839              }
 840            }
 841            if (!empty($theme_info->stylesheets)) { // Grab stylesheets from current theme
 842              foreach ($theme_info->stylesheets as $type => $stylesheets) {
 843                if ($type != "print") {
 844                  foreach ($stylesheets as $name => $path) {
 845                    if (file_exists($path)) {
 846                      $css_files[$name] = $host . $path;
 847                    }
 848                    elseif (!empty($css_files[$name])) {
 849                      unset($css_files[$name]);
 850                    }
 851                  }
 852                }
 853              }
 854            }
 855            if (!empty($css_files)) {
 856              $editorcss .= implode(",", $css_files) .",";
 857            }
 858            // Grab stylesheets from color module
 859            $color_paths = variable_get('color_'. $theme .'_stylesheets', array());
 860            if (defined('LANGUAGE_RTL') && $language->direction == LANGUAGE_RTL) {
 861              if (!empty($color_paths[1])) {
 862                $editorcss .= $host . $color_paths[1] .",";
 863              }
 864            }
 865            elseif (!empty($color_paths[0])) {
 866              $editorcss .= $host . $color_paths[0] .",";
 867            }
 868            $editorcss .= $module_full_path ."/fckeditor.css\";\n";
 869            $js .=  $js_id .".Config['EditorAreaCSS'] = ". $editorcss;
 870          }
 871          elseif (file_exists($style_css)) {
 872            $js .=  $js_id .".Config['EditorAreaCSS'] = \"". $host . $style_css .",". $module_full_path ."/fckeditor.css\";";
 873          }
 874          else {
 875            $js .=  $js_id .".Config['EditorAreaCSS'] = \"". $module_full_path ."/fckeditor.css\";";
 876          }
 877          break;
 878  
 879        case 'self':
 880          $conf['css_path'] = str_replace("%h%t", "%t", $conf['css_path']);
 881          $cssfiles[] = str_replace(array('%h', '%t'), array($host, $host . $themepath), $conf['css_path']);
 882          $js .=  $js_id .".Config['EditorAreaCSS'] = '". implode(',', $cssfiles) ."';\n";
 883          break;
 884  
 885        case 'none':
 886          $js .=  $js_id .".Config['EditorAreaCSS'] = ". $js_id .".BasePath + 'editor/css/fck_editorarea.css,' + '". implode(',', $cssfiles) ."';\n";
 887          break;
 888      }
 889      if ($num == 2) {
 890        $js .= 'var fckInstances = {};';
 891      }
 892      $js .= 'fckInstances[\''. $textarea_id .'\'] = '. $js_id .";\n";
 893  
 894      drupal_add_js('var '. $js_id .';if (Drupal.jsEnabled) {'. $js .'}', 'inline');
 895  
 896      if ($conf['popup'] == 't') {
 897        $element['#suffix'] .= ' <span class="fckeditor_popuplink">(<a href="#" onclick="FCKeditor_OpenPopup(\''. $module_full_path .'/fckeditor.popup.html\', \''. $js_id .'\', \''. $element['#id'] .'\', \''. $conf['width'] .'\'); return false;">'. t('Open rich text editor') ."</a>)</span>";
 898      }
 899    }
 900  
 901    // display the field id for administrators
 902    if (user_access('administer fckeditor') && (!isset($global_conf['show_fieldnamehint']) || $global_conf['show_fieldnamehint'] == 't')) {
 903      module_load_include('admin.inc', 'fckeditor');
 904  
 905      $element['#suffix'] .= '<div class="textarea-identifier description">'. t('The ID for !excludingorincludinglink this element is %fieldname.', array('!excludingorincludinglink' => l(t('excluding or including'), 'admin/settings/fckeditor'), '%fieldname' => fckeditor_rule_to_string(fckeditor_rule_create(fckeditor_get_nodetype($_GET['q']), $_GET['q'], $element['#id'])))) .'</div>';
 906    }
 907  
 908    return $element;
 909  }
 910  
 911  /**
 912   * sort roles according to precedence settings. previously sorted roles are followed by latest added roles.
 913   */
 914  function fckeditor_sorted_roles($clear = FALSE) {
 915    static $order;
 916    if (isset($order) && $clear !== TRUE) {
 917      return $order;
 918    }
 919    $order = array();
 920    $roles = user_roles(0, 'access fckeditor');
 921  
 922    $result = db_query("SELECT settings FROM {fckeditor_settings} WHERE name='FCKeditor Global Profile'");
 923    $data = db_fetch_object($result);
 924    if (!empty($data->settings)) {
 925      $settings = unserialize($data->settings);
 926      if (isset($settings['rank']) && !empty($settings['rank']))
 927      foreach ($settings['rank'] as $rid) {
 928        if (isset($roles[$rid])) {
 929          $order[$rid] = $roles[$rid];
 930          unset($roles[$rid]);
 931        }
 932      }
 933    }
 934    krsort($roles);//sort the remaining unsorted roles by id, descending.
 935    $order += $roles;
 936    return $order;
 937  }
 938  
 939  /**
 940   * Test if client can render the FCKeditor
 941   * Use built-in test method in fckeditor.php
 942   * If fckeditor.php is not found, return false (probably in such case fckeditor is not installed correctly)
 943   *
 944   * @return
 945   *   TRUE if the browser is reasonably capable
 946   */
 947  function fckeditor_is_compatible_client() {
 948    $editor_local_path    = fckeditor_path(TRUE);
 949  
 950    $fckeditor_main_file = $editor_local_path .'/fckeditor.php';
 951    if (!function_exists('version_compare') || version_compare(phpversion(), '5', '<')) {
 952      $fckeditor_target_file = $editor_local_path .'/fckeditor_php4.php';
 953    }
 954    else {
 955      $fckeditor_target_file = $editor_local_path .'/fckeditor_php5.php';
 956    }
 957  
 958    if (file_exists($fckeditor_target_file)) {
 959      include_once $fckeditor_target_file;
 960      //FCKeditor 2.6.1+
 961      if (function_exists('FCKeditor_IsCompatibleBrowser')) {
 962        return FCKeditor_IsCompatibleBrowser();
 963      }
 964      elseif (class_exists('FCKeditor')) {
 965        //FCKeditor 2.5.1 up to 2.6 with definition of FCKeditor_IsCompatibleBrowser() in fckeditor.php
 966        if (filesize($fckeditor_main_file) > 1500) {
 967          include_once $fckeditor_main_file;
 968        }
 969        //FCKeditor 2.5.0 and earlier
 970        $fck = new FCKeditor('fake');
 971        return $fck->IsCompatible();
 972      }
 973    }
 974  
 975    return FALSE;
 976  }
 977  
 978  /**
 979   * Read FCKeditor path from Global profile
 980   *
 981   * @return
 982   *   path to FCKeditor folder
 983   */
 984  function fckeditor_path($local = FALSE) {
 985    static $fck_path;
 986    static $fck_local_path;
 987  
 988    if (!$fck_path) {
 989      $mod_path = drupal_get_path('module', 'fckeditor');
 990      $global_profile = fckeditor_profile_load('FCKeditor Global Profile');
 991  
 992      //default: path to fckeditor subdirectory in the fckeditor module directory (starting from the document root)
 993      //e.g. for http://example.com/drupal it will be /drupal/sites/all/modules/fckeditor/fckeditor
 994      $fck_path = base_path() . $mod_path .'/fckeditor';
 995  
 996      //default: path to fckeditor subdirectory in the fckeditor module directory (relative to index.php)
 997      //e.g.: sites/all/modules/fckeditor/fckeditor
 998      $fck_local_path = $mod_path .'/fckeditor';
 999  
1000      if ($global_profile) {
1001        $gs = $global_profile->settings;
1002  
1003        if (isset($gs['fckeditor_path'])) {
1004          $tmp_path = $gs['fckeditor_path'];
1005          $tmp_path = strtr($tmp_path, array("%b" => base_path(), "%m" => base_path() . $mod_path));
1006          $tmp_path   = str_replace('\\', '/', $tmp_path);
1007          $tmp_path   = str_replace('//', '/', $tmp_path);
1008          $tmp_path = rtrim($tmp_path, ' \/');
1009          if (substr($tmp_path, 0, 1) != '/') {
1010            $tmp_path = '/'. $tmp_path; //starts with '/'
1011          }
1012          $fck_path = $tmp_path;
1013  
1014          if (empty($gs['fckeditor_local_path'])) {
1015            //fortunately wildcards are used, we can easily get the right server path
1016            if (false !== strpos($gs['fckeditor_path'], "%m")) {
1017              $gs['fckeditor_local_path'] = strtr($gs['fckeditor_path'], array("%m" => $mod_path));
1018            }
1019            if (false !== strpos($gs['fckeditor_path'], "%b")) {
1020              $gs['fckeditor_local_path'] = strtr($gs['fckeditor_path'], array("%b" => "."));
1021            }
1022          }
1023        }
1024  
1025        //fckeditor_path is defined, but wildcards are not used, we need to try to find out where is
1026        //the document root located and append fckeditor_path to it.
1027        if (!empty($gs['fckeditor_local_path'])) {
1028          $fck_local_path = $gs['fckeditor_local_path'];
1029        }
1030        elseif (!empty($gs['fckeditor_path'])) {
1031          module_load_include('lib.inc', 'fckeditor');
1032          $local_path = fckeditor_resolve_url( $gs['fckeditor_path'] ."/" );
1033          if (FALSE !== $local_path) {
1034            $fck_local_path = $local_path;
1035          }
1036        }
1037      }
1038    }
1039    if ($local) {
1040      return $fck_local_path;
1041    }
1042    else {
1043      return $fck_path;
1044    }
1045  }
1046  
1047  function fckeditor_user_get_setting($user, $profile, $setting) {
1048    $default = array(
1049      'default' => 't',
1050      'show_toggle' => 't',
1051      'popup' => 'f',
1052      'skin' => 'default',
1053      'toolbar' => 'default',
1054      'expand' => 't',
1055      'width' => '100%',
1056      'lang' => 'en',
1057      'auto_lang' => 't',
1058    );
1059  
1060    if ($profile->settings['allow_user_conf']) {
1061      $status = isset($user->{'fckeditor_'. $setting}) ? $user->{'fckeditor_'. $setting} : (isset($profile->settings[$setting]) ? $profile->settings[$setting] : $default[$setting]);
1062    }
1063    else {
1064      $status = isset($profile->settings[$setting]) ? $profile->settings[$setting] : $default[$setting];
1065    }
1066  
1067    return $status;
1068  }
1069  
1070  function fckeditor_user_get_profile($user, $element_id = NULL) {
1071    $rids = array();
1072  
1073    // Since fckeditor_profile_load() makes a db hit, only call it when we're pretty sure
1074    // we're gonna render fckeditor.
1075    $sorted_roles = fckeditor_sorted_roles();
1076    foreach (array_keys($sorted_roles) as $rid) {
1077      if (isset($user->roles[$rid])) {
1078        $rids[] = $rid;
1079      }
1080    }
1081  
1082    if ($user->uid == 1 && !sizeof($rids)) {
1083      $r = db_fetch_object(db_query_range("SELECT r.rid FROM {fckeditor_role} r ORDER BY r.rid DESC", 1));
1084      $rids[] = $r->rid;
1085    }
1086  
1087    $profile_names = array();
1088    if (sizeof($rids)) {
1089      $result = db_query("SELECT r.rid, s.name FROM {fckeditor_settings} s INNER JOIN {fckeditor_role} r ON r.name = s.name WHERE r.rid IN (". implode(",", $rids) .")");
1090      while (($row = db_fetch_array($result))) {
1091        if (!isset($profile_names[$row['rid']])) {
1092          $profile_names[$row['rid']] = array();
1093        }
1094        array_push($profile_names[$row['rid']], $row['name']);
1095      }
1096    }
1097  
1098    foreach ($rids as $rid) {
1099      if (!empty($profile_names[$rid])) {
1100        foreach ($profile_names[$rid] as $profile_name) {
1101          $profile = fckeditor_profile_load($profile_name);
1102  
1103          $conf = $profile->settings;
1104          $enabled = fckeditor_is_enabled(empty($conf['excl_mode']) ? '0' : $conf['excl_mode'], empty($conf['excl_regex']) ? '' : $conf['excl_regex'], $element_id, $_GET['q']);
1105  
1106          if ($enabled) {
1107            return $profile;
1108          }
1109        }
1110      }
1111    }
1112  
1113    return FALSE;
1114  }
1115  
1116  function fckeditor_get_nodetype($get_q) {
1117    static $nodetype;
1118  
1119    if (!isset($nodetype)) {
1120      $menuitem = menu_get_item();
1121      $nodetype = '*';
1122      if (!empty($menuitem['page_arguments']) && is_array($menuitem['page_arguments'])) {
1123        foreach ($menuitem['page_arguments'] as $item) {
1124          if (!empty($item->nid) && !empty($item->type)) {
1125            // not 100% valid check if $item is a node
1126            $nodetype = $item->type;
1127            break;
1128          }
1129        }
1130      }
1131  
1132      if ($nodetype == '*') {
1133        $get_q = explode("/", $get_q, 3);
1134        if ($get_q[0] == "node" && $get_q[1] == "add" && !empty($get_q[2])) {
1135          $nodetype = $get_q[2];
1136        }
1137      }
1138    }
1139  
1140    return $nodetype;
1141  }
1142  
1143  function fckeditor_path_to_theme() {
1144    global $theme_key;
1145    static $themepath;
1146    
1147    if (empty($themepath) && !empty($theme_key)) {
1148      $themepath = drupal_get_path('theme', $theme_key);
1149    }
1150  
1151    // fall back
1152    if (empty($themepath)) {
1153      return path_to_theme();
1154    }
1155    
1156    return $themepath;
1157  }


Generated: Mon Jul 9 18:01:44 2012 Cross-referenced by PHPXref 0.7