Projet

Général

Profil

Paste
Télécharger (83,1 ko) Statistiques
| Branche: | Révision:

root / drupal7 / sites / all / modules / ckeditor / includes / ckeditor.admin.inc @ 2e0f6994

1
<?php
2

    
3
/**
4
 * CKEditor - The text editor for the Internet - http://ckeditor.com
5
 * Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.
6
 *
7
 * == BEGIN LICENSE ==
8
 *
9
 * Licensed under the terms of any of the following licenses of 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
 * CKEditor Module for Drupal 7.x
25
 *
26
 * This module allows Drupal to replace textarea fields with CKEditor.
27
 *
28
 * CKEditor is an online rich text editor that can be embedded inside web pages.
29
 * It is a WYSIWYG (What You See Is What You Get) editor which means that the
30
 * text edited in it looks as similar as possible to the results end users will
31
 * see after the document gets published. It brings to the Web popular editing
32
 * features found in desktop word processors such as Microsoft Word and
33
 * OpenOffice.org Writer. CKEditor is truly lightweight and does not require any
34
 * kind of installation on the client computer.
35
 */
36

    
37
/**
38
 * Main administrative page
39
 */
40
function ckeditor_admin_main() {
41
  global $base_url;
42
  module_load_include('inc', 'ckeditor', 'includes/ckeditor.lib');
43
  $editor_path = ckeditor_path('local');
44
  $ckconfig_file = $editor_path . '/config.js';
45

    
46
  //check if CKEditor plugin is installed
47
  if ($editor_path != '<URL>' && !_ckeditor_requirements_isinstalled()) {
48
    drupal_set_message(t(
49
            'Checking for !filename or !file.', array(
50
          '!filename' => '<code>' . $ckconfig_file . '</code>',
51
          '!file' => '<code>sites/all/libraries/ckeditor/ckeditor.js</code>'
52
            )
53
        ));
54
    drupal_set_message(t(
55
            'The CKEditor component is not installed correctly. Please go to the !ckeditorlink in order to download the latest version. After that you must extract the files to the !ckeditorpath or !librarypath directory and make sure that the !ckeditorfile or !ckeditorlibrary file exists. Refer to the !readme file for more information.', array(
56
          '!ckeditorlink' => l(t('CKEditor homepage'), 'http://ckeditor.com/download'),
57
          '!readme' => l(t('README.txt'), $base_url . '/' . drupal_get_path('module', 'ckeditor') . '/README.txt', array('absolute' => TRUE)),
58
          '!ckeditorpath' => '<code>sites/all/modules/ckeditor/ckeditor</code>',
59
          '!ckeditorfile' => '<code>sites/all/modules/ckeditor/ckeditor/ckeditor.js</code>',
60
          '!ckeditorlibrary' => '<code>sites/all/libraries/ckeditor/ckeditor.js</code>',
61
          '!librarypath' => '<code>sites/all/libraries/ckeditor</code>'
62
            )
63
        ), 'error');
64
    drupal_set_message(t(
65
            'If you have CKEditor already installed, edit the <strong>!editg</strong> and update the CKEditor path.', array(
66
          '!editg' => l(t('CKEditor Global Profile'), 'admin/config/content/ckeditor/editg')
67
            )
68
        ), 'warning');
69

    
70
    return '';
71
  }
72

    
73
  if (module_exists('wysiwyg')) {
74
    drupal_set_message(t(
75
            'The WYSIWYG module was detected. Using both modules at the same time may cause problems. It is recommended to turn the WYSIWYG module off (!wysiwygdisablelink).', array(
76
          '!wysiwygdisablelink' => l(t('click here to disable'), 'ckeditor/disable/wysiwyg/' . drupal_get_token('ckeditorDisableWysiwyg'))
77
            )
78
        ), 'warning');
79
  }
80

    
81
  //find profile other than Global
82
  $result = db_select('ckeditor_settings', 's')->fields('s', array('name'))->condition('name', 'CKEditor Global Profile', '<>')->range(0, 1)->execute()->fetchAssoc();
83
  if (!$result) {
84
    drupal_set_message(t('No CKEditor profiles found. Right now nobody is able to use CKEditor. Create a new profile below.'), 'error');
85
  }
86

    
87
  return ckeditor_profile_overview();
88
}
89

    
90
/**
91
 * Controller for CKEditor profiles.
92
 */
93
function ckeditor_profile_overview() {
94
  $output = '';
95
  $skins = ckeditor_load_skin_options();
96
  $global_profile = ckeditor_profile_load('CKEditor Global Profile');
97
  if (isset($global_profile->settings['skin']) && !array_key_exists($global_profile->settings['skin'], $skins)) {
98
    drupal_set_message(t('The <em>CKEditor Global Profile</em> profile is using %skin skin which cannot be found. Please <a href="@profile_settings">update your settings</a>.', array('%skin' => $global_profile->settings['skin'], '@profile_settings' => url('admin/config/content/ckeditor/editg'))), 'warning');
99
  }
100
  $profiles = ckeditor_profile_load();
101
  if ($profiles) {
102
    // @todo The following variable is never used. Remove it?
103
    $access_ckeditor_roles = user_roles(FALSE, 'access ckeditor');
104
    $header = array(t('Profile'), t('Input format'), t('Operations'));
105
    $disabled_plugins = array();
106
    foreach ($profiles as $p) {
107
      if ($p->name !== "CKEditor Global Profile") {
108
        $rows[] = array(
109
          array('data' => $p->name, 'valign' => 'top'),
110
          array('data' => implode("<br />\n", $p->input_formats)),
111
          array(
112
            'data' =>
113
            l(t('edit'), 'admin/config/content/ckeditor/edit/' . urlencode($p->name)) . ' ' .
114
            l(t('clone'), 'admin/config/content/ckeditor/clone/' . urlencode($p->name)) . ' ' .
115
            l(t('delete'), 'admin/config/content/ckeditor/delete/' . urlencode($p->name)),
116
            'valign' => 'top'
117
          )
118
        );
119
      }
120
    }
121

    
122
    if (count($disabled_plugins) > 0) {
123
      $msg = t("The following plugins could not be found and were automatically disabled in CKEditor profiles:");
124
      foreach ($disabled_plugins as $profile_name => $profile_plugins) {
125
        $msg .= "<br/><br/>";
126
        $msg .= t("<b>Profile</b>: %profile_name", array("%profile_name" => $profile_name));
127
        $msg .= "<br/>";
128
        $msg .= t("<b>Plugins</b>: %profile_plugins", array("%profile_plugins" => implode(', ', $profile_plugins)));
129
      }
130
      drupal_set_message($msg, 'warning');
131
    }
132

    
133
    $output .= '<h3>' . t('Profiles') . '</h3>';
134
    $output .= theme('table', array("header" => $header, "rows" => $rows));
135
    $output .= '<p>' . l(t('Create a new profile'), 'admin/config/content/ckeditor/add') . '</p>';
136
  }
137
  else {
138
    drupal_set_message(t(
139
            'No profiles found. Click here to !create.', array(
140
          '!create' => l(t('create a new profile'), 'admin/config/content/ckeditor/add')
141
            )
142
        ), 'warning');
143
  }
144

    
145
  $rows = array();
146
  if (!isset($profiles['CKEditor Global Profile'])) {
147
    drupal_set_message(t(
148
            'The global profile can not be found. Click here to !create.', array(
149
          '!create' => l(t('create the global profile'), 'admin/config/content/ckeditor/addg')
150
            )
151
        ), 'warning');
152
  }
153
  else {
154
    $output .= "<h3>" . t("Global settings") . "</h3>";
155
    $rows[] = array(
156
      array('data' => t('CKEditor Global Profile')),
157
      array('data' => l(t('edit'), 'admin/config/content/ckeditor/editg'), 'valign' => 'top')
158
    );
159
    $output .= theme('table', array("header" => array(t('Profile'), t('Operations')), "rows" => $rows));
160
  }
161
  return $output;
162
}
163

    
164
/**
165
 * Form builder for a global profile
166
 */
