You are here

function ckeditor_admin_profile_form in CKEditor - WYSIWYG HTML editor 6

Same name and namespace in other branches
  1. 7 includes/ckeditor.admin.inc \ckeditor_admin_profile_form()

Form builder for a normal profile

1 call to ckeditor_admin_profile_form()
ckeditor_admin_profile_clone_form in includes/ckeditor.admin.inc
Clone profile
1 string reference to 'ckeditor_admin_profile_form'
ckeditor_menu in ./ckeditor.module
Implementation of hook_menu().

File

includes/ckeditor.admin.inc, line 273
CKEditor - The text editor for the Internet - http://ckeditor.com Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.

Code

function ckeditor_admin_profile_form($form_state, $profile = NULL) {
  global $theme;
  if ($profile != NULL) {
    $form['_profile'] = array(
      '#type' => 'value',
      '#value' => $profile,
    );
  }
  else {
    $profile = new stdClass();
  }
  module_load_include('inc', 'ckeditor', 'includes/ckeditor.lib');
  drupal_add_js(array(
    'ckeditor_version' => ckeditor_get_version(),
  ), 'setting');
  $skin_options = ckeditor_load_skin_options();
  $lang_options = ckeditor_load_lang_options();

  // Only display the roles that currently don't have a ckeditor profile. One
  // profile per role.
  $orig_roles = user_roles(FALSE, 'access ckeditor');
  $roles = $orig_roles;
  if (!empty($profile->rids) && !user_roles(FALSE, 'access ckeditor')) {
    drupal_set_message(t('You have not assigned the "access ckeditor" !permissions yet. It is recommended to assign the "access ckeditor" !permissions before updating CKEditor profiles.', array(
      '!permissions' => l(t('permissions'), 'admin/user/permissions'),
    )), 'warning');
  }
  if (empty($profile->name)) {
    $result = db_query("SELECT DISTINCT(rid) FROM {ckeditor_role}");
    while ($data = db_fetch_object($result)) {
      if ((empty($profile->rids) || !in_array($data->rid, array_keys((array) $profile->rids))) && !form_get_errors()) {
        unset($roles[$data->rid]);
      }
    }
    if (count($orig_roles) != count($roles)) {
      drupal_set_message(t('Not all user roles are shown since they already have CKEditor profiles assigned. You must first remove the assignment of profiles in order to add them to a new one.'));
    }
  }
  $form['basic'] = array(
    '#type' => 'fieldset',
    '#title' => t('Basic setup'),
    '#collapsible' => TRUE,
    '#collapsed' => TRUE,
  );
  switch (arg(3)) {
    case 'clone':

      //load all profiles to check their names
      $profiles = ckeditor_profile_load();
      $oldname = $profile->name;
      $maxsize = 128;

      //default max name length
      $res = array();
      $pat = "/^(.*?)_([0-9]+)\$/";
      if (preg_match($pat, $oldname, $res)) {

        // oldname like 'name_nr'
        $name = $res[1];
        $num = $res[2] + 1;
      }
      else {
        $name = $oldname;
        $num = 2;
      }
      $newname = substr($name, 0, $maxsize - 3) . '_' . $num;

      // +limit
      while (isset($profiles[$newname])) {

        //find next free number
        $num++;
        $newname = substr($name, 0, $maxsize - 3) . '_' . $num;
      }

      //dont clone rids
      $profile->settings['rids'] = array();
      $profile->rids = array();
      break;
    case 'edit':
      $newname = $profile->name;
      break;
  }
  $global_profile = ckeditor_profile_load("CKEditor Global Profile");
  $toolbar_wizard = !empty($global_profile->settings['toolbar_wizard']) ? $global_profile->settings['toolbar_wizard'] : 't';
  drupal_add_js(array(
    'ckeditor_toolbar_wizard' => $toolbar_wizard,
  ), 'setting');
  $form['basic']['name'] = array(
    '#type' => 'textfield',
    '#title' => t('Profile name'),
    '#default_value' => !empty($profile->name) ? $newname : '',
    '#size' => 40,
    '#maxlength' => 128,
    '#description' => t('Enter a name for this profile. This name is only visible within the CKEditor administration page.'),
    '#required' => TRUE,
  );
  $form['basic']['rids'] = array(
    '#type' => 'checkboxes',
    '#title' => t('Roles allowed to use this profile'),
    '#default_value' => !empty($profile->rids) ? array_keys((array) $profile->rids) : array(),
    '#options' => $roles,
    '#description' => t('Only roles with the "access ckeditor" permission will be shown here. If no role is available, make sure that you have assigned the "access ckeditor" <a href="!permission">permission</a>.', array(
      '!permission' => l(t('permission'), 'admin/user/permissions'),
    )),
    '#required' => TRUE,
  );
  $form['basic']['allow_user_conf'] = array(
    '#type' => 'radios',
    '#title' => t('Allow users to customize CKEditor appearance'),
    '#default_value' => !empty($profile->settings['allow_user_conf']) ? $profile->settings['allow_user_conf'] : 'f',
    '#options' => array(
      'f' => t('No'),
      't' => t('Yes'),
    ),
    '#description' => t('If allowed, users will be able to override the "Editor appearance" by visiting their profile page.'),
  );
  $form['security'] = array(
    '#type' => 'fieldset',
    '#title' => t('Security'),
    '#description' => '<p>' . t('The CKEditor security system protects you from executing malicious code that is already in your database. In plain textareas database content is harmless because it is not executed, but the CKEditor WYSIWYG editor interprets HTML like a web browser and thus the content needs to be filtered before it is loaded.') . '</p>',
    '#collapsible' => TRUE,
    '#collapsed' => TRUE,
  );
  $all = filter_list_all();
  $form['security']['filters'] = array(
    '#type' => 'fieldset',
    '#title' => t('Security filters'),
    '#description' => t('Please choose all filters that protect your content (probably not all filters listed below are security filters).'),
    '#tree' => TRUE,
  );

  //don't bother administrator with filters that definitely are not security filters
  $modules_with_filters_to_skip = array(
    'amazon_filter',
    'asy',
    'bbcode',
    'biblio',
    'blockquote',
    'bookpost',
    'chessboard',
    'citation_filter',
    'codefilter',
    'collapse_text',
    'contextlinks',
    'coolfilter',
    'dialectic',
    'dript',
    'dme',
    'drutex',
    'embedfilter',
    'ext_link_page',
    'extlink',
    'elf',
    'flickr',
    'flickrstickr',
    'footnotes',
    'formdefaults',
    'freelinking',
    'gallery',
    'geogebra',
    'geshifilter',
    'gotwo',
    'googtube',
    'gotcha',
    'gtspam',
    'hidden_content',
    'img_assist',
    'image_filter',
    'imagebrowser',
    'inlinetags',
    'insert_view',
    'insertframe',
    'insertnode',
    'interwiki',
    'jlightbox',
    'jsmath',
    'language_sections',
    'link_node',
    'lootz',
    'markdown',
    'marksmarty',
    'mobile_codes',
    'mykml',
    'nofollowlist',
    'oagwt',
    'paging',
    'pathfilter',
    'pearwiki_filter',
    'php',
    'pirate',
    'reptag',
    'scrippet',
    'scripturefilter',
    'signwriter',
    'slideshowpro',
    'smartlinebreakconverter',
    'smartypants',
    'smileys',
    'spamspan',
    'spam_tokens',
    'spoiler',
    'table_altrow',
    'tablemanager',
    'tableofcontents',
    'textile',
    'tooltips',
    'twikifilter',
    'typogrify',
    'unwrap',
    'urlclass',
    'urlicon',
    'url_replace_filter',
    'username_highlighter',
    'video_filter',
    'quote',
  );
  if (!isset($profile->settings['ss'])) {
    $profile->settings['filters']['filter/0'] = 1;
  }
  foreach ($all as $id => $filter) {
    if (in_array(strtolower($filter->module), $modules_with_filters_to_skip)) {
      continue;
    }

    //skip line break converter and email -> link
    if ($filter->module == 'filter' && in_array($filter->delta, array(
      1,
      2,
    ))) {
      continue;
    }
    $form['security']['filters'][$id] = array(
      '#type' => 'checkbox',
      '#title' => check_plain($filter->name),
      '#default_value' => !empty($profile->settings['filters'][$id]),
      '#description' => check_plain(module_invoke($filter->module, 'filter', 'description', $filter->delta)),
    );
  }
  $form['security']['ss'] = array(
    '#type' => 'radios',
    '#title' => t('Security settings'),
    '#default_value' => isset($profile->settings['ss']) ? $profile->settings['ss'] : '2',
    '#options' => array(
      '2' => t('Always run security filters for CKEditor.'),
      '1' => t('Run security filters only when CKEditor is set to start automatically.'),
    ),
    '#description' => t('There are two ways of starting CKEditor: automatically and manually (via toggle or in a popup). If you decide to apply security filters only when CKEditor starts automatically, you will not be protected when toggling manually from plain textarea to CKEditor or when using CKEditor in the popup mode. Choose this option only if you can detect various attacks (mainly XSS) by yourself just by looking at the HTML code.'),
  );
  $form['ckeditor_exclude_settings'] = array(
    '#type' => 'fieldset',
    '#title' => t('Visibility settings'),
    '#collapsible' => TRUE,
    '#collapsed' => TRUE,
    '#description' => t('The following settings are combined with the visibility settings of the global profile.'),
  );
  $form['ckeditor_exclude_settings']['min_rows'] = array(
    '#type' => 'textfield',
    '#title' => t('Minimum rows'),
    '#default_value' => !empty($profile->settings['min_rows']) ? $profile->settings['min_rows'] : '1',
    '#description' => t("CKEditor will be triggered if the textarea has more rows than the number given here. Enter '1' if you do not want to use this feature."),
  );
  $form['ckeditor_exclude_settings']['excl_mode'] = array(
    '#type' => 'radios',
    '#title' => t('Use inclusion or exclusion mode'),
    '#default_value' => empty($profile->settings['excl_mode']) || in_array($profile->settings['excl_mode'], array(
      0,
      2,
    )) ? 0 : 1,
    '#options' => array(
      '0' => t('Exclude'),
      '1' => t('Include'),
    ),
    '#description' => t('Choose the way of disabling/enabling CKEditor on selected fields/paths (see below). Use <strong>Exclude</strong> to disable CKEditor on selected fields/paths. Use <strong>Include</strong> if you want to load CKEditor only on selected paths/fields.'),
  );

  /**
   * get excluded fields - so we can have normal textareas too
   * split the phrase by any number of commas or space characters,
   * which include " ", \r, \t, \n and \f
   */
  $form['ckeditor_exclude_settings']['excl'] = array(
    '#type' => 'textarea',
    '#title' => t('Fields to exclude/include'),
    '#cols' => 60,
    '#rows' => 5,
    '#prefix' => '<div style="margin-left:20px">',
    '#suffix' => '</div>',
    '#default_value' => !empty($profile->settings['excl']) ? $profile->settings['excl'] : '',
    '#description' => t('Enter the paths to the textarea fields for which you want to enable or disable CKEditor.') . ' ' . t('See the !helppagelink for more information about defining field names. Short instruction is available below.', array(
      '!helppagelink' => l(t('Help page'), 'admin/help/ckeditor', array(
        'fragment' => 'fieldinclexcl',
      )),
    )) . ' <ul><li>' . t('Path structure: <strong>theme_name:content_type@path.element_id</strong>') . '</li><li>' . t('The following wildcards are available: "*", "?".') . '</li><li>' . t('Content type and theme name is optional. You may even just specify the path or the field ID.') . '</li><li>' . t('Examples:') . '<ul><li><em>garland:blog@*.edit-body</em> - ' . t('matches all fields of type <code>blog</code> called <code>edit-body</code> in the garland theme, on any page.') . '<li><em>node/add/*.edit-user-*</em> - ' . t('matches fields starting with <code>edit-user-</code> on pages starting with <code>node/add/</code>') . '</li></ul></li></ul>',
    '#wysiwyg' => FALSE,
  );
  $form['ckeditor_exclude_settings']['simple_incl'] = array(
    '#type' => 'textarea',
    '#title' => t('Force simplified toolbar on the following fields'),
    '#cols' => 60,
    '#rows' => 5,
    '#default_value' => !empty($profile->settings['simple_incl']) ? $profile->settings['simple_incl'] : '',
    '#description' => t('Enter the paths to the textarea fields for which you want to force the simplified toolbar.') . ' ' . t('Please see the !helppagelink for more information about defining field names. Take a look at the exclusion settings (above) for a short instruction.', array(
      '!helppagelink' => l(t('Help page'), 'admin/help/ckeditor', array(
        'fragment' => 'fieldinclexcl',
      )),
    )),
    '#wysiwyg' => FALSE,
  );
  $form['appearance'] = array(
    '#type' => 'fieldset',
    '#title' => t('Editor appearance'),
    '#collapsible' => TRUE,
    '#collapsed' => TRUE,
  );
  $form['appearance']['default'] = array(
    '#type' => 'radios',
    '#title' => t('Default state'),
    '#default_value' => !empty($profile->settings['default']) ? $profile->settings['default'] : 't',
    '#options' => array(
      't' => t('Enabled'),
      'f' => t('Disabled'),
    ),
    '#description' => t('Default editor state. If disabled, the rich text editor may still be enabled by using toggle or popup window.'),
  );
  $form['appearance']['default_state_exception'] = array(
    '#type' => 'textarea',
    '#title' => t('Reverse default state on the following fields'),
    '#cols' => 60,
    '#rows' => 5,
    '#default_value' => !empty($profile->settings['default_state_exception']) ? $profile->settings['default_state_exception'] : '',
    '#description' => t('Enter the paths to the textarea fields for which you want to reverse the default state above.') . ' ' . t('See the !helppagelink for more information about defining field names.', array(
      '!helppagelink' => l(t('Help page'), 'admin/help/ckeditor', array(
        'fragment' => 'fieldinclexcl',
      )),
    )),
    '#wysiwyg' => FALSE,
  );
  $form['appearance']['show_toggle'] = array(
    '#type' => 'radios',
    '#title' => t('Show the disable/enable rich text editor toggle'),
    '#default_value' => !empty($profile->settings['show_toggle']) ? $profile->settings['show_toggle'] : 't',
    '#options' => array(
      't' => t('Show'),
      'f' => t('Hide'),
    ),
    '#description' => t('Whether or not to show the disable/enable rich text editor toggle below the textarea. Works only if CKEditor is not running in a popup window (see below).'),
  );
  $form['appearance']['popup'] = array(
    '#type' => 'radios',
    '#title' => t('Use CKEditor in a popup window'),
    '#default_value' => !empty($profile->settings['popup']) ? $profile->settings['popup'] : 'f',
    '#options' => array(
      'f' => t('No'),
      't' => t('Yes'),
    ),
    '#description' => t('If this option is enabled, a link to a popup window will be used instead of a textarea replace.'),
  );

  //if skin is not set or not exists select default skin (moono or skin) or first on the skin list
  if (empty($profile->settings['skin']) || !empty($profile->settings['skin']) && !array_key_exists($profile->settings['skin'], $skin_options)) {
    if (count($skin_options) > 0) {
      if (array_key_exists('moono', $skin_options)) {
        $profile->settings['skin'] = 'moono';
      }
      else {
        if (array_key_exists('kama', $skin_options)) {
          $profile->settings['skin'] = 'kama';
        }
        else {
          $profile->settings['skin'] = $skin_options[0];
        }
      }
    }
  }
  $form['appearance']['skin'] = array(
    '#type' => 'select',
    '#title' => t('Skin'),
    '#default_value' => !empty($profile->settings['skin']) ? $profile->settings['skin'] : 'default',
    '#options' => $skin_options,
    '#description' => t('Choose a CKEditor skin.'),
  );
  $ui_colors = array(
    "default" => t('CKEditor default'),
    "custom" => t('Select manually'),
  );
  if (function_exists('color_get_palette')) {

    // apparently $theme is not initialized (?)
    if (empty($theme)) {
      init_theme();
    }
    $palette = @color_get_palette($theme, FALSE);

    //[#652274]
    $color_palette['default'] = '#D3D3D3';
    if (!empty($palette)) {
      if (!empty($palette['base'])) {
        $color_palette['color_base'] = $palette['base'];
        $ui_colors["color_base"] = t('Color module: base');
      }
      if (!empty($palette['top'])) {
        $color_palette['color_top'] = $palette['top'];
        $ui_colors["color_top"] = t('Color module: top');
      }
      if (!empty($palette['bottom'])) {
        $color_palette['color_bottom'] = $palette['bottom'];
        $ui_colors["color_bottom"] = t('Color module: bottom');
      }
    }
    drupal_add_js(array(
      'ckeditor_uicolor' => $color_palette,
    ), 'setting');
  }
  $editor_path = ckeditor_path(FALSE);
  $module_drupal_path = drupal_get_path('module', 'ckeditor');
  drupal_set_html_head('<script type="text/javascript">window.CKEDITOR_BASEPATH = "' . $editor_path . '/";</script>');
  drupal_set_html_head('<script type="text/javascript" src="' . $editor_path . '/ckeditor.js?I"></script>');
  drupal_add_js($module_drupal_path . '/ckeditor.config.js', 'file');
  drupal_add_js($module_drupal_path . '/includes/ckeditor.admin.js', 'file');
  if ($toolbar_wizard == 't') {
    if (module_exists('jquery_ui')) {
      if (!module_exists('jquery_update') || jquery_update_get_version() <= 1.2) {
        drupal_add_js($module_drupal_path . '/includes/jqueryUI/jquery-1.4.4.min.js', 'core');
      }
      if (jquery_ui_get_version() > 1.6) {
        jquery_ui_add(array(
          'ui.sortable',
        ));
      }
      else {
        drupal_add_js($module_drupal_path . '/includes/jqueryUI/jquery-ui.min.js', 'file');
        drupal_add_js($module_drupal_path . '/includes/jqueryUI/jquery.ui.widget.min.js', 'file');
        drupal_add_js($module_drupal_path . '/includes/jqueryUI/jquery.ui.sortable.min.js', 'file');
      }
    }
    else {
      if (!module_exists('jquery_update') || jquery_update_get_version() <= 1.2) {
        drupal_add_js($module_drupal_path . '/includes/jqueryUI/jquery-1.4.4.min.js', 'core');
      }
      drupal_add_js($module_drupal_path . '/includes/jqueryUI/jquery-ui.min.js', 'file');
      drupal_add_js($module_drupal_path . '/includes/jqueryUI/jquery.ui.widget.min.js', 'file');
      drupal_add_js($module_drupal_path . '/includes/jqueryUI/jquery.ui.sortable.min.js', 'file');
    }
    drupal_add_js($module_drupal_path . '/includes/jqueryUI/sort.js', 'file');
  }
  $form['appearance']['uicolor'] = array(
    '#type' => 'select',
    '#title' => t('User interface color'),
    '#default_value' => !empty($profile->settings['uicolor']) ? $profile->settings['uicolor'] : 'default',
    '#options' => $ui_colors,
  );
  $skinframe_url = url('admin/settings/ckeditor/skinframe', array(
    'query' => array(
      'token' => drupal_get_token('ckeditorSkinframeCall'),
      'skin' => 'kama',
      'uicolor' => !empty($profile->settings['uicolor_user']) && $profile->settings['uicolor'] == 'custom' ? ltrim($profile->settings['uicolor_user'], '#') : 'D3D3D3',
    ),
  ));
  $form['appearance']['skinframe'] = array(
    '#type' => 'markup',
    '#value' => '<iframe frameborder="0" id="skinframe" marginheight="0" marginwidth="0" src="' . $skinframe_url . '" style="height:500px;width:700px;"></iframe><br/>',
    '#description' => '',
  );
  $form['appearance']['uicolor_user'] = array(
    '#type' => 'hidden',
    '#default_value' => !empty($profile->settings['uicolor_user']) ? $profile->settings['uicolor_user'] : 'default',
  );
  $form['appearance']['toolbar'] = array(
    '#type' => 'textarea',
    '#title' => t('Toolbar'),
    '#default_value' => !empty($profile->settings['toolbar']) ? $profile->settings['toolbar'] : '',
    '#description' => t('Load sample toolbar: <a href="#" id="cke_toolbar_DrupalBasic" class="cke_load_toolbar">Basic</a> | <a href="#" id="cke_toolbar_DrupalAdvanced" class="cke_load_toolbar">Advanced</a> | <a href="#" id="cke_toolbar_DrupalFull" class="cke_load_toolbar">Full</a>'),
    '#wysiwyg' => FALSE,
    '#rows' => 15,
  );
  if ($toolbar_wizard == 't') {
    $form['appearance']['toolbar_wizzard_used'] = array(
      '#type' => 'markup',
      '#value' => '<div>' . t('Used buttons') . '</div><div class="sortableList" id="groupLayout"></div><br/>',
      '#description' => t('Currently used buttons'),
    );
    drupal_add_js(array(
      'cke_toolbar_buttons_all' => ckeditor_toolbar_buttons_all(),
    ), 'setting');
    $form['appearance']['toolbar_wizzard_all'] = array(
      '#type' => 'markup',
      '#value' => '<div>' . t('All buttons') . '</div><div id="allButtons" class="sortableList"></div><br/>',
      '#description' => t('All available buttons'),
    );
  }
  $plugin_list = ckeditor_load_plugins();
  $plugins = array();
  if (isset($profile->settings['loadPlugins'])) {
    foreach ($plugin_list as $key => $val) {
      $plugins[$key] = $val['desc'];
    }
  }
  else {
    $default_plugins = array();
    foreach ($plugin_list as $key => $val) {
      $plugins[$key] = $val['desc'];
      if (isset($val['default']) && $val['default'] == 't') {
        $default_plugins[] = $key;
      }
    }
  }
  $form['appearance']['loadPlugins'] = array(
    '#type' => 'checkboxes',
    '#title' => t('Plugins'),
    '#default_value' => isset($profile->settings['loadPlugins']) ? array_keys((array) $profile->settings['loadPlugins']) : $default_plugins,
    '#options' => $plugins,
    '#description' => t('Choose the plugins that you want to enable in CKEditor.'),
  );
  $form['appearance']['expand'] = array(
    '#type' => 'radios',
    '#title' => t('Toolbar state on startup'),
    '#default_value' => !empty($profile->settings['expand']) ? $profile->settings['expand'] : 't',
    '#options' => array(
      't' => t('Expanded'),
      'f' => t('Collapsed'),
    ),
    '#description' => t('The toolbar will start in an expanded or collapsed state.'),
  );
  if (file_exists(ckeditor_path(TRUE) . '/plugins/divarea/plugin.js')) {
    $form['appearance']['use_divarea'] = array(
      '#type' => 'radios',
      '#title' => t('"Div-based" editor'),
      '#default_value' => !empty($profile->settings['use_divarea']) ? $profile->settings['use_divarea'] : 'f',
      '#options' => array(
        't' => t('Enabled'),
        'f' => t('Disabled'),
      ),
      '#description' => t("Loading editor into <code>div</code> instead of <code>iframe</code>."),
    );
  }
  $form['appearance']['width'] = array(
    '#type' => 'textfield',
    '#title' => t('Editor width'),
    '#default_value' => !empty($profile->settings['width']) ? $profile->settings['width'] : '100%',
    '#description' => t("Editor interface width in pixels or percent. Examples: 400, 100%."),
    '#size' => 40,
    '#maxlength' => 128,
  );
  $form['appearance']['lang'] = array(
    '#type' => 'select',
    '#title' => t('Language'),
    '#default_value' => !empty($profile->settings['lang']) ? $profile->settings['lang'] : 'en',
    '#options' => $lang_options,
    '#description' => t('The language for the CKEditor user interface.'),
  );
  $form['appearance']['auto_lang'] = array(
    '#type' => 'radios',
    '#title' => t('Auto-detect language'),
    '#default_value' => !empty($profile->settings['auto_lang']) ? $profile->settings['auto_lang'] : 't',
    '#options' => array(
      't' => t('Enabled'),
      'f' => t('Disabled'),
    ),
    '#description' => t('Automatically detect the user language.'),
  );
  $form['appearance']['language_direction'] = array(
    '#type' => 'select',
    '#title' => t('Language direction'),
    '#default_value' => !empty($profile->settings['language_direction']) ? $profile->settings['language_direction'] : 'default',
    '#options' => array(
      'default' => t('Get from current locale (default)'),
      'ltr' => t('Left-To-Right'),
      // language like English
      'rtl' => t('Right-To-Left'),
    ),
    '#description' => t('Choose the language direction used in the editing area. Even when CKEditor automatically detects the user language and adjusts its user interface, the editing area is not automatically changed into the LTR or RTL mode. To be able to type LTR (like English) and RTL (like Arabic, Hebrew, Persian) content at the same time, please make sure that the <strong>!bidiltr</strong> and <strong>!bidirtl</strong> buttons are enabled in the toolbar.', array(
      '!bidiltr' => 'BidiLtr',
      '!bidirtl' => 'BidiRtl',
    )),
  );
  $form['acf'] = array(
    '#type' => 'fieldset',
    '#title' => t('Advanced content filter'),
    '#description' => t('Configure input data filtering in CKEditor. See !link for more information about ACF.', array(
      '!link' => l(t('this blog post'), 'http://ckeditor.com/blog/Upgrading-to-CKEditor-4.1'),
    )),
    '#collapsible' => TRUE,
    '#collapsed' => TRUE,
  );
  $form['acf']['allowed_content'] = array(
    '#type' => 'radios',
    '#title' => t('Advanced content filter'),
    '#description' => t('<strong>Enabled:</strong> CKEditor will only allow tags/attributes/styles provided by CKEditor features. Disallowed content will be removed directly by CKEditor. When configured properly, it helps to ensure a true WYSIWYG experience.') . '<br />' . '<br />' . t('<strong>Disabled:</strong> CKEditor will not filter any tags and as a result, the user will be able to insert any content into the editor. The content will only be filtered by server-side filters associated with input formats.') . '<br />' . '<br />' . t('<strong>Example:</strong> if only Bold and Link buttons are enabled, only !strong and !a tags will be allowed. Any !b tags will automatically be converted into !strong. The !img tag will not be allowed, unless the Image button is added to the toolbar.', array(
      '!strong' => '<code>&lt;strong&gt;</code>',
      '!a' => '<code>&lt;a&gt;</code>',
      '!img' => '<code>&lt;img&gt;</code>',
      '!b' => '<code>&lt;b&gt;</code>',
    )) . '<br /><br />' . t('<strong>Warning:</strong> CKEditor will not use the set of tags associated with text format. Only the buttons enabled in the toolbar and optional plugins will determine which tags/attributes/styles are handled by CKEditor. Enabling ACF in CKEditor does not affect server-side filtering done by Drupal in any way.'),
    '#default_value' => !empty($profile->settings['allowed_content']) ? $profile->settings['allowed_content'] : 't',
    '#options' => array(
      't' => t('Enabled'),
      'f' => t('Disabled'),
    ),
  );
  $form['acf']['extraAllowedContent'] = array(
    '#type' => 'textarea',
    '#title' => t('Extra allowed content'),
    '#default_value' => !empty($profile->settings['extraAllowedContent']) ? $profile->settings['extraAllowedContent'] : "",
    '#cols' => 60,
    '#rows' => 5,
    '#description' => t('Set additional allowed content rules for CKEditor. Separate rules with a semicolon. See !docs for more information.', array(
      '!docs' => l(t('CKEditor documentation'), 'http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-allowedContent'),
    )) . '<p>' . t('<strong>Example:</strong> !rules', array(
      '!rules' => "<code>object[width,height];param[name,value];embed[*];</code>",
    )) . '</p>',
    '#wysiwyg' => FALSE,
  );
  $form['output'] = array(
    '#type' => 'fieldset',
    '#title' => t('Cleanup and output'),
    '#collapsible' => TRUE,
    '#collapsed' => TRUE,
  );
  $form['output']['enter_mode'] = array(
    '#type' => 'select',
    '#title' => t('Enter mode'),
    '#default_value' => !empty($profile->settings['enter_mode']) ? $profile->settings['enter_mode'] : 'p',
    '#options' => array(
      'p' => '<p>',
      'br' => '<br>',
      'div' => '<div>',
    ),
    '#description' => t('Set which tag should be used by CKEditor when the <em>Enter</em> key is pressed.'),
  );
  $form['output']['shift_enter_mode'] = array(
    '#type' => 'select',
    '#title' => t('Shift+Enter mode'),
    '#default_value' => !empty($profile->settings['shift_enter_mode']) ? $profile->settings['shift_enter_mode'] : 'br',
    '#options' => array(
      'p' => '<p>',
      'br' => '<br>',
      'div' => '<div>',
    ),
    '#description' => t('Set which tag should be used by CKEditor when the <em>Shift+Enter</em> key combination is pressed.'),
  );
  $form['output']['font_format'] = array(
    '#type' => 'textfield',
    '#title' => t('Font formats'),
    '#default_value' => !empty($profile->settings['font_format']) ? $profile->settings['font_format'] : 'p;div;pre;address;h1;h2;h3;h4;h5;h6',
    '#size' => 40,
    '#maxlength' => 250,
    '#description' => t('Semicolon-separated list of HTML font formats. Allowed values are: !allowed_values', array(
      '!allowed_values' => '<code>p;div;pre;address;h1;h2;h3;h4;h5;h6</code>',
    )),
  );
  if (!empty($profile->settings['formatting']['custom_formatting_options'])) {
    foreach ($profile->settings['formatting']['custom_formatting_options'] as $k => $v) {
      if ($v === 0) {
        unset($profile->settings['formatting']['custom_formatting_options'][$k]);
      }
    }
  }
  $form['output']['custom_formatting'] = array(
    '#type' => 'radios',
    '#title' => t('Use custom formatting options'),
    '#default_value' => !empty($profile->settings['custom_formatting']) ? $profile->settings['custom_formatting'] : 'f',
    '#options' => array(
      't' => t('Yes'),
      'f' => t('No'),
    ),
  );
  $form['output']['formatting'] = array(
    '#type' => 'fieldset',
    '#title' => t('Custom formatting options'),
    '#tree' => TRUE,
  );
  $form['output']['formatting']['custom_formatting_options'] = array(
    '#type' => 'checkboxes',
    '#default_value' => isset($profile->settings['formatting']['custom_formatting_options']) ? array_keys((array) $profile->settings['formatting']['custom_formatting_options']) : array(
      'indent' => 'indent',
      'breakBeforeOpen' => 'breakBeforeOpen',
      'breakAfterOpen' => 'breakAfterOpen',
      'breakAfterClose' => 'breakAfterClose',
    ),
    '#options' => array(
      'indent' => t('Indent the element contents.'),
      'breakBeforeOpen' => t('Break line before the opening tag.'),
      'breakAfterOpen' => t('Break line after the opening tag.'),
      'breakBeforeClose' => t('Break line before the closing tag.'),
      'breakAfterClose' => t('Break line after the closing tag.'),
      'pre_indent' => t('Indent the <code>&lt;pre&gt;</code> element contents.'),
    ),
  );
  $form['css'] = array(
    '#type' => 'fieldset',
    '#title' => t('CSS'),
    '#collapsible' => TRUE,
    '#collapsed' => TRUE,
  );
  $form['css']['css_mode'] = array(
    '#type' => 'select',
    '#title' => t('Editor CSS'),
    '#default_value' => !empty($profile->settings['css_mode']) ? $profile->settings['css_mode'] : 'theme',
    '#options' => array(
      'theme' => t('Use theme CSS'),
      'self' => t('Define CSS'),
      'none' => t('CKEditor default'),
    ),
    '#description' => t('Defines the CSS to be used in the editor area.!title_theme_css &ndash; load the !style_css file from the current site theme.!title_define_css &ndash; enter the CSS file path below.!title_ckeditor_default &ndash; use the default editor CSS.', array(
      '!title_theme_css' => '<br /><strong>' . t('Use theme CSS') . '</strong>',
      '!title_define_css' => '<br /><strong>' . t('Define CSS') . '</strong>',
      '!title_ckeditor_default' => '<br /><strong>' . t('CKEditor default') . '</strong>',
      '!style_css' => '<code>style.css</code>',
    )),
  );
  $form['css']['css_path'] = array(
    '#type' => 'textfield',
    '#title' => t('CSS file path'),
    '#default_value' => !empty($profile->settings['css_path']) ? $profile->settings['css_path'] : "",
    '#size' => 40,
    '#maxlength' => 255,
    '#description' => t('Enter the path to the CSS file (Example: !example1) or a list of CSS files separated with a comma (Example: !example2). Make sure you select the <strong>Define CSS</strong> option above.', array(
      '!example1' => '<code>"css/editor.css"</code>',
      '!example2' => '<code>"/themes/garland/style.css,http://example.com/style.css"</code>',
    )) . '<br />' . t('Available placeholders:!h - host name (!host).!t - path to theme (!theme).', array(
      '!h' => '<br /><code>%h</code>',
      '!t' => '<br /><code>%t</code>',
      '!host' => base_path(),
      '!theme' => base_path() . path_to_theme() . '/',
    )),
  );
  $form['css']['css_style'] = array(
    '#type' => 'select',
    '#title' => t('Predefined styles'),
    '#default_value' => !empty($profile->settings['css_style']) ? $profile->settings['css_style'] : 'theme',
    '#options' => array(
      'theme' => t('Use theme ckeditor.styles.js'),
      'self' => t('Define path to ckeditor.styles.js'),
      'default' => t('CKEditor default'),
    ),
    '#description' => t('Define the location of the !ckeditor_styles_js_file file. It is used by the <strong>Style</strong> drop-down list available in the default toolbar. Copy the !ckeditor_styles_js_path file into your theme directory (!theme) and adjust it to your needs.', array(
      '!ckeditor_styles_js_file' => '<code>ckeditor.styles.js</code>',
      '!ckeditor_styles_js_path' => '<code>' . ckeditor_path(TRUE) . '/ckeditor.styles.js</code>',
      '!theme' => '<code>' . path_to_theme() . '/ckeditor.styles.js</code>',
    )),
  );
  $form['css']['styles_path'] = array(
    '#type' => 'textfield',
    '#title' => t('Predefined styles path'),
    '#default_value' => !empty($profile->settings['styles_path']) ? $profile->settings['styles_path'] : "",
    '#size' => 40,
    '#maxlength' => 255,
    '#description' => t('Enter the path to a file with predefined styles (Example: !example1). Make sure you select the <strong>Define path to ckeditor.styles.js</strong> option above.', array(
      '!example1' => '<code>/ckeditor.styles.js</code>',
    )) . '<br />' . t('Available placeholders:!h &ndash;  host name (!host).!t &ndash; path to theme !theme.!m &ndash; path to the CKEditor module !module.', array(
      '!h' => '<br /><code>%h</code>',
      '!t' => '<br /><code>%t</code>',
      '!m' => '<br /><code>%m</code>',
      '!host' => '<code>' . base_path() . '</code>',
      '!theme' => '<code>' . base_path() . path_to_theme() . '/</code>',
      '!module' => '<code>' . drupal_get_path('module', 'ckeditor') . '</code>',
    )),
  );
  $form['ckeditor_upload_settings'] = array(
    '#type' => 'fieldset',
    '#title' => t('File browser settings'),
    '#collapsible' => TRUE,
    '#collapsed' => TRUE,
    '#description' => t('Set the file browser settings. A file browser will allow you to browse the files stored on the server and embed them as links, images, or Flash movies. CKEditor is compatible with such Drupal modules as !imce, !ib, !webfm or !elfinder. CKEditor can be also integrated with !ckfinder, an advanced Ajax file manager.', array(
      '!imce' => l(t('IMCE'), 'http://drupal.org/project/imce'),
      '!ib' => l(t('Image Browser'), 'http://drupal.org/project/imagebrowser'),
      '!webfm' => l(t('Web File Manager'), 'http://drupal.org/project/webfm'),
      '!ckfinder' => l(t('CKFinder'), 'http://cksource.com/ckfinder'),
      '!elfinder' => l(t('elFinder'), 'http://drupal.org/project/elfinder'),
    )),
  );
  $filebrowsers = array(
    'none' => t('None'),
    'ckfinder' => t('CKFinder'),
  );
  $filebrowsers_dialogs = array(
    '' => t('Same as in the Link dialog window'),
    'ckfinder' => t('CKFinder'),
  );
  if (module_exists('imce')) {
    $filebrowsers['imce'] = t('IMCE');
    $filebrowsers_dialogs['imce'] = t('IMCE');
  }
  if (module_exists('tinybrowser')) {
    $filebrowsers['tinybrowser'] = t('TinyBrowser');
    $filebrowsers_dialogs['tinybrowser'] = t('TinyBrowser');
  }
  if (module_exists('imagebrowser')) {
    $filebrowsers['ib'] = t('Image Browser');
    $filebrowsers_dialogs['ib'] = t('Image Browser');
  }
  if (module_exists('webfm_popup')) {
    $filebrowsers['webfm'] = t('Web File Manager');
    $filebrowsers_dialogs['webfm'] = t('Web File Manager');
  }
  if (module_exists('elfinder')) {
    $filebrowsers['elfinder'] = t('elFinder');
    $filebrowsers_dialogs['elfinder'] = t('elFinder');
  }
  $form['ckeditor_upload_settings']['filebrowser'] = array(
    '#type' => 'select',
    '#title' => t('File browser type (Link dialog window)'),
    '#default_value' => !empty($profile->settings['filebrowser']) ? $profile->settings['filebrowser'] : 'none',
    '#options' => $filebrowsers,
    '#description' => t('Select the file browser that you would like to use to upload files.'),
  );
  $form['ckeditor_upload_settings']['filebrowser_image'] = array(
    '#type' => 'select',
    '#title' => t('File browser type (Image dialog window)'),
    '#default_value' => !empty($profile->settings['filebrowser_image']) ? $profile->settings['filebrowser_image'] : 'none',
    '#options' => $filebrowsers_dialogs,
    '#description' => t('Select the file browser that you would like to use to upload images.'),
  );
  $form['ckeditor_upload_settings']['filebrowser_flash'] = array(
    '#type' => 'select',
    '#title' => t('File browser type (Flash dialog window)'),
    '#default_value' => !empty($profile->settings['filebrowser_flash']) ? $profile->settings['filebrowser_flash'] : 'none',
    '#options' => $filebrowsers_dialogs,
    '#description' => t('Select the file browser that you would like to use to upload Flash movies.'),
  );
  $current_user_files_path = empty($profile->settings['UserFilesPath']) ? "%b%f/" : $profile->settings['UserFilesPath'];
  $current_user_files_path = strtr($current_user_files_path, array(
    "%f" => file_directory_path(),
    "%u" => "UID",
    "%b" => base_path(),
    "%n" => "UNAME",
  ));
  $current_user_files_absolute_path = empty($profile->settings['UserFilesAbsolutePath']) ? "%d%b%f/" : $profile->settings['UserFilesAbsolutePath'];
  $current_user_files_absolute_path = strtr($current_user_files_absolute_path, array(
    "%f" => file_directory_path(),
    "%u" => "UID",
    "%b" => base_path(),
    "%d" => $_SERVER['DOCUMENT_ROOT'],
    "%n" => "UNAME",
  ));
  if (variable_get('file_downloads', '') != FILE_DOWNLOADS_PRIVATE) {
    $form['ckeditor_upload_settings']['UserFilesPath'] = array(
      '#type' => 'textfield',
      '#prefix' => '<fieldset><legend>' . t('CKFinder settings') . '</legend>',
      '#title' => t('Path to uploaded files'),
      '#default_value' => !empty($profile->settings['UserFilesPath']) ? $profile->settings['UserFilesPath'] : "%b%f/",
      '#size' => 40,
      '#maxlength' => 255,
      '#description' => t('Path to uploaded files relative to the document root.') . '<br />' . t('Available placeholders:!b &ndash; the base URL path of the Drupal installation <code>!base</code>.!f &ndash; Drupal file system path where the files are stored <code>!files</code>.!u &ndash; User ID.!n &ndash; Username.', array(
        '!n' => '<br /><code>%n</code>',
        '!u' => '<br /><code>%u</code>',
        '!f' => '<br/><code>%f</code>',
        '!b' => '<br/><code>%b</code>',
        '!files' => file_directory_path(),
        '!base' => base_path(),
      )) . '<br />' . t('Current path: !path', array(
        '!path' => '<code>' . $current_user_files_path . '</code>',
      )),
    );
    $form['ckeditor_upload_settings']['UserFilesAbsolutePath'] = array(
      '#type' => 'textfield',
      '#title' => t('Absolute path to uploaded files'),
      '#default_value' => !empty($profile->settings['UserFilesAbsolutePath']) ? $profile->settings['UserFilesAbsolutePath'] : "%d%b%f/",
      '#size' => 40,
      '#maxlength' => 255,
      '#suffix' => '</fieldset>',
      '#description' => t('The path to the local directory (on the server) which points to the path defined above. If left empty, CKEditor will try to discover the right path.') . '<br />' . t('Available placeholders:!d &ndash; the server path to document root !root.!b &ndash; base URL path of the Drupal installation !base.!f &ndash; Drupal file system path where the files are stored !files.!u &ndash; User ID.!n &ndash; Username.', array(
        '!u' => '<br /><code>%u</code>',
        '!n' => '<br /><code>%n</code>',
        '!d' => '<br/><code>%d</code>',
        '!b' => '<br /><code>%b</code>',
        '!f' => '<br/><code>%f</code>',
        '!files' => '<code>' . file_directory_path() . '</code>',
        '!base' => '<code>' . base_path() . '</code>',
        '!root' => '<code>' . $_SERVER['DOCUMENT_ROOT'] . '</code>',
      )) . '<br />' . t('Current path: !path', array(
        '!path' => '<code>' . $current_user_files_absolute_path . '</code>',
      )),
    );
  }
  if (variable_get('file_downloads', '') == FILE_DOWNLOADS_PRIVATE) {
    $form['ckeditor_upload_settings']['private_path_descrption'] = array(
      '#value' => '<div>' . t('Setting a relative path to uploaded files was disabled because private downloads are enabled and thus this path is calculated automatically. To change the location of uploaded files in the private file system, edit the <strong>!url</strong>.', array(
        '!url' => l(t('CKEditor Global Profile'), 'admin/settings/ckeditor/editg'),
      )) . '</div>',
    );
  }
  $form['advanced'] = array(
    '#type' => 'fieldset',
    '#title' => t('Advanced options'),
    '#collapsible' => TRUE,
    '#collapsed' => TRUE,
  );
  if (ckeditor_get_version(TRUE) == 3) {
    $form['advanced']['ckeditor_load_method'] = array(
      '#type' => 'select',
      '#title' => t('Loading method'),
      '#default_value' => !empty($profile->settings['ckeditor_load_method']) ? $profile->settings['ckeditor_load_method'] : 'ckeditor.js',
      '#options' => _ckeditor_load_methods(),
      '#description' => t('Select the loading method of CKEditor. If the !ckeditor_basic_js file is used, only a small file is loaded initially and the rest of the editor is loaded later (see <strong>Loading timeout</strong>). This might be useful if CKEditor is disabled by default.', array(
        '!ckeditor_basic_js' => '<code>ckeditor_basic.js</code>',
      )),
    );
    $form['advanced']['ckeditor_load_time_out'] = array(
      '#type' => 'textfield',
      '#title' => t('Loading timeout'),
      '#default_value' => !empty($profile->settings['ckeditor_load_time_out']) ? $profile->settings['ckeditor_load_time_out'] : "0",
      '#size' => 40,
      '#maxlength' => 255,
      '#description' => t('The time to wait (in seconds) to load the full editor code after the page is loaded, if the !ckeditor_basic_js file is used. If set to zero, the editor is loaded on demand.', array(
        '!ckeditor_basic_js' => '<code>ckeditor_basic.js</code>',
      )),
    );
  }
  $form['advanced']['forcePasteAsPlainText'] = array(
    '#type' => 'select',
    '#title' => t('Force pasting as plain text'),
    '#default_value' => !empty($profile->settings['forcePasteAsPlainText']) ? $profile->settings['forcePasteAsPlainText'] : "f",
    '#options' => array(
      't' => t('Enabled'),
      'f' => t('Disabled'),
    ),
    '#description' => t('If enabled, HTML content will be automatically changed to plain text when pasting.'),
  );
  $form['advanced']['html_entities'] = array(
    '#type' => 'radios',
    '#title' => t('HTML Entities'),
    '#default_value' => !empty($profile->settings['html_entities']) ? $profile->settings['html_entities'] : 't',
    '#description' => t('Convert all applicable characters to HTML entities.'),
    '#options' => array(
      'f' => t('No'),
      't' => t('Yes'),
    ),
  );
  $form['advanced']['scayt_autoStartup'] = array(
    '#type' => 'radios',
    '#title' => t('Spellchecker'),
    '#default_value' => !empty($profile->settings['scayt_autoStartup']) ? $profile->settings['scayt_autoStartup'] : 'f',
    '#description' => t('If enabled, turns on SCAYT (Spell Check As You Type) automatically after loading the editor.'),
    '#options' => array(
      'f' => t('No'),
      't' => t('Yes'),
    ),
  );
  $form['advanced']['theme_config_js'] = array(
    '#type' => 'radios',
    '#title' => t('Load !ckeditor_config_js from the theme path', array(
      '!ckeditor_config_js' => '<code>ckeditor.config.js</code>',
    )),
    '#default_value' => !empty($profile->settings['theme_config_js']) ? $profile->settings['theme_config_js'] : 'f',
    '#options' => array(
      't' => t('Yes'),
      'f' => t('No'),
    ),
    '#description' => t('When enabled, the editor will try to load the !ckeditor_config_js file from the theme directory.', array(
      '!ckeditor_config_js' => '<code>ckeditor.config.js</code>',
    )),
  );
  $form['advanced']['js_conf'] = array(
    '#type' => 'textarea',
    '#title' => t('Custom JavaScript configuration'),
    '#default_value' => !empty($profile->settings['js_conf']) ? $profile->settings['js_conf'] : "",
    '#cols' => 60,
    '#rows' => 5,
    '#description' => t('In order to change CKEditor configuration globally, you should modify the !ckeditor_config configuration file. Sometimes it is required to change the CKEditor configuration for a single profile only. Use this box to define settings that are unique for this profile. Available options are listed in the !docs. Add the following code snippet to change the fonts available in the CKEditor <strong>Font</strong> and <strong>Size</strong> drop-down lists: <pre>@code</pre><strong>Warning</strong>: If you make a mistake here, CKEditor may not load correctly.', array(
      '!ckeditor_config' => '<code>' . drupal_get_path('module', 'ckeditor') . "/ckeditor.config.js</code>",
      '!docs' => l(t('CKEditor documentation'), 'http://docs.cksource.com/ckeditor_api/symbols/CKEDITOR.config.html'),
      '@code' => "config.fontSize_sizes = '16/16px;24/24px;48/48px;';\nconfig.font_names = 'Arial;Times New Roman;Verdana';",
    )),
    '#wysiwyg' => FALSE,
  );
  $form['submit'] = array(
    '#type' => 'submit',
    '#value' => t('Save'),
  );
  return $form;
}