167
function ckeditor_admin_global_profile_form($form, $form_state, $mode = 'add') {
168
  module_load_include('inc', 'ckeditor', 'includes/ckeditor.lib');
169
  if ($mode == 'edit') {
170
    $profile = ckeditor_profile_load('CKEditor Global Profile');
171

    
172
    $form['_profile'] = array(
173
      '#type' => 'value',
174
      '#value' => $profile,
175
    );
176
  }
177
  else {
178
    $profile = new stdClass();
179
  }
180

    
181
  if ($mode == 'add') {
182
    $data = ckeditor_profile_load('CKEditor Global Profile');
183
    if (!empty($data)) {
184
      drupal_set_message(t('The global profile already exists. Only one global profile is allowed.'), 'error');
185
      drupal_not_found();
186
    }
187

    
188
    $btn = t('Create a global profile');
189
  }
190
  else {
191
    $btn = t('Update the global profile');
192
  }
193

    
194
  $orig_formats = filter_formats();
195
  $formats = array();
196
  foreach ($orig_formats AS $format) {
197
    $formats[$format->format] = $format->name;
198
  }
199

    
200
  $drupal_base_path = ckeditor_base_path('relative');
201
  $drupal_library_path = ckeditor_library_path('relative');
202
  $module_drupal_path = ckeditor_module_path('relative');
203
  $skin_options = ckeditor_load_skin_options();
204

    
205
  $form['appearance'] = array(
206
    '#type' => 'fieldset',
207
    '#title' => t('Editor appearance'),
208
    '#collapsible' => TRUE,
209
    '#collapsed' => FALSE,
210
  );
211

    
212
  //if skin is not set or not exists select default skin (moono or skin) or first on the skin list
213
  if (empty($profile->settings['skin']) || (!empty($profile->settings['skin']) && !array_key_exists($profile->settings['skin'], $skin_options))) {
214
    $profile->settings['skin'] = ckeditor_default_skin();
215
  }
216

    
217
  $form['appearance']['skin'] = array(
218
    '#type' => 'select',
219
    '#title' => t('Skin'),
220
    '#default_value' => $profile->settings['skin'],
221
    '#options' => $skin_options,
222
    '#description' => t('Choose a CKEditor skin.'),
223
  );
224

    
225
  $form['ckeditor_advanced_settings'] = array(
226
    '#type' => 'fieldset',
227
    '#title' => t('Advanced settings'),
228
    '#collapsible' => TRUE,
229
    '#collapsed' => FALSE,
230
  );
231

    
232
  $current_path = ckeditor_path('relative');
233
  if ($current_path == '<URL>') {
234
    $current_path = ckeditor_path('url');
235
  }
236
  $form['ckeditor_advanced_settings']['ckeditor_path'] = array(
237
    '#type' => 'textfield',
238
    '#title' => t('Path to CKEditor'),
239
    '#default_value' => !empty($profile->settings['ckeditor_path']) ? $profile->settings['ckeditor_path'] : '%m/ckeditor',
240
    '#size' => 40,
241
    '#maxlength' => 128,
242
    '#description' => t(
243
        'The path to CKEditor (the WYSIWYG rich text editor downloaded from !ckeditorcom). Provide a path relative to the document root, unless CKEditor is located on an external URL. In such case enter the full URL to a folder with CKEditor.<br />The simplest way to have the editor running is to use CDN, to use it set: !cdn', array(
244
      '!ckeditorcom' => l(t('ckeditor.com'), 'http://ckeditor.com/download'),
245
      '!cdn' => '<strong>//cdn.ckeditor.com/' . CKEDITOR_LATEST . '/full-all</strong>'
246
        )
247
    ) .
248
    '<br /><br /> ' .
249
    t('Available placeholders:!b &ndash; path of the Drupal installation (!base) !m &ndash; path where the CKEditor module is stored (!module).!l &ndash; path to the libraries directory (!library).', array(
250
      '!b' => '<br /><code>%b</code>',
251
      '!m' => '<br /><code>%m</code>',
252
      '!l' => '<br /><code>%l</code>',
253
      '!base' => '<code>' . $drupal_base_path . '</code>',
254
      '!module' => '<code>' . $module_drupal_path . '</code>',
255
      '!library' => '<code>' . $drupal_library_path . '</code>',
256
        )
257
    ) .
258
    '<br /> ' .
259
    t('Current path: !path', array(
260
      '!path' => '<code>' . $current_path . '</code>'
261
        )
262
    ),
263
    '#required' => TRUE
264
  );
265

    
266
  $local_path = ckeditor_path('local');
267
  if ($local_path == '<URL>') {
268
    $local_path = t('CKEditor is loaded from URL. Local path is not available.');
269
  }
270
  $form['ckeditor_advanced_settings']['ckeditor_local_path'] = array(
271
    '#type' => 'textfield',
272
    '#title' => t('Local path to CKEditor'),
273
    '#default_value' => isset($profile->settings['ckeditor_local_path']) ? $profile->settings['ckeditor_local_path'] : '',
274
    '#size' => 40,
275
    '#maxlength' => 128,
276
    '#description' => t(
277
        'The path to the local directory (on the server) that points to the path defined above. Enter either an absolute server path or a path relative to the !indexphp file. If left empty, the CKEditor module will try to find the right path.', array(
278
      '!indexphp' => '<code>index.php</code>'
279
        )
280
    ) .
281
    '<br /> ' .
282
    t('Current path: !path', array(
283
      '!path' => '<code>' . $local_path . '</code>'
284
        )
285
    )
286
  );
287

    
288
  $form['ckeditor_advanced_settings']['ckeditor_plugins_path'] = array(
289
    '#type' => 'textfield',
290
    '#title' => t('Path to the CKEditor plugins directory'),
291
    '#default_value' => !empty($profile->settings['ckeditor_plugins_path']) ? $profile->settings['ckeditor_plugins_path'] : '%m/plugins',
292
    '#size' => 40,
293
    '#maxlength' => 128,
294
    '#description' => t('Path to the CKEditor plugins directory relative to the document root.') .
295
    '<br />' .
296
    t('Available placeholders:!b &ndash; path of the Drupal installation (!base) !m &ndash; the base URL path where the CKEditor module is stored (!module).!l &ndash; the base URL path to the libraries directory (!library)', array(
297
      '!b' => '<br /><code>%b</code>',
298
      '!m' => '<br /><code>%m</code>',
299
      '!l' => '<br /><code>%l</code>',
300
      '!base' => '<code>' . $drupal_base_path . '</code>',
301
      '!module' => '<code>' . $module_drupal_path . '</code>',
302
      '!library' => '<code>' . $drupal_library_path . '</code>',
303
        )
304
    ) .
305
    '<br /> ' .
306
    t('Current path: !path', array(
307
      '!path' => '<code>' . ckeditor_plugins_path('relative') . '</code>'
308
        )
309
    )
310
  );
311

    
312
  $form['ckeditor_advanced_settings']['ckeditor_plugins_local_path'] = array(
313
    '#type' => 'textfield',
314
    '#title' => t('Local path to the CKEditor plugins directory'),
315
    '#default_value' => isset($profile->settings['ckeditor_plugins_local_path']) ? $profile->settings['ckeditor_plugins_local_path'] : '',
316
    '#size' => 40,
317
    '#maxlength' => 128,
318
    '#description' => t(
319
        'The path to the local directory (on the server) that points to the path defined above. Enter either an absolute server path or a path relative to the !indexphp file. If left empty, the CKEditor module will try to find the right path.', array(
320
      '!indexphp' => '<code>index.php</code>'
321
        )
322
    ) .
323
    '<br /> ' .
324
    t('Current path: !path', array(
325
      '!path' => '<code>' . ckeditor_plugins_path('local') . '</code>'
326
        )
327
    )
328
  );
329

    
330
  $form['ckeditor_advanced_settings']['ckfinder_path'] = array(
331
    '#type' => 'textfield',
332
    '#title' => t('Path to CKFinder'),
333
    '#default_value' => !empty($profile->settings['ckfinder_path']) ? $profile->settings['ckfinder_path'] : '%m/ckfinder',
334
    '#size' => 40,
335
    '#maxlength' => 128,
336
    '#description' => t(
337
        'The path to CKFinder (AJAX based file manager downloaded from !ckfindercom) relative to the document root.', array(
338
      '!ckfindercom' => l(t('ckfinder.com'), 'http://cksource.com/ckfinder')
339
        )
340
    ) .
341
    '<br />' .
342
    t('Available placeholders:!b &ndash; path of the Drupal installation (!base) !m &ndash; path where the CKEditor module is stored (!module).!l &ndash; path to the libraries directory (!library)', array(
343
      '!b' => '<br /><code>%b</code>',
344
      '!m' => '<br /><code>%m</code>',
345
      '!l' => '<br /><code>%l</code>',
346
      '!base' => '<code>' . $drupal_base_path . '</code>',
347
      '!module' => '<code>' . $module_drupal_path . '</code>',
348
      '!library' => '<code>' . $drupal_library_path . '</code>'
349
        )
350
    ) .
351
    '<br /> ' .
352
    t('Current path: !path', array(
353
      '!path' => '<code>' . ckfinder_path('relative') . '</code>'
354
        )
355
    )
356
  );
357

    
358
  $form['ckeditor_advanced_settings']['ckfinder_local_path'] = array(
359
    '#type' => 'textfield',
360
    '#title' => t('Local path to CKFinder'),
361
    '#default_value' => isset($profile->settings['ckfinder_local_path']) ? $profile->settings['ckfinder_local_path'] : '',
362
    '#size' => 40,
363
    '#maxlength' => 128,
364
    '#description' => t(
365
        'The path to the local directory (on the server) that points to the path defined above. Enter either an absolute server path or a path relative to the !indexphp file. If left empty, the CKEditor module will try to find the right path.', array(
366
      '!indexphp' => '<code>index.php</code>'
367
        )
368
    ) .
369
    '<br /> ' .
370
    t('Current path: !path', array(
371
      '!path' => '<code>' . ckfinder_path('local') . '</code>'
372
        )
373
    )
374
  );
375

    
376
  //@todo DOWNLOAD API
377
  if (variable_get('file_default_scheme', '') == 'private') {
378
    $form['ckeditor_advanced_settings']['ckeditor_allow_download_private_files'] = array(
379
      '#type' => 'checkbox',
380
      '#title' => t('Enable access to files located in the private folder'),
381
      '#default_value' => !empty($profile->settings['ckeditor_allow_download_private_files']),
382
      '#return_value' => 't',
383
      '#description' => t(
384
          '<strong>Use this option with care.</strong> If checked, CKEditor will allow anyone knowing the URL to view a file located inside of the private path (!private_path), but only if there is no information about the file in the Drupal database. If the path below is specified, anyone will have access only to that location.', array(
385
        '!private_path' => '<code>' . variable_get('file_private_path', '') . '</code>'
386
          )
387
      ),
388
      '#required' => FALSE
389
    );
390
    $current_private_dir = !empty($profile->settings['private_dir']) ? $profile->settings['private_dir'] : '';
391
    $form['ckeditor_advanced_settings']['private_dir'] = array(
392
      '#type' => 'textfield',
393
      '#title' => t('Location of files uploaded with CKEditor to the private folder'),
394
      '#default_value' => !empty($profile->settings['private_dir']) ? $profile->settings['private_dir'] : '',
395
      '#size' => 40,
396
      '#maxlength' => 255,
397
      '#description' => t('The path relative to the location of the private directory where CKEditor should store uploaded files.') .
398
      '<br />' .
399
      t('Available wildcard characters:!u &ndash; User ID.!n &ndash; Username', array(
400
        '!u' => '<br/><code>%u</code>',
401
        '!n' => '<br /><code>%n</code>'
402
          )
403
      ) .
404
      '<br />' .
405
      t('System path to the private folder is: !system_path.', array(
406
        '!system_path' => '<code>' . realpath(variable_get('file_private_path', conf_path() . '/files')) . DIRECTORY_SEPARATOR . '</code>'
407
          )
408
      )
409
    );
410
  }
411

    
412
  if (function_exists('linktocontent_node_menu') && function_exists('pathfilter_filter')) {
413
    $form['ckeditor_advanced_settings']['linktoc'] = array(
414
      '#type' => 'select',
415
      '#options' => array('p' => t('Link to paths only'), 'n' => t('Link using internal: links'), 'pn' => t('Allow the user to select between paths and internal links')),
416
      '#title' => t('Path Filter & Link To Content integration'),
417
      '#default_value' => empty($profile->settings['linktoc']) ? 'p' : $profile->settings['linktoc'],
418
      '#description' => t(
419
          'With the !plink extension it is possible to use internal: links. By default the !link extension is linking to nodes using paths.', array(
420
        '!plink' => l(t('Path Filter'), 'http://drupal.org/project/pathfilter'),
421
        '!link' => l(t('Link To Content'), 'http://drupal.org/project/linktocontent')
422
          )
423
      )
424
    );
425
  }
426

    
427
  $form['ckeditor_advanced_settings']['ckeditor_aggregate'] = array(
428
    '#type' => 'radios',
429
    '#title' => t('Aggregate <code>ckeditor.js</code>'),
430
    '#default_value' => !empty($profile->settings['ckeditor_aggregate']) ? $profile->settings['ckeditor_aggregate'] : 'f',
431
    '#options' => array(
432
      't' => t('Enabled'),
433
      'f' => t('Disabled')
434
    ),
435
    '#description' => t('When enabled, <code>ckeditor.js</code> will be aggregated if JavaScript aggregation is enabled. <strong>Not recommended</strong>.'),
436
  );
437

    
438
  $form['ckeditor_advanced_settings']['toolbar_wizard'] = array(
439
    '#type' => 'radios',
440
    '#title' => t('Use toolbar Drag&Drop feature'),
441
    '#default_value' => !empty($profile->settings['toolbar_wizard']) ? $profile->settings['toolbar_wizard'] : 't',
442
    '#options' => array(
443
      't' => t('Enabled'),
444
      'f' => t('Disabled')
445
    ),
446
    '#description' => t('When enabled, the toolbar can be built by using the drag-and-drop feature. Otherwise you will need to enter the toolbar configuration manually to the text box.'),
447
  );
448

    
449
  $form['submit'] = array(
450
    '#type' => 'submit',
451
    '#value' => $btn
452
  );
453

    
454
  return $form;
455
}
456

    
457
/**
458
 * Form validation for a global profile
459
 */
460
function ckeditor_admin_global_profile_form_validate($form, &$form_state) {
461

    
462
}
463

    
464
/**
465
 * Submit form for a global profile
466
 */
467
function ckeditor_admin_global_profile_form_submit($form, &$form_state) {
468
  module_load_include('inc', 'ckeditor', 'includes/ckeditor.lib');
469
  $edit = & $form_state['values'];
470
  $edit['name'] = 'CKEditor Global Profile';
471

    
472
  if (isset($edit['_profile'])) {
473
    ckeditor_profile_delete($edit['_profile']->name);
474
  }
475

    
476
  //strip whitespaces
477
  if (empty($edit['ckeditor_local_path'])) {
478
    $edit['ckeditor_local_path'] = '';
479
  }
480
  else {
481
    $edit['ckeditor_local_path'] = trim($edit['ckeditor_local_path']);
482
  }
483

    
484
  //strip slash from the end
485
  if (empty($edit['ckeditor_path'])) {
486
    $edit['ckeditor_path'] = '';
487
  }
488
  $edit['ckeditor_path'] = trim(rtrim($edit['ckeditor_path'], "/"));
489
  if ($edit['ckeditor_path'] && 0 !== strpos($edit['ckeditor_path'], "/") && 0 !== strpos($edit['ckeditor_path'], "%") && !preg_match("|^http(s)?://|i", $edit['ckeditor_path'])) {
490
    //ensure that slash is at the beginning
491
    $edit['ckeditor_path'] = "/" . $edit['ckeditor_path'];
492
  }
493
  //no slash at the end
494
  $edit['ckeditor_local_path'] = trim(rtrim($edit['ckeditor_local_path'], "/"));
495

    
496
  //strip whitespaces
497
  if (empty($edit['ckeditor_plugins_local_path'])) {
498
    $edit['ckeditor_plugins_local_path'] = '';
499
  }
500
  else {
501
    $edit['ckeditor_plugins_local_path'] = trim($edit['ckeditor_plugins_local_path']);
502
  }
503

    
504
  //strip slash from the end
505
  if (empty($edit['ckeditor_plugins_path'])) {
506
    $edit['ckeditor_plugins_path'] = '';
507
  }
508
  $edit['ckeditor_plugins_path'] = trim(rtrim($edit['ckeditor_plugins_path'], "/"));
509
  if ($edit['ckeditor_plugins_path'] && 0 !== strpos($edit['ckeditor_plugins_path'], "/") && 0 !== strpos($edit['ckeditor_plugins_path'], "%")) {
510
    //ensure that slash is at the beginning
511
    $edit['ckeditor_plugins_path'] = "/" . $edit['ckeditor_plugins_path'];
512
  }
513
  //no slash at the end
514
  $edit['ckeditor_plugins_path'] = trim(rtrim($edit['ckeditor_plugins_path'], "/"));
515

    
516
  //strip slash from the end
517
  if (empty($edit['ckfinder_path'])) {
518
    $edit['ckfinder_path'] = '';
519
  }
520
  $edit['ckfinder_path'] = trim(rtrim($edit['ckfinder_path'], "/"));
521
  if ($edit['ckfinder_path'] && 0 !== strpos($edit['ckfinder_path'], "/") && 0 !== strpos($edit['ckfinder_path'], "%")) {
522
    //ensure that slash is at the beginning
523
    $edit['ckfinder_path'] = "/" . $edit['ckfinder_path'];
524
  }
525

    
526
  //no slash at the end
527
  $edit['ckfinder_local_path'] = trim(rtrim($edit['ckfinder_local_path'], "/"));
528

    
529
  $settings = ckeditor_admin_values_to_settings($edit);
530
  db_insert('ckeditor_settings')
531
      ->fields(array(
532
        "name" => $edit["name"],
533
        "settings" => $settings
534
      ))
535
      ->execute();
536

    
537
  drupal_set_message(t('The CKEditor global profile was saved.'));
538
  $form_state['redirect'] = 'admin/config/content/ckeditor';
539
}
540

    
541
/**
542
 * Form builder for a profile
543
 */
544
function ckeditor_admin_profile_form($form, $form_state, $task, $profile = NULL) {
545
  global $theme;
546

    
547
  if ($profile != NULL) {
548
    $form['_profile'] = array(
549
      '#type' => 'value',
550
      '#value' => $profile,
551
    );
552
  }
553
  else {
554
    $profile = new stdClass();
555
  }
556

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

    
559
  $editor_path = ckeditor_path('relative');
560
  $editor_local_path = ckeditor_path('local');
561
  $editor_url_path = ckeditor_path('url');
562
  $module_drupal_path = ckeditor_module_path('relative');
563
  $module_drupal_url_path = ckeditor_module_path('url');
564

    
565
  drupal_add_js(array('ckeditor_version' => ckeditor_get_version()), 'setting');
566

    
567
  $lang_options = ckeditor_load_lang_options();
568

    
569
  // Attach the administration CSS.
570
  $form['#attached'] = array(
571
    'css' => array(
572
      drupal_get_path('module', 'ckeditor') . '/css/ckeditor.admin.css',
573
    ),
574
  );
575

    
576
  $form['basic'] = array(
577
    '#type' => 'fieldset',
578
    '#title' => t('Basic setup'),
579
    '#collapsible' => TRUE,
580
    '#collapsed' => TRUE
581
  );
582

    
583
  switch ($task) {
584
    case 'clone':
585
      //load all profiles to check their names
586
      $profiles = ckeditor_profile_load();
587
      $oldname = $profile->name;
588
      $maxsize = 128;   //default max name length
589

    
590
      $res = array();
591
      $pat = "/^(.*?)_([0-9]+)$/";
592
      if (preg_match($pat, $oldname, $res)) {     // oldname like 'name_nr'
593
        $name = $res[1];
594
        $num = $res[2] + 1;
595
      }
596
      else {
597
        $name = $oldname;
598
        $num = 2;
599
      }
600

    
601
      $newname = substr($name, 0, $maxsize - 3) . '_' . $num;   // +limit
602
      while (isset($profiles[$newname])) {            //find next free number
603
        $num++;
604
        $newname = substr($name, 0, $maxsize - 3) . '_' . $num;
605
      }
606
      break;
607
    case 'edit':
608
      $newname = $profile->name;
609
      break;
610
  }
611

    
612
  $global_profile = ckeditor_profile_load('CKEditor Global Profile');
613
  $toolbar_wizard = !empty($global_profile->settings['toolbar_wizard']) ? $global_profile->settings['toolbar_wizard'] : 't';
614
  drupal_add_js(array('ckeditor_toolbar_wizard' => $toolbar_wizard), 'setting');
615

    
616
  $form['basic']['name'] = array(
617
    '#type' => 'textfield',
618
    '#title' => t('Profile name'),
619
    '#default_value' => !empty($profile->name) ? $newname : '',
620
    '#size' => 40,
621
    '#maxlength' => 128,
622
    '#description' => t('Enter a name for this profile. This name is only visible within the CKEditor administration page.'),
623
    '#required' => TRUE
624
  );
625

    
626
  $orig_formats = filter_formats();
627

    
628
  if ($task == 'edit' && !empty($profile->name)) {
629
    $used_formats = db_select('ckeditor_input_format', 'f')->fields('f', array("format"))->distinct()->condition("f.name", array($profile->name), 'NOT IN')->execute()->fetchAllAssoc('format');
630
  }
631
  else {
632
    $profile->input_formats = array();
633
    $used_formats = db_select('ckeditor_input_format', 'f')->fields('f', array("format"))->distinct()->execute()->fetchAllAssoc('format');
634
  }
635

    
636
  $formats = array();
637
  $input_format_config_links = array();
638
  foreach ($orig_formats AS $format) {
639
    if (($task == 'edit' && !empty($profile->input_formats) && array_key_exists($format->format, $profile->input_formats)) || !array_key_exists($format->format, $used_formats)) {
640
      $formats[$format->format] = $format->name;
641
      $input_format_config_links[$format->format] = array("name" => $format->name, "config_url" => url("admin/config/content/formats/" . $format->format));
642
    }
643
  }
644

    
645
  $form['basic']['input_formats'] = array(
646
    '#id' => 'input-formats',
647
    '#type' => 'checkboxes',
648
    '#title' => t('Text formats'),
649
    '#default_value' => !empty($profile->input_formats) ? array_keys((array) $profile->input_formats) : array(),
650
    '#options' => $formats,
651
    '#description' => t('Choose the text formats where you want to load CKEditor.')
652
  );
653

    
654
  $form['security'] = array(
655
    '#type' => 'fieldset',
656
    '#title' => t('Security'),
657
    '#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>',
658
    '#collapsible' => TRUE,
659
    '#collapsed' => TRUE
660
  );
661

    
662
  $form['security']['filters'] = array(
663
    '#id' => 'security-filters',
664
    '#type' => 'container'
665
  );
666

    
667
  $form['security']['filters']['__header'] = array(
668
    '#type' => 'item',
669
    '#title' => t('Security filters'),
670
    '#description' => t(
671
      'Below is a list of security filters along with their status for each text format.<br /><br />The following statuses are available: !img_enabled - the filter is configured for a given text format and will be run on the content during the filtering process. !img_disabled - the filter is disabled for a given text format and will not be run on the content during the filtering process.<br /><br />In order to modify the security filters settings for each of the text formats, you need to visit the text format configuration sections as listed below: !elem_format_config', array(
672
      '!img_enabled' => '</br><img src="' . $module_drupal_path . '/images/tick.png"/>',
673
      '!img_disabled' => '</br><img src="' . $module_drupal_path . '/images/delete.png"/>',
674
      '!elem_format_config' => '<ul class="text-formats-config"></ul>'
675
        )
676
    ),
677
    '#weight' => -10
678
  );
679

    
680
  //get text formats filters
681
  $input_format_filters = array();
682
  foreach ($formats AS $key => $value) {
683
    $input_format_filters[$key] = array();
684
    $filters = filter_list_format($key);
685
    foreach ($filters as $filter_name => $filter_settings) {
686
      if ($filter_settings->status == 1) {
687
        $input_format_filters[$key][$filter_name] = TRUE;
688
      }
689
    }
690
  }
691
  drupal_add_js(array('text_format_filters' => $input_format_filters, 'text_formats_config_links' => $input_format_config_links), 'setting');
692

    
693
  $security_filters = ckeditor_security_filters();
694
  _ckeditor_admin_profile_form_security_filters($form, $profile, $security_filters);
695

    
696
  $form['security']['ss'] = array(
697
    '#type' => 'radios',
698
    '#title' => t('Security settings'),
699
    '#default_value' => isset($profile->settings['ss']) ? $profile->settings['ss'] : '2',
700
    '#options' => array(
701
      '2' => t('Always run security filters for CKEditor.'),
702
      '1' => t('Run security filters only when CKEditor is set to start automatically.'),
703
    ),
704
    '#description' => t('There are two ways of starting CKEditor: automatically and manually (via toggle). 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. Choose this option only if you can detect various attacks (mainly XSS) by yourself just by looking at the HTML code.'),
705
  );
706

    
707
  $form['appearance'] = array(
708
    '#type' => 'fieldset',
709
    '#title' => t('Editor appearance'),
710
    '#collapsible' => TRUE,
711
    '#collapsed' => TRUE,
712
  );
713

    
714
  $ui_colors = array(
715
    "default" => t('CKEditor default'),
716
    "custom" => t('Select manually')
717
  );
718
  if (function_exists('color_get_palette')) {
719
    // apparently $theme is not initialized (?)
720
    if (empty($theme)) {
721
      init_theme();
722
    }
723
    $palette = @color_get_palette($theme, FALSE); //[#652274]
724
    $color_palette['default'] = '#D3D3D3';
725
    if (!empty($palette)) {
726
      if (!empty($palette['base'])) {
727
        $color_palette['color_base'] = $palette['base'];
728
        $ui_colors["color_base"] = t('Color module: base');
729
      }
730
      if (!empty($palette['top'])) {
731
        $color_palette['color_top'] = $palette['top'];
732
        $ui_colors["color_top"] = t('Color module: top');
733
      }
734
      if (!empty($palette['bottom'])) {
735
        $color_palette['color_bottom'] = $palette['bottom'];
736
        $ui_colors["color_bottom"] = t('Color module: bottom');
737
      }
738
    }
739
    drupal_add_js(array('ckeditor_uicolor' => $color_palette), 'setting');
740
  }
741

    
742
  if ($editor_path == '<URL>') {
743
    drupal_add_js($editor_url_path . '/ckeditor.js', 'external');
744
  }
745
  else {
746
    drupal_add_js('window.CKEDITOR_BASEPATH = "' . $editor_path . '/"', array('type' => 'inline', 'weight' => -100));
747
    drupal_add_js($editor_url_path . '/ckeditor.js', array('type' => 'file', 'preprocess' => FALSE));
748
  }
749
  drupal_add_js($module_drupal_url_path . '/ckeditor.config.js', 'file');
750
  drupal_add_js($module_drupal_url_path . '/includes/ckeditor.admin.js', 'file');
751

    
752
  if ($toolbar_wizard == 't') {
753
    drupal_add_library('system', 'ui.widget');
754
    drupal_add_library('system', 'ui.sortable');
755
    drupal_add_js($module_drupal_url_path . '/includes/jqueryUI/sort.js', 'file');
756
  }
757

    
758
  $form['appearance']['toolbar'] = array(
759
    '#type' => 'textarea',
760
    '#title' => t('Toolbar'),
761
    '#default_value' => !empty($profile->settings['toolbar']) ? $profile->settings['toolbar'] : '',
762
    '#description' => t('Load sample toolbar: !toolbars', array("!toolbars" => '<a href="#" id="cke_toolbar_DrupalBasic" class="cke_load_toolbar">' . t('Basic') . '</a> | <a href="#" id="cke_toolbar_DrupalAdvanced" class="cke_load_toolbar">' . t('Advanced') . '</a> | <a href="#" id="cke_toolbar_DrupalFull" class="cke_load_toolbar">' . t('Full') . '</a>')),
763
    '#wysiwyg' => FALSE,
764
    '#rows' => 15
765
  );
766

    
767
  if ($toolbar_wizard == 't') {
768
    $form['appearance']['toolbar_wizzard_used'] = array(
769
      '#markup' => '<div>' . t('Current toolbar') . '</div><div class="sortableList" id="groupLayout"></div><br/>',
770
      '#description' => t('Currently used buttons'),
771
    );
772

    
773
    drupal_add_js(array('cke_toolbar_buttons_all' => ckeditor_toolbar_buttons_all()), 'setting');
774

    
775
    $form['appearance']['toolbar_wizzard_all'] = array(
776
      '#markup' => '<div>' . t('Available buttons') . '</div><div id="allButtons" class="sortableList"></div><br/>',
777
      '#description' => t('All available buttons'),
778
    );
779
  }
780

    
781
  $form['appearance']['expand'] = array(
782
    '#type' => 'radios',
783
    '#title' => t('Toolbar state on startup'),
784
    '#default_value' => !empty($profile->settings['expand']) ? $profile->settings['expand'] : 't',
785
    '#options' => array(
786
      't' => t('Expanded'),
787
      'f' => t('Collapsed')
788
    ),
789
    '#description' => t('The toolbar will start in an expanded or collapsed state.'),
790
  );
791

    
792
  $form['appearance']['default'] = array(
793
    '#type' => 'radios',
794
    '#title' => t('Default editor state'),
795
    '#default_value' => !empty($profile->settings['default']) ? $profile->settings['default'] : 't',
796
    '#options' => array(
797
      't' => t('Enabled'),
798
      'f' => t('Disabled')
799
    ),
800
    '#description' => t('Default editor state. If disabled, the rich text editor may still be enabled by using toggle.'),
801
  );
802

    
803
  $form['appearance']['show_toggle'] = array(
804
    '#type' => 'radios',
805
    '#title' => t('Show the disable/enable rich text editor toggle'),
806
    '#default_value' => !empty($profile->settings['show_toggle']) ? $profile->settings['show_toggle'] : 't',
807
    '#options' => array(
808
      't' => t('Show'),
809
      'f' => t('Hide')
810
    ),
811
    '#description' => t('Whether or not to show the disable/enable rich text editor toggle below the textarea.'),
812
  );
813

    
814
  $form['appearance']['uicolor'] = array(
815
    '#type' => 'select',
816
    '#title' => t('User interface color'),
817
    '#default_value' => !empty($profile->settings['uicolor']) ? $profile->settings['uicolor'] : 'default',
818
    '#options' => $ui_colors,
819
  );
820

    
821
  if (!isset($global_profile->settings['skin']) || !file_exists($editor_local_path . '/skins/' . $global_profile->settings['skin'])) {
822
    $global_profile->settings['skin'] = ckeditor_default_skin();
823
  }
824
  $skinframe_url = url('admin/config/content/ckeditor/skinframe', array(
825
    'query' => array(
826
      'token' => drupal_get_token('ckeditorSkinframeCall'),
827
      'skin' => $global_profile->settings['skin'],
828
      'uicolor' => (!empty($profile->settings['uicolor_user']) && $profile->settings['uicolor'] == 'custom') ? ltrim($profile->settings['uicolor_user'], '#') : 'D3D3D3'
829
    )
830
  ));
831
  $form['appearance']['skinframe'] = array(
832
    '#markup' => '<iframe frameborder="0" id="skinframe" marginheight="0" marginwidth="0" src="' . $skinframe_url . '" style="height:430px;width:700px;"></iframe><br/>',
833
    '#description' => '',
834
  );
835
  $form['appearance']['uicolor_user'] = array(
836
    '#type' => 'hidden',
837
    '#default_value' => !empty($profile->settings['uicolor_user']) ? $profile->settings['uicolor_user'] : 'default',
838
  );
839

    
840
  $plugin_list = ckeditor_load_plugins();
841
  $plugins = array();
842
  if (isset($profile->settings['loadPlugins'])) {
843
    foreach ($plugin_list AS $key => $val) {
844
      $plugins[$key] = $val['desc'];
845
    }
846
  }
847
  else {
848
    $default_plugins = array();
849
    foreach ($plugin_list AS $key => $val) {
850
      $plugins[$key] = $val['desc'];
851
      if (isset($val['default']) && $val['default'] == 't') {
852
        $default_plugins[] = $key;
853
      }
854
    }
855
  }
856

    
857
  $form['appearance']['loadPlugins'] = array(
858
    '#type' => 'checkboxes',
859
    '#title' => t('Plugins'),
860
    '#default_value' => isset($profile->settings['loadPlugins']) ? array_keys((array) $profile->settings['loadPlugins']) : $default_plugins,
861
    '#options' => $plugins,
862
    '#description' => t('Choose the plugins that you want to enable in CKEditor.')
863
  );
864

    
865
  if ($editor_local_path != '<URL>' && file_exists($editor_local_path . '/plugins/divarea/plugin.js')) {
866
    $form['appearance']['use_divarea'] = array(
867
      '#type' => 'radios',
868
      '#title' => t('"Div-based" editor'),
869
      '#default_value' => !empty($profile->settings['use_divarea']) ? $profile->settings['use_divarea'] : 'f',
870
      '#options' => array(
871
        't' => t('Enabled'),
872
        'f' => t('Disabled')
873
      ),
874
      '#description' => t("Loading editor into <code>div</code> instead of <code>iframe</code>.")
875
    );
876
  }
877

    
878
  $form['appearance']['width'] = array(
879
    '#type' => 'textfield',
880
    '#title' => t('Editor width'),
881
    '#default_value' => !empty($profile->settings['width']) ? $profile->settings['width'] : '100%',
882
    '#description' => t("Editor interface width in pixels or percent. Examples: 400, 100%."),
883
    '#size' => 40,
884
    '#maxlength' => 128,
885
  );
886

    
887
  $form['appearance']['lang'] = array(
888
    '#type' => 'select',
889
    '#title' => t('Language'),
890
    '#default_value' => !empty($profile->settings['lang']) ? $profile->settings['lang'] : 'en',
891
    '#options' => $lang_options,
892
    '#description' => t('The language for the CKEditor user interface.')
893
  );
894

    
895
  $form['appearance']['auto_lang'] = array(
896
    '#type' => 'radios',
897
    '#title' => t('Auto-detect language'),
898
    '#default_value' => !empty($profile->settings['auto_lang']) ? $profile->settings['auto_lang'] : 't',
899
    '#options' => array(
900
      't' => t('Enabled'),
901
      'f' => t('Disabled')
902
    ),
903
    '#description' => t('Automatically detect the user language.')
904
  );
905

    
906
  $form['appearance']['language_direction'] = array(
907
    '#type' => 'select',
908
    '#title' => t('Language direction'),
909
    '#default_value' => !empty($profile->settings['language_direction']) ? $profile->settings['language_direction'] : 'default',
910
    '#options' => array(
911
      'default' => t('Get from current locale (default)'),
912
      'ltr' => t('Left-To-Right'), // language like English
913
      'rtl' => t('Right-To-Left') // languages like Arabic
914
    ),
915
    '#description' => t(
916
        '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(
917
      '!bidiltr' => 'BidiLtr',
918
      '!bidirtl' => 'BidiRtl'
919
        )
920
    )
921
  );
922

    
923
  $form['acf'] = array(
924
    '#type' => 'fieldset',
925
    '#title' => t('Advanced content filter'),
926
    '#description' => t('Configure input data filtering in CKEditor. See !link for more information about ACF.', array(
927
        '!link' => l(t('this blog post'), 'http://ckeditor.com/blog/Upgrading-to-CKEditor-4.1')
928
      )),
929
    '#collapsible' => TRUE,
930
    '#collapsed' => TRUE
931
  );
932

    
933
  $form['acf']['allowed_content'] = array(
934
    '#type' => 'radios',
935
    '#title' => t('Advanced content filter'),
936
    '#description' => 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(
937
    '!strong' => '<code>&lt;strong&gt;</code>',
938
    '!a' => '<code>&lt;a&gt;</code>',
939
    '!img' => '<code>&lt;img&gt;</code>',
940
    '!b' => '<code>&lt;b&gt;</code>'
941
  )).'<br /><br />'.
942
    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.'),
943

    
944
    '#default_value' => !empty($profile->settings['allowed_content']) ? $profile->settings['allowed_content'] : 't',
945
    '#options' => array(
946
      't' => t('Enabled'),
947
      'f' => t('Disabled'),
948
    ),
949
  );
950
  $form['acf']['allowed_content']['t']['#description'] = t('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.');
951
  $form['acf']['allowed_content']['f']['#description'] = t('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.');
952

    
953
  $form['acf']['extraAllowedContent'] = array(
954
    '#type' => 'textarea',
955
    '#title' => t('Extra allowed content'),
956
    '#default_value' => !empty($profile->settings['extraAllowedContent']) ? $profile->settings['extraAllowedContent'] : "",
957
    '#cols' => 60,
958
    '#rows' => 5,
959
    '#description' => t(
960
      'Set additional allowed content rules for CKEditor. Separate rules with a semicolon. See !docs for more information.', array(
961
        '!docs' => l(t('CKEditor documentation'), 'http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-allowedContent')
962
       )).'<p>'.
963
       t('<strong>Example:</strong> !rules', array(
964
         '!rules' => "<code>object[width,height];param[name,value];embed[*];</code>"
965
       )).'</p>',
966
    '#wysiwyg' => FALSE,
967
  );
968

    
969
  $form['output'] = array(
970
    '#type' => 'fieldset',
971
    '#title' => t('Cleanup and output'),
972
    '#collapsible' => TRUE,
973
    '#collapsed' => TRUE,
974
  );
975

    
976
  $form['output']['enter_mode'] = array(
977
    '#type' => 'select',
978
    '#title' => t('Enter mode'),
979
    '#default_value' => !empty($profile->settings['enter_mode']) ? $profile->settings['enter_mode'] : 'p',
980
    '#options' => array(
981
      'p' => '<p>',
982
      'br' => '<br>',
983
      'div' => '<div>'
984
    ),
985
    '#description' => t('Set which tag should be used by CKEditor when the <em>Enter</em> key is pressed.')
986
  );
987

    
988
  $form['output']['shift_enter_mode'] = array(
989
    '#type' => 'select',
990
    '#title' => t('Shift+Enter mode'),
991
    '#default_value' => !empty($profile->settings['shift_enter_mode']) ? $profile->settings['shift_enter_mode'] : 'br',
992
    '#options' => array(
993
      'p' => '<p>',
994
      'br' => '<br>',
995
      'div' => '<div>'
996
    ),
997
    '#description' => t('Set which tag should be used by CKEditor when the <em>Shift+Enter</em> key combination is pressed.')
998
  );
999

    
1000
  $form['output']['font_format'] = array(
1001
    '#type' => 'textfield',
1002
    '#title' => t('Font formats'),
1003
    '#default_value' => !empty($profile->settings['font_format']) ? $profile->settings['font_format'] : 'p;div;pre;address;h1;h2;h3;h4;h5;h6',
1004
    '#size' => 40,
1005
    '#maxlength' => 250,
1006
    '#description' => t(
1007
        'Semicolon-separated list of HTML font formats. Allowed values are: !allowed_values', array(
1008
      '!allowed_values' => '<code>p;div;pre;address;h1;h2;h3;h4;h5;h6</code>'
1009
        )
1010
    )
1011
  );
1012

    
1013
  if (!empty($profile->settings['formatting']['custom_formatting_options'])) {
1014
    foreach ($profile->settings['formatting']['custom_formatting_options'] as $k => $v) {
1015
      if ($v === 0) {
1016
        unset($profile->settings['formatting']['custom_formatting_options'][$k]);
1017
      }
1018
    }
1019
  }
1020

    
1021
  $form['output']['custom_formatting'] = array(
1022
    '#type' => 'radios',
1023
    '#title' => t('Use custom formatting options'),
1024
    '#default_value' => !empty($profile->settings['custom_formatting']) ? $profile->settings['custom_formatting'] : 'f',
1025
    '#options' => array(
1026
      't' => t('Yes'),
1027
      'f' => t('No'),
1028
    ),
1029
  );
1030

    
1031
  $form['output']['formatting'] = array(
1032
    '#type' => 'fieldset',
1033
    '#title' => t('Custom formatting options'),
1034
    '#tree' => TRUE,
1035
  );
1036

    
1037
  $form['output']['formatting']['custom_formatting_options'] = array(
1038
    '#type' => 'checkboxes',
1039
    '#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'),
1040
    '#options' => array(
1041
      'indent' => t('Indent the element contents.'),
1042
      'breakBeforeOpen' => t('Break line before the opening tag.'),
1043
      'breakAfterOpen' => t('Break line after the opening tag.'),
1044
      'breakBeforeClose' => t('Break line before the closing tag.'),
1045
      'breakAfterClose' => t('Break line after the closing tag.'),
1046
      'pre_indent' => t('Indent the <code>&lt;pre&gt;</code> element contents.'),
1047
    ),
1048
  );
1049

    
1050
  $form['css'] = array(
1051
    '#type' => 'fieldset',
1052
    '#title' => t('CSS'),
1053
    '#collapsible' => TRUE,
1054
    '#collapsed' => TRUE
1055
  );
1056

    
1057
  $current_theme = variable_get('theme_default', $theme);
1058
  $theme_path = drupal_get_path('theme', $current_theme);
1059

    
1060
  $form['css']['css_mode'] = array(
1061
    '#type' => 'select',
1062
    '#title' => t('Editor CSS'),
1063
    '#default_value' => !empty($profile->settings['css_mode']) ? $profile->settings['css_mode'] : 'theme',
1064
    '#options' => array(
1065
      'theme' => t('Use theme CSS'),
1066
      'self' => t('Define CSS'),
1067
      'none' => t('CKEditor default')
1068
    ),
1069
    '#description' => t(
1070
        '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(
1071
      '!title_theme_css' => '<br /><strong>' . t('Use theme CSS') . '</strong>',
1072
      '!title_define_css' => '<br /><strong>' . t('Define CSS') . '</strong>',
1073
      '!title_ckeditor_default' => '<br /><strong>' . t('CKEditor default') . '</strong>',
1074
      '!style_css' => '<code>style.css</code>'
1075
        )
1076
    )
1077
  );
1078

    
1079
  $form['css']['css_path'] = array(
1080
    '#type' => 'textfield',
1081
    '#title' => t('CSS file path'),
1082
    '#default_value' => !empty($profile->settings['css_path']) ? $profile->settings['css_path'] : "",
1083
    '#size' => 40,
1084
    '#maxlength' => 255,
1085
    '#description' => t(
1086
        '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 !title_define_css option above.', array(
1087
      '!example1' => '<code>"css/editor.css"</code>',
1088
      '!example2' => '<code>"/themes/garland/style.css,http://example.com/style.css"</code>',
1089
      '!title_define_css' => '<strong>' . t('Define CSS') . '</strong>'
1090
        )
1091
    ) .
1092
    '<br />' .
1093
    t('Available placeholders:!h &ndash; host name (!host).!t &ndash; path to theme (!theme).', array(
1094
      '!h' => '<br /><code>%h</code>',
1095
      '!t' => '<br /><code>%t</code>',
1096
      '!host' => '<code>' . base_path() . '</code>',
1097
      '!theme' => '<code>' . base_path() . $theme_path . '/</code>'
1098
        )
1099
    )
1100
  );
1101

    
1102
  $form['css']['css_style'] = array(
1103
    '#type' => 'select',
1104
    '#title' => t('Predefined styles'),
1105
    '#default_value' => !empty($profile->settings['css_style']) ? $profile->settings['css_style'] : 'theme',
1106
    '#options' => array(
1107
      'theme' => t('Use theme ckeditor.styles.js'),
1108
      'self' => t('Define path to ckeditor.styles.js'),
1109
      'default' => t('CKEditor default')
1110
    ),
1111
    '#description' => t(
1112
        '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(
1113
      '!ckeditor_styles_js_file' => '<code>ckeditor.styles.js</code>',
1114
      '!ckeditor_styles_js_path' => '<code>' . drupal_get_path('module', 'ckeditor') . '/ckeditor.styles.js</code>',
1115
      '!theme' => '<code>' . $theme_path . '/ckeditor.styles.js' . '</code>'
1116
        )
1117
    )
1118
  );
1119

    
1120
  $form['css']['styles_path'] = array(
1121
    '#type' => 'textfield',
1122
    '#title' => t('Predefined styles path'),
1123
    '#default_value' => !empty($profile->settings['styles_path']) ? $profile->settings['styles_path'] : "",
1124
    '#size' => 40,
1125
    '#maxlength' => 255,
1126
    '#description' => t(
1127
        'Enter the path to a file with predefined styles (Example: !example1). Make sure you select the !style_define_path option above.', array(
1128
      '!style_define_path' => '<strong>' . t('Define path to ckeditor.styles.js') . '</strong>',
1129
      '!ckeditor_styles_js_file' => '<code>ckeditor.styles.js</code>',
1130
      '!example1' => '<code>/ckeditor.styles.js</code>'
1131
        )
1132
    ) .
1133
    '<br />' .
1134
    t('Available placeholders:!h &ndash; host name (!host).!t &ndash; path to theme (!theme).!m &ndash; path to the CKEditor module (!module).', array(
1135
      '!h' => '<br /><code>%h</code>',
1136
      '!t' => '<br /><code>%t</code>',
1137
      '!m' => '<br /><code>%m</code>',
1138
      '!host' => '<code>' . base_path() . '</code>',
1139
      '!theme' => '<code>' . base_path() . $theme_path . '/</code>',
1140
      '!module' => '<code>' . drupal_get_path('module', 'ckeditor') . '</code>'
1141
        )
1142
    )
1143
  );
1144

    
1145
  $form['ckeditor_upload_settings'] = array(
1146
    '#type' => 'fieldset',
1147
    '#title' => t('File browser settings'),
1148
    '#collapsible' => TRUE,
1149
    '#collapsed' => TRUE,
1150
    '#description' => t(
1151
        '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 or !elfinder. CKEditor can be also integrated with !ckfinder, an advanced Ajax file manager.', array(
1152
      '!imce' => l(t('IMCE'), 'http://drupal.org/project/imce'),
1153
      '!elfinder' => l(t('elFinder'), 'http://drupal.org/project/elfinder'),
1154
      '!ckfinder' => l(t('CKFinder'), 'http://cksource.com/ckfinder')
1155
        )
1156
    )
1157
  );
1158

    
1159
  $filebrowsers = array(
1160
    'none' => t('None'),
1161
    'ckfinder' => t('CKFinder'),
1162
  );
1163

    
1164
  $filebrowsers_dialogs = array(
1165
    '' => t('Same as in the Link dialog window'),
1166
    'ckfinder' => t('CKFinder'),
1167
  );
1168

    
1169
  if (module_exists('imce')) {
1170
    $filebrowsers['imce'] = t('IMCE');
1171
    $filebrowsers_dialogs['imce'] = t('IMCE');
1172
  }
1173

    
1174
  if (module_exists('elfinder')) {
1175
    $filebrowsers['elfinder'] = t('elFinder');
1176
    $filebrowsers_dialogs['elfinder'] = t('elFinder');
1177
  }
1178

    
1179
  /* MODULES NOT PORTED TO D7
1180
    if (module_exists('tinybrowser')) {
1181
    $filebrowsers['tinybrowser'] = t('TinyBrowser');
1182
    $filebrowsers_dialogs['tinybrowser'] = t('TinyBrowser');
1183
    }
1184

    
1185
    if (module_exists('imagebrowser')) {
1186
    $filebrowsers['ib'] = t('Image Browser');
1187
    $filebrowsers_dialogs['ib'] = t('Image Browser');
1188
    }
1189

    
1190
    if (module_exists('webfm_popup')) {
1191
    $filebrowsers['webfm'] = t('Web File Manager');
1192
    $filebrowsers_dialogs['webfm'] = t('Web File Manager');
1193
    }
1194
   */
1195
  $form['ckeditor_upload_settings']['filebrowser'] = array(
1196
    '#type' => 'select',
1197
    '#title' => t('File browser type (Link dialog window)'),
1198
    '#default_value' => !empty($profile->settings['filebrowser']) ? $profile->settings['filebrowser'] : 'none',
1199
    '#options' => $filebrowsers,
1200
    '#description' => t('Select the file browser that you would like to use to upload files.'),
1201
  );
1202

    
1203
  $form['ckeditor_upload_settings']['filebrowser_image'] = array(
1204
    '#type' => 'select',
1205
    '#title' => t('File browser type (Image dialog window)'),
1206
    '#default_value' => !empty($profile->settings['filebrowser_image']) ? $profile->settings['filebrowser_image'] : 'none',
1207
    '#options' => $filebrowsers_dialogs,
1208
    '#description' => t('Select the file browser that you would like to use to upload images.'),
1209
  );
1210

    
1211
  $form['ckeditor_upload_settings']['filebrowser_flash'] = array(
1212
    '#type' => 'select',
1213
    '#title' => t('File browser type (Flash dialog window)'),
1214
    '#default_value' => !empty($profile->settings['filebrowser_flash']) ? $profile->settings['filebrowser_flash'] : 'none',
1215
    '#options' => $filebrowsers_dialogs,
1216
    '#description' => t('Select the file browser that you would like to use to upload Flash movies.'),
1217
  );
1218

    
1219
  if (variable_get('file_default_scheme', '') != 'private') {
1220
    $current_user_files_path = empty($profile->settings['UserFilesPath']) ? "%b%f/" : $profile->settings['UserFilesPath'];
1221
    $current_user_files_path = strtr($current_user_files_path, array("%f" => variable_get('file_public_path', conf_path() . '/files'), "%u" => "UID", "%b" => base_path(), "%n" => "UNAME"));
1222

    
1223
    $current_user_files_absolute_path = empty($profile->settings['UserFilesAbsolutePath']) ? "%d%b%f/" : $profile->settings['UserFilesAbsolutePath'];
1224
    $current_user_files_absolute_path = strtr($current_user_files_absolute_path, array("%f" => variable_get('file_public_path', conf_path() . '/files'), "%u" => "UID", "%b" => base_path(), "%d" => ckeditor_get_document_root_full_path(), "%n" => "UNAME"));
1225

    
1226

    
1227
    $form['ckeditor_upload_settings']['UserFilesPath'] = array(
1228
      '#type' => 'textfield',
1229
      '#prefix' => '<fieldset><legend>' . t('CKFinder settings') . '</legend>',
1230
      '#title' => t('Path to uploaded files'),
1231
      '#default_value' => !empty($profile->settings['UserFilesPath']) ? $profile->settings['UserFilesPath'] : "%b%f/",
1232
      '#size' => 40,
1233
      '#maxlength' => 255,
1234
      '#description' => t('Path to uploaded files relative to the document root.') .
1235
      '<br />' .
1236
      t('Available placeholders:!b &ndash; the base URL path of the Drupal installation (!base).!f &ndash; the Drupal file system path where the files are stored (!files).!u &ndash; User ID.!n &ndash; Username.', array(
1237
        '!n' => '<br /><code>%n</code>',
1238
        '!u' => '<br /><code>%u</code>',
1239
        '!f' => '<br/><code>%f</code>',
1240
        '!b' => '<br/><code>%b</code>',
1241
        '!files' => '<code>' . variable_get('file_public_path', conf_path() . '/files') . '</code>',
1242
        '!base' => '<code>' . base_path() . '</code>'
1243
          )
1244
      ) .
1245
      '<br />' .
1246
      t('Current path: !path', array(
1247
        '!path' => '<code>' . $current_user_files_path . '</code>'
1248
          )
1249
      )
1250
    );
1251

    
1252
    $form['ckeditor_upload_settings']['UserFilesAbsolutePath'] = array(
1253
      '#type' => 'textfield',
1254
      '#title' => t('Absolute path to uploaded files'),
1255
      '#default_value' => !empty($profile->settings['UserFilesAbsolutePath']) ? $profile->settings['UserFilesAbsolutePath'] : "%d%b%f/",
1256
      '#size' => 40,
1257
      '#maxlength' => 255,
1258
      '#suffix' => '</fieldset>',
1259
      '#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.') .
1260
      '<br />' .
1261
      t('Available placeholders:!d &ndash; the server path to the document root (!root).!b &ndash; the base URL path of the Drupal installation (!base).!f &ndash; the Drupal file system path where the files are stored (!files).!u &ndash; User ID.!n &ndash; Username.', array(
1262
        '!u' => '<br /><code>%u</code>',
1263
        '!n' => '<br /><code>%n</code>',
1264
        '!d' => '<br/><code>%d</code>',
1265
        '!b' => '<br /><code>%b</code>',
1266
        '!f' => '<br/><code>%f</code>',
1267
        '!files' => '<code>' . variable_get('file_public_path', conf_path() . '/files') . '</code>',
1268
        '!base' => '<code>' . base_path() . '</code>',
1269
        '!root' => '<code>' . ckeditor_get_document_root_full_path() . '</code>'
1270
          )
1271
      ) .
1272
      '<br />' .
1273
      t('Current path: !path', array(
1274
        '!path' => '<code>' . $current_user_files_absolute_path . '</code>'
1275
          )
1276
      )
1277
    );
1278
  }
1279
  if (variable_get('file_default_scheme', '') == 'private') {
1280
    $form['ckeditor_upload_settings']['private_path_descrption'] = array(
1281
      '#markup' => '<div>' . t(
1282
          '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(
1283
        '!url' => l(t('CKEditor Global Profile'), 'admin/config/content/ckeditor/editg')
1284
          )
1285
      ) . '</div>',
1286
    );
1287
  }
1288

    
1289
  $form['advanced'] = array(
1290
    '#type' => 'fieldset',
1291
    '#title' => t('Advanced options'),
1292
    '#collapsible' => TRUE,
1293
    '#collapsed' => TRUE,
1294
  );
1295
  if (ckeditor_get_version(TRUE) == 3) {
1296
    $form['advanced']['ckeditor_load_method'] = array(
1297
      '#type' => 'select',
1298
      '#title' => t('Loading method'),
1299
      '#default_value' => !empty($profile->settings['ckeditor_load_method']) ? $profile->settings['ckeditor_load_method'] : 'ckeditor.js',
1300
      '#options' => _ckeditor_load_methods(),
1301
      '#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(
1302
        '!ckeditor_basic_js' => '<code>ckeditor_basic.js</code>'
1303
          )
1304
      )
1305
    );
1306
    $form['advanced']['ckeditor_load_time_out'] = array(
1307
      '#type' => 'textfield',
1308
      '#title' => t('Loading timeout'),
1309
      '#default_value' => !empty($profile->settings['ckeditor_load_time_out']) ? $profile->settings['ckeditor_load_time_out'] : "0",
1310
      '#size' => 40,
1311
      '#maxlength' => 255,
1312
      '#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(
1313
        '!ckeditor_basic_js' => '<code>ckeditor_basic.js</code>'
1314
          )
1315
      )
1316
    );
1317
  }
1318

    
1319
  $form['advanced']['forcePasteAsPlainText'] = array(
1320
    '#type' => 'select',
1321
    '#title' => t('Force pasting as plain text'),
1322
    '#default_value' => !empty($profile->settings['forcePasteAsPlainText']) ? $profile->settings['forcePasteAsPlainText'] : "f",
1323
    '#options' => array(
1324
      't' => t('Enabled'),
1325
      'f' => t('Disabled')
1326
    ),
1327
    '#description' => t('If enabled, HTML content will be automatically changed to plain text when pasting.'),
1328
  );
1329
  $form['advanced']['html_entities'] = array(
1330
    '#type' => 'radios',
1331
    '#title' => t('HTML Entities'),
1332
    '#default_value' => !empty($profile->settings['html_entities']) ? $profile->settings['html_entities'] : 'f',
1333
    '#description' => t('Convert all applicable characters to HTML entities.'),
1334
    '#options' => array(
1335
      'f' => t('No'),
1336
      't' => t('Yes')
1337
    ),
1338
  );
1339
  $form['advanced']['scayt_autoStartup'] = array(
1340
    '#type' => 'radios',
1341
    '#title' => t('Spellchecker'),
1342
    '#default_value' => !empty($profile->settings['scayt_autoStartup']) ? $profile->settings['scayt_autoStartup'] : 'f',
1343
    '#description' => t('If enabled, turns on SCAYT (Spell Check As You Type) automatically after loading the editor.'),
1344
    '#options' => array(
1345
      'f' => t('No'),
1346
      't' => t('Yes')
1347
    ),
1348
  );
1349
  $form['advanced']['theme_config_js'] = array(
1350
    '#type' => 'radios',
1351
    '#title' => t('Load !ckeditor_config_js from the theme path', array(
1352
      '!ckeditor_config_js' => '<code>ckeditor.config.js</code>'
1353
        )
1354
    ),
1355
    '#default_value' => !empty($profile->settings['theme_config_js']) ? $profile->settings['theme_config_js'] : 'f',
1356
    '#options' => array(
1357
      't' => t('Yes'),
1358
      'f' => t('No')
1359
    ),
1360
    '#description' => t('When enabled, the editor will try to load the !ckeditor_config_js file from the theme directory.', array(
1361
      '!ckeditor_config_js' => '<code>ckeditor.config.js</code>'
1362
        )
1363
    )
1364
  );
1365
  $form['advanced']['js_conf'] = array(
1366
    '#type' => 'textarea',
1367
    '#title' => t('Custom JavaScript configuration'),
1368
    '#default_value' => !empty($profile->settings['js_conf']) ? $profile->settings['js_conf'] : "",
1369
    '#cols' => 60,
1370
    '#rows' => 5,
1371
    '#description' => t(
1372
        '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(
1373
      '!ckeditor_config' => '<code>' . drupal_get_path('module', 'ckeditor') . "/ckeditor.config.js</code>",
1374
      '!docs' => l(t('CKEditor documentation'), 'http://docs.cksource.com/ckeditor_api/symbols/CKEDITOR.config.html'),
1375
      '@code' => "config.font_names = 'Arial;Times New Roman;Verdana';\nconfig.fontSize_sizes = '16/16px;24/24px;48/48px;';"
1376
        )
1377
    ),
1378
    '#wysiwyg' => FALSE,
1379
  );
1380

    
1381
  $form['submit'] = array(
1382
    '#type' => 'submit',
1383
    '#value' => t('Save')
1384
  );
1385

    
1386
  return $form;
1387
}
1388

    
1389
/**
1390
 * Form validation for a profile.
1391
 */
1392
function ckeditor_admin_profile_form_validate($form, &$form_state) {
1393
  $edit = & $form_state['values'];
1394
  /*
1395
    if ($edit['default'] == 't' && $edit['popup'] == 't') {
1396
    form_set_error('popup', t('If CKEditor is enabled by default, the popup window must be disabled.'));
1397
    }
1398

    
1399
    if ($edit['show_toggle'] == 't' && $edit['popup'] == 't') {
1400
    form_set_error('popup', t('If toggle is enabled, the popup window must be disabled.'));
1401
    }
1402
   */
1403
  if (!$edit['name']) {
1404
    form_set_error('name', t('You must give a profile name.'));
1405
  }
1406
  elseif (!preg_match('/^[A-Za-z0-9_]+$/', $edit['name'])) {
1407
    form_set_error('name', t('Enter a valid profile name. Only alphanumeric and underscore characters are allowed.'));
1408
  }
1409
  elseif ($edit['name'] == 'CKEditor Global Profile') {
1410
    form_set_error('name', t('This profile name is reserved. Please choose a different name.'));
1411
  }
1412
  elseif (!isset($edit['_profile']) || ($edit['_profile']->name != $edit['name'])) {
1413
    $result = ckeditor_profile_load($edit['name']);
1414
    if (!empty($result)) {
1415
      form_set_error('name', t('The profile name must be unique. A profile with this name already exists.'));
1416
    }
1417
  }
1418

    
1419
  if (!preg_match('/^\d+%?$/', $edit['width'])) {
1420
    form_set_error('width', t('Enter a valid width value. Examples: 400, 100%.'));
1421
  }
1422

    
1423
  if (!empty($edit['css_path'])) {
1424
    if ($edit['css_mode'] != 'self') {
1425
      form_set_error('css_path', t('The CSS path is not empty. Please set the <strong>Editor CSS</strong> option to the <strong>Define CSS</strong> mode.'));
1426
    }
1427
    elseif (FALSE !== strpos($edit['css_path'], '"')) {
1428
      form_set_error('css_path', t('Double quotes are not allowed in the CSS path.'));
1429
    }
1430
    elseif (substr($edit['css_path'], 0, 1) == "'" && substr($edit['css_path'], -1) == "'") {
1431
      form_set_error('css_path', t('Enter a valid CSS path, do not surround it with quotes.'));
1432
    }
1433
  }
1434

    
1435
  if (!empty($edit['styles_path'])) {
1436
    if ($edit['css_style'] != 'self') {
1437
      form_set_error('styles_path', t('The path to predefined styles is not empty. Please set the <strong>Predefined styles</strong> option to the <strong>Define path to ckeditor.styles.js</strong> mode.'));
1438
    }
1439
    elseif (FALSE !== strpos($edit['styles_path'], '"')) {
1440
      form_set_error('styles_path', t('Double quotes are not allowed in the styles path.'));
1441
    }
1442
    elseif (substr($edit['styles_path'], 0, 1) == "'" && substr($edit['styles_path'], -1) == "'") {
1443
      form_set_error('styles_path', t('Enter a valid styles path, do not surround it with quotes.'));
1444
    }
1445
  }
1446

    
1447
  if (!empty($edit['font_format'])) {
1448
    if (!preg_match("/^((p|div|pre|address|h1|h2|h3|h4|h5|h6);)*(p|div|pre|address|h1|h2|h3|h4|h5|h6)$/", $edit['font_format'])) {
1449
      form_set_error('font_format', t('Enter a valid, semicolon-separated list of HTML font formats (no semicolon at the end of the list is expected).'));
1450
    }
1451
  }
1452
  // @todo DOWNLOAD API
1453
  if (!empty($edit['UserFilesAbsolutePath']) && empty($edit['UserFilesPath'])) {
1454
    form_set_error('UserFilesPath', t('The path to uploaded files is required.'));
1455
  }
1456
  if (!empty($edit['UserFilesPath']) && empty($edit['UserFilesAbsolutePath'])) {
1457
    form_set_error('UserFilesPath', t('An absolute path to uploaded files is required.'));
1458
  }
1459

    
1460
  if (ckeditor_get_version(TRUE) == 3) {
1461
    $load_methods = _ckeditor_load_methods();
1462
    if (!isset($load_methods[$edit['ckeditor_load_method']])) {
1463
      form_set_error('ckeditor_load_method', t('Set a valid loading method.'));
1464
    }
1465
    if (!preg_match('#\d+#', $edit['ckeditor_load_time_out'])) {
1466
      form_set_error('ckeditor_load_time_out', t('Enter a valid loading timeout in seconds.'));
1467
    }
1468
  }
1469
  $toolbar = $edit['toolbar'];
1470
  $toolbar = str_replace("'", '"', $toolbar);
1471
  $toolbar = preg_replace('/(\w*)\s*\:/', '"${1}":', $toolbar);
1472

    
1473
  if (strpos($toolbar, 'CodeSnippet') !== false && empty($edit['loadPlugins']['codesnippet'])) {
1474
    form_set_error('loadPlugins][codesnippet', t('The Code Snippet plugin must be enabled if the CodeSnippet button is enabled in the toolbar.'));
1475
  }
1476
  if (strpos($toolbar, 'Mathjax') !== false && empty($edit['loadPlugins']['mathjax'])) {
1477
    form_set_error('loadPlugins][mathjax', t('The Mathjax plugin must be enabled if the Mathjax button is enabled in the toolbar.'));
1478
  }
1479
  if (!json_decode($toolbar)) {
1480
    form_set_error('toolbar', t('Enter a valid toolbar configuration.'));
1481
  }
1482
}
1483

    
1484
/**
1485
 * Form submit for a profile
1486
 */
1487
function ckeditor_admin_profile_form_submit($form, &$form_state) {
1488
  $edit = & $form_state['values'];
1489

    
1490
  if (isset($edit['_profile'])) {
1491
    ckeditor_profile_delete($edit['_profile']->name);
1492
    drupal_set_message(t('Your CKEditor profile was updated.'));
1493
  }
1494
  else {
1495
    drupal_set_message(t('Your CKEditor profile was created.'));
1496
  }
1497

    
1498
  $settings = ckeditor_admin_values_to_settings($edit);
1499
  db_insert('ckeditor_settings')
1500
      ->fields(array(
1501
        "name" => $edit['name'],
1502
        "settings" => $settings
1503
      ))
1504
      ->execute();
1505

    
1506
  if (!empty($edit['input_formats'])) {
1507
    foreach (array_keys($edit['input_formats']) as $format) {
1508
      if ($edit['input_formats'][$format] != '0') {
1509
        db_insert('ckeditor_input_format')->fields(array("name" => $edit['name'], "format" => $format))->execute();
1510
      }
1511
    }
1512
  }
1513

    
1514
  $form_state['redirect'] = 'admin/config/content/ckeditor';
1515
}
1516

    
1517
/**
1518
 * Form builder for a clone profile
1519
 */
1520
function ckeditor_admin_profile_clone_form($form, $form_state, $task, $oldprofile) {
1521
  return ckeditor_admin_profile_form($form, $form_state, $task, $oldprofile);
1522
}
1523

    
1524
/**
1525
 * Form validation for a clone profile
1526
 */
1527
function ckeditor_admin_profile_clone_form_validate($form_state, $oldprofile) {
1528
  ckeditor_admin_profile_form_validate($form_state, $oldprofile);
1529
}
1530

    
1531
/**
1532
 * Form submit for a clone profile
1533
 */
1534
function ckeditor_admin_profile_clone_form_submit($form, &$form_state) {
1535
  $edit = & $form_state['values'];
1536
  drupal_set_message(t('Your CKEditor profile was created.'));
1537
  $settings = ckeditor_admin_values_to_settings($edit);
1538
  db_insert('ckeditor_settings')
1539
      ->fields(array(
1540
        "name" => $edit['name'],
1541
        "settings" => $settings
1542
      ))
1543
      ->execute();
1544

    
1545
  if (!empty($edit['input_formats'])) {
1546
    foreach (array_keys($edit['input_formats']) as $format) {
1547
      if ($edit['input_formats'][$format] != 0) {
1548
        db_insert('ckeditor_input_format')->fields(array("name" => $edit['name'], "format" => $format))->execute();
1549
      }
1550
    }
1551
  }
1552

    
1553
  $form_state['redirect'] = 'admin/config/content/ckeditor';
1554
}
1555

    
1556
/**
1557
 * Form builder for a profile delete
1558
 */
1559
function ckeditor_admin_profile_delete_form($form, $form_state, $profile) {
1560
  $form = array();
1561

    
1562
  $form['_profile'] = array(
1563
    '#type' => 'value',
1564
    '#value' => $profile,
1565
  );
1566

    
1567
  $form['question'] = array(
1568
    '#type' => 'item',
1569
    '#markup' => t(
1570
        'Are you sure that you want to delete the CKEditor profile <strong>%profile</strong>?', array(
1571
      '%profile' => $profile->name
1572
        )
1573
    ),
1574
  );
1575

    
1576
  $form['delete'] = array(
1577
    '#type' => 'submit',
1578
    '#id' => 'delete',
1579
    '#value' => t('Delete'),
1580
  );
1581

    
1582
  $form['back'] = array(
1583
    '#type' => 'submit',
1584
    '#id' => 'back',
1585
    '#value' => t('Cancel'),
1586
  );
1587

    
1588
  return $form;
1589
}
1590

    
1591
/**
1592
 * Submit form for a profile delete
1593
 */
1594
function ckeditor_admin_profile_delete_form_submit($form, &$form_state) {
1595
  $v = & $form_state['values'];
1596

    
1597
  if ($form_state['clicked_button']['#id'] == 'delete') {
1598
    ckeditor_profile_delete($v['_profile']->name);
1599
    drupal_set_message(t('The CKEditor profile was deleted.'));
1600
  }
1601

    
1602
  $form_state['redirect'] = 'admin/config/content/ckeditor';
1603
}
1604

    
1605
/**
1606
 * Converts an array of form values to a serialized array that does not
1607
 * contain Drupal Form API values
1608
 */
1609
function ckeditor_admin_values_to_settings($values) {
1610
  $plugins = array();
1611
  if (isset($values['loadPlugins'])) {
1612
    $plugins = $values['loadPlugins'];
1613
  }
1614
  unset($values['name'], $values['input_formats'], $values['_profile'], $values['op'], $values['submit'], $values['form_build_id'], $values['form_token'], $values['form_id'], $values['loadPlugins']);
1615

    
1616
  // Replace CRLF with LF in toolbar settings
1617
  if(isset($values['toolbar'])){
1618
    $values['toolbar'] = str_replace("\r\n", "\n", $values['toolbar']);
1619
  }
1620

    
1621
  module_load_include('inc', 'ckeditor', 'includes/ckeditor.lib');
1622
  $plugin_list = ckeditor_load_plugins();
1623
  $values['loadPlugins'] = array();
1624
  if (!empty($plugins)) {
1625
    foreach (array_keys($plugins) as $plugin) {
1626
      if ($plugins[$plugin] != '0') {
1627
        $values['loadPlugins'][$plugin] = $plugin_list[$plugin];
1628
      }
1629
    }
1630
  }
1631

    
1632
  return serialize($values);
1633
}
1634

    
1635
/**
1636
 * Remove a profile from the database.
1637
 */
1638
function ckeditor_profile_delete($name) {
1639
  db_delete('ckeditor_settings')
1640
      ->condition('name', $name)
1641
      ->execute();
1642
  db_delete('ckeditor_input_format')
1643
      ->condition('name', $name)
1644
      ->execute();
1645
}
1646

    
1647
/*
1648
 * List of CKEditor librares to load
1649
 */
1650

    
1651
function _ckeditor_load_methods() {
1652
  $result = array('ckeditor.js' => 'ckeditor.js');
1653
  $ckeditor_local_path = ckeditor_path('local');
1654
  if ($ckeditor_local_path == '<URL>') {
1655
    return $result;
1656
  }
1657
  if (file_exists($ckeditor_local_path . '/ckeditor_basic.js')) {
1658
    $result['ckeditor_basic.js'] = 'ckeditor_basic.js';
1659
  }
1660
  if (file_exists($ckeditor_local_path . '/ckeditor_source.js')) {
1661
    $result['ckeditor_source.js'] = 'ckeditor_source.js (' . t('for developers only') . ')';
1662
  }
1663
  return $result;
1664
}
1665

    
1666
/*
1667
 * Disable WYSIWYG module
1668
 */
1669

    
1670
function ckeditor_disable_wysiwyg($token) {
1671
  if (!drupal_valid_token($token, 'ckeditorDisableWysiwyg')) {
1672
    exit();
1673
  }
1674
  module_disable(array('wysiwyg'));
1675
  drupal_set_message(t('The WYSIWYG module is disabled.'));
1676

    
1677
  drupal_goto('admin/config/content/ckeditor');
1678
}
1679

    
1680
/*
1681
 * Get all available toolbar buttons
1682
 */
1683

    
1684
function ckeditor_toolbar_buttons_all() {
1685
  $path = base_path() . drupal_get_path('module', 'ckeditor');
1686

    
1687
  //CKEditor default buttons
1688
  $buttons = array(
1689
    'Source' => array('name' => 'Source', 'icon' => $path . '/images/buttons/source.png', 'title' => 'Source', 'row' => 1),
1690
    'Save' => array('name' => 'Save', 'icon' => $path . '/images/buttons/save.png', 'title' => 'Save', 'row' => 1),
1691
    'NewPage' => array('name' => 'NewPage', 'icon' => $path . '/images/buttons/newpage.png', 'title' => 'New Page', 'row' => 1),
1692
    'Preview' => array('name' => 'Preview', 'icon' => $path . '/images/buttons/preview.png', 'title' => 'Preview', 'row' => 1),
1693
    'Templates' => array('name' => 'Templates', 'icon' => $path . '/images/buttons/templates.png', 'title' => 'Templates', 'row' => 1),
1694
    'Cut' => array('name' => 'Cut', 'icon' => $path . '/images/buttons/cut.png', 'title' => 'Cut', 'row' => 1),
1695
    'Copy' => array('name' => 'Copy', 'icon' => $path . '/images/buttons/copy.png', 'title' => 'Copy', 'row' => 1),
1696
    'Paste' => array('name' => 'Paste', 'icon' => $path . '/images/buttons/paste.png', 'title' => 'Paste', 'row' => 1),
1697
    'PasteText' => array('name' => 'PasteText', 'icon' => $path . '/images/buttons/pastetext.png', 'title' => 'Paste as plain text', 'row' => 1),
1698
    'PasteFromWord' => array('name' => 'PasteFromWord', 'icon' => $path . '/images/buttons/pastefromword.png', 'title' => 'Paste from Word', 'row' => 1),
1699
    'Print' => array('name' => 'Print', 'icon' => $path . '/images/buttons/print.png', 'title' => 'Print', 'row' => 1),
1700
    'SpellChecker' => array('name' => 'SpellChecker', 'icon' => $path . '/images/buttons/spellchecker.png', 'title' => 'Check Spelling', 'row' => 1),
1701
    'Scayt' => array('name' => 'Scayt', 'icon' => $path . '/images/buttons/scayt.png', 'title' => 'Spell Check As you Type', 'row' => 1), //TODO sprawdzic ta opcje
1702
    'Undo' => array('name' => 'Undo', 'icon' => $path . '/images/buttons/undo.png', 'title' => 'Undo', 'row' => 1),
1703
    'Redo' => array('name' => 'Redo', 'icon' => $path . '/images/buttons/redo.png', 'title' => 'Redo', 'row' => 1),
1704
    'Find' => array('name' => 'Find', 'icon' => $path . '/images/buttons/find.png', 'title' => 'Find', 'row' => 1),
1705
    'Replace' => array('name' => 'Replace', 'icon' => $path . '/images/buttons/replace.png', 'title' => 'Replace', 'row' => 1),
1706
    'SelectAll' => array('name' => 'SelectAll', 'icon' => $path . '/images/buttons/selectall.png', 'title' => 'Select All', 'row' => 1),
1707
    'RemoveFormat' => array('name' => 'RemoveFormat', 'icon' => $path . '/images/buttons/removeformat.png', 'title' => 'Remove Format', 'row' => 1),
1708
    'Form' => array('name' => 'Form', 'icon' => $path . '/images/buttons/form.png', 'title' => 'Form', 'row' => 1),
1709
    'Checkbox' => array('name' => 'Checkbox', 'icon' => $path . '/images/buttons/checkbox.png', 'title' => 'Checkbox', 'row' => 1),
1710
    'Radio' => array('name' => 'Radio', 'icon' => $path . '/images/buttons/radio.png', 'title' => 'Radio Button', 'row' => 1),
1711
    'TextField' => array('name' => 'TextField', 'icon' => $path . '/images/buttons/textfield.png', 'title' => 'Text Field', 'row' => 1),
1712
    'Textarea' => array('name' => 'Textarea', 'icon' => $path . '/images/buttons/textarea.png', 'title' => 'Textarea', 'row' => 1),
1713
    'Select' => array('name' => 'Select', 'icon' => $path . '/images/buttons/select.png', 'title' => 'Selection Field', 'row' => 1),
1714
    'Button' => array('name' => 'Button', 'icon' => $path . '/images/buttons/button.png', 'title' => 'Button', 'row' => 1),
1715
    'ImageButton' => array('name' => 'ImageButton', 'icon' => $path . '/images/buttons/imagebutton.png', 'title' => 'Image Button', 'row' => 1),
1716
    'HiddenField' => array('name' => 'HiddenField', 'icon' => $path . '/images/buttons/hiddenfield.png', 'title' => 'Hidden Field', 'row' => 1),
1717
    'Bold' => array('name' => 'Bold', 'icon' => $path . '/images/buttons/bold.png', 'title' => 'Bold', 'row' => 2),
1718
    'Italic' => array('name' => 'Italic', 'icon' => $path . '/images/buttons/italic.png', 'type' => 'command', 'title' => 'Italic', 'row' => 2),
1719
    'Underline' => array('name' => 'Underline', 'icon' => $path . '/images/buttons/underline.png', 'title' => 'Underline', 'row' => 2),
1720
    'Strike' => array('name' => 'Strike', 'icon' => $path . '/images/buttons/strike.png', 'title' => 'Strike Through', 'row' => 2),
1721
    'Subscript' => array('name' => 'Subscript', 'icon' => $path . '/images/buttons/subscript.png', 'title' => 'Subscript', 'row' => 2),
1722
    'Superscript' => array('name' => 'Superscript', 'icon' => $path . '/images/buttons/superscript.png', 'title' => 'Superscript', 'row' => 2),
1723
    'NumberedList' => array('name' => 'NumberedList', 'icon' => $path . '/images/buttons/numberedlist.png', 'title' => 'Insert/Remove Numbered List', 'row' => 2),
1724
    'BulletedList' => array('name' => 'BulletedList', 'icon' => $path . '/images/buttons/bulletedlist.png', 'title' => 'Insert/Remove Bulleted List', 'row' => 2),
1725
    'Outdent' => array('name' => 'Outdent', 'icon' => $path . '/images/buttons/outdent.png', 'title' => 'Decrease Indent', 'row' => 2),
1726
    'Indent' => array('name' => 'Indent', 'icon' => $path . '/images/buttons/indent.png', 'title' => 'Increase Indent', 'row' => 2),
1727
    'Blockquote' => array('name' => 'Blockquote', 'icon' => $path . '/images/buttons/blockquote.png', 'title' => 'Block Quote', 'row' => 2),
1728
    'CreateDiv' => array('name' => 'CreateDiv', 'icon' => $path . '/images/buttons/creatediv.png', 'title' => 'Create Div Container', 'row' => 2),
1729
    'JustifyLeft' => array('name' => 'JustifyLeft', 'icon' => $path . '/images/buttons/justifyleft.png', 'title' => 'Left Justify', 'row' => 2),
1730
    'JustifyCenter' => array('name' => 'JustifyCenter', 'icon' => $path . '/images/buttons/justifycenter.png', 'title' => 'Center Justify', 'row' => 2),
1731
    'JustifyRight' => array('name' => 'JustifyRight', 'icon' => $path . '/images/buttons/justifyright.png', 'title' => 'Right Justify', 'row' => 2),
1732
    'JustifyBlock' => array('name' => 'JustifyBlock', 'icon' => $path . '/images/buttons/justifyblock.png', 'title' => 'Block Justify', 'row' => 2),
1733
    'BidiLtr' => array('name' => 'BidiLtr', 'icon' => $path . '/images/buttons/bidiltr.png', 'title' => 'Text direction from left to right', 'row' => 2),
1734
    'BidiRtl' => array('name' => 'BidiRtl', 'icon' => $path . '/images/buttons/bidirtl.png', 'title' => 'Text direction from right to left', 'row' => 2),
1735
    'Language' => array('name' => 'Language', 'icon' => $path . '/images/buttons/language.png', 'title' => 'Set Language', 'row' => 2),
1736
    'Link' => array('name' => 'Link', 'icon' => $path . '/images/buttons/link.png', 'title' => 'Link', 'row' => 2),
1737
    'Unlink' => array('name' => 'Unlink', 'icon' => $path . '/images/buttons/unlink.png', 'title' => 'Unlink', 'row' => 2),
1738
    'Anchor' => array('name' => 'Anchor', 'icon' => $path . '/images/buttons/anchor.png', 'title' => 'Anchor', 'row' => 2),
1739
    'Image' => array('name' => 'Image', 'icon' => $path . '/images/buttons/image.png', 'title' => 'Image', 'row' => 2),
1740
    'Flash' => array('name' => 'Flash', 'icon' => $path . '/images/buttons/flash.png', 'title' => 'Flash', 'row' => 2),
1741
    'Table' => array('name' => 'Table', 'icon' => $path . '/images/buttons/table.png', 'title' => 'Table', 'row' => 2),
1742
    'HorizontalRule' => array('name' => 'HorizontalRule', 'icon' => $path . '/images/buttons/horizontalrule.png', 'title' => 'Insert Horizontal Line', 'row' => 2),
1743
    'Smiley' => array('name' => 'Smiley', 'icon' => $path . '/images/buttons/smiley.png', 'title' => 'Smiley', 'row' => 2),
1744
    'SpecialChar' => array('name' => 'SpecialChar', 'icon' => $path . '/images/buttons/specialchar.png', 'title' => 'Insert Special Character', 'row' => 2),
1745
    'PageBreak' => array('name' => 'PageBreak', 'icon' => $path . '/images/buttons/pagebreak.png', 'title' => 'Insert Page Break for Printing', 'row' => 2),
1746
    'Styles' => array('name' => 'Styles', 'icon' => $path . '/images/buttons/styles.png', 'title' => 'Formatting Styles', 'row' => 3),
1747
    'Format' => array('name' => 'Format', 'icon' => $path . '/images/buttons/format.png', 'title' => 'Paragraph Format', 'row' => 3),
1748
    'Font' => array('name' => 'Font', 'icon' => $path . '/images/buttons/font.png', 'title' => 'Font Name', 'row' => 3),
1749
    'FontSize' => array('name' => 'FontSize', 'icon' => $path . '/images/buttons/size.png', 'title' => 'Font Size', 'row' => 3),
1750
    'TextColor' => array('name' => 'TextColor', 'icon' => $path . '/images/buttons/textcolor.png', 'title' => 'Text Color', 'row' => 3),
1751
    'BGColor' => array('name' => 'BGColor', 'icon' => $path . '/images/buttons/bgcolor.png', 'title' => 'Background Color', 'row' => 3),
1752
    'Maximize' => array('name' => 'Maximize', 'icon' => $path . '/images/buttons/maximize.png', 'title' => 'Maximize', 'row' => 3),
1753
    'ShowBlocks' => array('name' => 'ShowBlocks', 'icon' => $path . '/images/buttons/showblocks.png', 'title' => 'Show Blocks', 'row' => 3),
1754
    'Iframe' => array('name' => 'Iframe', 'icon' => $path . '/images/buttons/iframe.png', 'title' => 'IFrame', 'row' => 3),
1755
    'About' => array('name' => 'About', 'icon' => $path . '/images/buttons/about.png', 'title' => 'About', 'row' => 3),
1756
    '__spacer' => array('name' => FALSE, 'icon' => $path . '/images/buttons/spacer.png', 'title' => 'Spacer', 'row' => 4),
1757
    '__group' => array('name' => FALSE, 'icon' => $path . '/images/buttons/group.png', 'title' => 'Group', 'row' => 4)
1758
  );
1759

    
1760
  $plugins = ckeditor_load_plugins(TRUE);
1761

    
1762
  foreach ($plugins as $plugin_name => $plugin) {
1763
    if (empty($plugin['buttons'])) {
1764
      continue;
1765
    }
1766
    foreach ((array) $plugin['buttons'] as $button_name => $button) {
1767
      $buttons[$button_name] = array(
1768
        'name' => $button_name,
1769
        'icon' => !empty($button['icon_path']) ? $button['icon_path'] . $button['icon'] : $plugin['path'] . $button['icon'],
1770
        'title' => t($button['label']),
1771
        'row' => 4,
1772
      );
1773
    }
1774
  }
1775

    
1776
  return $buttons;
1777
}
1778

    
1779
/**
1780
 * Add security filters to the configuration panel available in the CKEditor profile administration section
1781
 */
1782
function _ckeditor_admin_profile_form_security_filters(&$form, $profile, $security_filters) {
1783
  foreach ((array) $security_filters['modules'] as $module_name => $module_conf) {
1784
    if (isset($module_conf['project_page']) && strlen($module_conf['project_page']) > 0) {
1785
      $form['security']['filters'][$module_name] = array(
1786
        '#type' => 'fieldset',
1787
        '#title' => t(
1788
            "!title <a href=\"!link\" target=\"_blank\">project page</a>", array(
1789
          "!title" => $module_conf['title'],
1790
          "!link" => $module_conf['project_page']
1791
            )
1792
        ),
1793
        '#weight' => $module_conf['weight']
1794
      );
1795
    }
1796
    else {
1797
      $form['security']['filters'][$module_name] = array(
1798
        '#type' => 'fieldset',
1799
        '#title' => t("!title", array("!title" => $module_conf['title'])),
1800
        '#weight' => $module_conf['weight']
1801
      );
1802
    }
1803

    
1804
    if ($module_conf['installed'] == TRUE) {
1805
      foreach ((array) $module_conf['filters'] as $filter_name => $filter_conf) {
1806
        $filter_text_formats = '<div class="filter-text-formats" filter="' . $filter_name . '"></div><div class="filter-info">';
1807
        $form['security']['filters'][$module_name][$filter_name] = array(
1808
          '#type' => 'item',
1809
          '#title' => t("@data", array('@data' => $filter_conf['title'])),
1810
          '#description' => t("!data", array('!data' => $filter_conf['description'])),
1811
          '#prefix' => "<div class=\"filter-wrapper\"></div>" . $filter_text_formats,
1812
          '#suffix' => "</div>"
1813
        );
1814
      }
1815
    }
1816
    else {
1817
      $form['security']['filters'][$module_name]['not_installed'] = array(
1818
        '#markup' => t("<i>Not installed</i>")
1819
      );
1820
    }
1821
  }
1822
}
1823

    
1824
function ckeditor_skinframe() {
1825
  header('Content-Type: text/html; charset=utf-8');
1826

    
1827
  if (!isset($_GET['token']) || !drupal_valid_token($_GET['token'], 'ckeditorSkinframeCall')) {
1828
    exit;
1829
  }
1830

    
1831
  $editor_path = ckeditor_path('relative');
1832
  if ($editor_path == '<URL>')
1833
    $editor_path = ckeditor_path('url');
1834
  $module_drupal_path = ckeditor_module_path('relative');
1835

    
1836
  $html = "<!DOCTYPE html>";
1837
  $html .= "<html>";
1838
  $html .= "<head>";
1839
  $html .= '<title>CKEditor UI Color Picker</title>';
1840
  $html .= "<script type=\"text/javascript\" src=\"{$editor_path}/ckeditor.js\"></script>";
1841
  $html .= "</head>";
1842
  $html .= "<body>";
1843
  $html .= "<input type=\"hidden\" name=\"uicolor_user\"/>";
1844
  $html .= "<div id=\"editor\" style=\"height: 200px;\">Click the <strong>UI Color Picker</strong> button to set your color preferences.</div>";
1845
  $html .= "<script type=\"text/javascript\">
1846
var skin = window.location.search.match(/skin=([^&]*)/)[1];
1847
var uicolor = window.location.search.match(/uicolor=([^&]*)/)[1];
1848
var ckeditorUiColorOnChange = function() {
1849
  var color = CKEDITOR.instances['editor'].getUiColor();
1850
  if (typeof(color) != 'undefined') {
1851
    document.getElementsByName('uicolor_user').value = parent.document.getElementsByName('uicolor_user')[0].value = color;
1852
    var edit_uicolor = parent.document.getElementById('edit-uicolor');
1853
    for (i=0; i<edit_uicolor.options.length; i++) {
1854
      if (edit_uicolor[i].value == 'custom') {
1855
        edit_uicolor.selectedIndex = i;
1856
        edit_uicolor[i].selected = 'selected';
1857
        break;
1858
      }
1859
    }
1860
  }
1861
};
1862
CKEDITOR.on('dialogDefinition', function( ev ) {
1863
  var dialogName = ev.data.name;
1864
  var dialogDefinition = ev.data.definition;
1865

    
1866
  if (dialogName == 'uicolor') {
1867
    dialogDefinition.getContents('tab1').get('configBox').style = 'display:none';
1868
  }
1869
});
1870
CKEDITOR.replace('editor', {
1871
  extraPlugins : 'uicolor',
1872
  height: 330,
1873
  uiColor: '#' + uicolor,
1874
  toolbar : [[ 'Bold', 'Italic', '-', 'NumberedList', 'BulletedList'],[ 'UIColor' ]],
1875
  skin: skin,
1876
  on: {
1877
    configLoaded: function(ev) {
1878
      var ckeditor_ver = CKEDITOR.version.split('.')[0];
1879
      if (ckeditor_ver == 3) {
1880
        if (skin != 'kama') {
1881
          ev.editor.config.toolbar = [[ 'Bold', 'Italic', '-', 'NumberedList', 'BulletedList']];
1882
        }
1883
      }
1884
      else {
1885
        CKEDITOR.plugins.addExternal('uicolor', '{$module_drupal_path}/includes/uicolor/', 'plugin.js');
1886
        if (uicolor.length == 0 || uicolor == 'default') {
1887
          delete ev.editor.config.uiColor;
1888
        }
1889
      }
1890
    },
1891
    blur: ckeditorUiColorOnChange,
1892
    focus: ckeditorUiColorOnChange
1893
  }
1894
});
1895
</script>";
1896
  $html .= "</body>";
1897
  $html .= "</html>";
1898
  echo $html;
1899
}