Projet

Général

Profil

Paste
Télécharger (26,9 ko) Statistiques
| Branche: | Révision:

root / drupal7 / sites / all / modules / ckeditor / ckeditor.module @ 0695d136

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
 * The name of the simplified toolbar that should be forced.
38
 * Make sure that this toolbar is defined in ckeditor.config.js or fckconfig.js.
39
 */
40
define('CKEDITOR_FORCE_SIMPLE_TOOLBAR_NAME', 'DrupalBasic');
41
define('CKEDITOR_ENTERMODE_P', 1);
42
define('CKEDITOR_ENTERMODE_BR', 2);
43
define('CKEDITOR_ENTERMODE_DIV', 3);
44

    
45
global $_ckeditor_configuration;
46
global $_ckeditor_ids;
47

    
48
module_load_include('inc', 'ckeditor', 'includes/ckeditor.user');
49

    
50
$_ckeditor_configuration = array();
51
$_ckeditor_ids = array();
52

    
53
/**
54
 * Implementation of hook_menu().
55
 */
56
function ckeditor_menu() {
57
  $items = array();
58

    
59
  $items['ckeditor/xss'] = array(
60
    'title' => 'XSS Filter',
61
    'description' => 'XSS Filter.',
62
    'page callback' => 'ckeditor_filter_xss',
63
    'file' => 'includes/ckeditor.page.inc',
64
    'access callback' => TRUE,
65
    'type' => MENU_CALLBACK,
66
  );
67

    
68
  $items['ckeditor/disable/wysiwyg/%'] = array(
69
    'title' => 'Disable the WYSIWYG module',
70
    'description' => 'Disable WYSIWYG module.',
71
    'page callback' => 'ckeditor_disable_wysiwyg',
72
    'page arguments' => array(3),
73
    'file' => 'includes/ckeditor.admin.inc',
74
    'access arguments' => array('administer ckeditor'),
75
    'access callback' => TRUE,
76
    'type' => MENU_CALLBACK,
77
  );
78

    
79
  $items['admin/config/content/ckeditor'] = array(
80
    'title' => 'CKEditor',
81
    'description' => 'Configure the rich text editor.',
82
    'page callback' => 'ckeditor_admin_main',
83
    'file' => 'includes/ckeditor.admin.inc',
84
    'access arguments' => array('administer ckeditor'),
85
    'type' => MENU_NORMAL_ITEM,
86
  );
87

    
88
  $items['admin/config/content/ckeditor/skinframe'] = array(
89
    'title' => 'Change skin of CKEditor',
90
    'description' => 'Configure skin for CKEditor.',
91
    'page callback' => 'ckeditor_skinframe',
92
    'file' => 'includes/ckeditor.admin.inc',
93
    'access arguments' => array('administer ckeditor'),
94
    'type' => MENU_CALLBACK,
95
  );
96

    
97
  $items['admin/config/content/ckeditor/add'] = array(
98
    'title' => 'Add a new CKEditor profile',
99
    'description' => 'Configure the rich text editor.',
100
    'page callback' => 'drupal_get_form',
101
    'page arguments' => array('ckeditor_admin_profile_form', 'add'),
102
    'file' => 'includes/ckeditor.admin.inc',
103
    'access arguments' => array('administer ckeditor'),
104
    'type' => MENU_CALLBACK,
105
  );
106

    
107
  $items['admin/config/content/ckeditor/clone/%ckeditor_profile'] = array(
108
    'title' => 'Clone the CKEditor profile',
109
    'description' => 'Configure the rich text editor.',
110
    'page callback' => 'drupal_get_form',
111
    'page arguments' => array('ckeditor_admin_profile_clone_form', 'clone', 5),
112
    'file' => 'includes/ckeditor.admin.inc',
113
    'access arguments' => array('administer ckeditor'),
114
    'type' => MENU_CALLBACK,
115
  );
116

    
117
  $items['admin/config/content/ckeditor/edit/%ckeditor_profile'] = array(
118
    'title' => 'Edit the CKEditor profile',
119
    'description' => 'Configure the rich text editor.',
120
    'page callback' => 'drupal_get_form',
121
    'page arguments' => array('ckeditor_admin_profile_form', 'edit', 5),
122
    'file' => 'includes/ckeditor.admin.inc',
123
    'access arguments' => array('administer ckeditor'),
124
    'type' => MENU_CALLBACK,
125
  );
126

    
127
  $items['admin/config/content/ckeditor/delete/%ckeditor_profile'] = array(
128
    'title' => 'Delete the CKEditor profile',
129
    'description' => 'Configure the rich text editor.',
130
    'page callback' => 'drupal_get_form',
131
    'page arguments' => array('ckeditor_admin_profile_delete_form', 5),
132
    'file' => 'includes/ckeditor.admin.inc',
133
    'access arguments' => array('administer ckeditor'),
134
    'type' => MENU_CALLBACK,
135
  );
136

    
137
  $items['admin/config/content/ckeditor/addg'] = array(
138
    'title' => 'Add the CKEditor Global profile',
139
    'description' => 'Configure the rich text editor.',
140
    'page callback' => 'drupal_get_form',
141
    'page arguments' => array('ckeditor_admin_global_profile_form', 'add'),
142
    'file' => 'includes/ckeditor.admin.inc',
143
    'access arguments' => array('administer ckeditor'),
144
    'type' => MENU_CALLBACK,
145
  );
146

    
147
  $items['admin/config/content/ckeditor/editg'] = array(
148
    'title' => 'Edit the CKEditor Global profile',
149
    'description' => 'Configure the rich text editor.',
150
    'page callback' => 'drupal_get_form',
151
    'page arguments' => array('ckeditor_admin_global_profile_form', 'edit'),
152
    'file' => 'includes/ckeditor.admin.inc',
153
    'access arguments' => array('administer ckeditor'),
154
    'type' => MENU_CALLBACK,
155
  );
156

    
157
  return $items;
158
}
159

    
160
/**
161
 * Implementation of hook_permission().
162
 *
163
 * People -> Permissions
164
 */
165
function ckeditor_permission() {
166
  $arr = array();
167
  $arr['administer ckeditor'] = array(
168
    'title' => t('Administer CKEditor access'),
169
    'description' => t('Allow users to change CKEditor settings.')
170
  );
171

    
172
  $arr['customize ckeditor'] = array(
173
    'title' => t('Customize CKEditor appearance'),
174
    'description' => t('Allow users to customize CKEditor appearance.')
175
  );
176

    
177
  if (file_exists(ckfinder_path('local'))) {
178
    $arr['allow CKFinder file uploads'] = array(
179
      'title' => t('CKFinder access'),
180
      'description' => t('Allow users to use CKFinder.')
181
    );
182
  }
183
  return $arr;
184
}
185

    
186
/**
187
 * Implementation of hook_help().
188
 *
189
 * This function delegates the execution to ckeditor_help_delegate() in includes/ckeditor.page.inc to
190
 * lower the amount of code in ckeditor.module.
191
 */
192
function ckeditor_help($path, $arg) {
193
  module_load_include('inc', 'ckeditor', 'includes/ckeditor.page');
194
  return module_invoke('ckeditor', 'help_delegate', $path, $arg);
195
}
196

    
197
/**
198
 * Check CKEditor version
199
 */
200
function ckeditor_get_version($main_version = FALSE) {
201
  static $ckeditor_version = FALSE;
202

    
203
  if ($ckeditor_version !== FALSE) {
204
    if (!$main_version) {
205
      return $ckeditor_version;
206
    }
207
    $version = explode('.', $ckeditor_version);
208
    return trim($version[0]);
209
  }
210

    
211
  $editor_path = ckeditor_path('local', TRUE);
212
  if ($editor_path == '<URL>') {
213
    $url = ckeditor_path('url', TRUE);
214
    $matches = array();
215
    if (preg_match("|cdn.ckeditor.com/(\d(\.\d+)+.*)/|i", $url, $matches)) {
216
      $ckeditor_version = $matches[1];
217
      return $matches[1];
218
    }
219
    return $ckeditor_version = NULL;
220
  }
221

    
222
  $jspath = $editor_path . '/ckeditor.js';
223

    
224
  $configcontents = @file_get_contents($jspath);
225
  if (!$configcontents) {
226
    return $ckeditor_version = NULL;
227
  }
228
  $matches = array();
229
  if (preg_match('#,version:[\'\"]{1}(.*?)[\'\"]{1},#', $configcontents, $matches)) {
230
    $ckeditor_version = $matches[1];
231
    if ($ckeditor_version == '%VERSION%') {
232
      $ckeditor_version = '4.0.0';
233
    }
234
    if (!$main_version) {
235
      return $ckeditor_version;
236
    }
237
    $version = explode('.', $ckeditor_version);
238
    return trim($version[0]);
239
  }
240
  return $ckeditor_version = NULL;
241
}
242

    
243
/**
244
 * Implements hook_page_build().
245
 */
246
function ckeditor_page_build(&$page) {
247
  // Add our CSS file that adds common needed classes, such as align-left,
248
  // align-right, underline, indent, etc.
249
  $page['page_bottom']['ckeditor']['#attached']['css'] = array(
250
    drupal_get_path('module', 'ckeditor') . '/css/ckeditor.css' => array(
251
      'every_page' => TRUE,
252
    ),
253
  );
254
}
255

    
256
/**
257
 * Implements hook_form_FORM_ID_alter() for user_profile_form().
258
 */
259
function ckeditor_form_user_profile_form_alter(&$form, &$form_state) {
260
  if ($form['#user_category'] == 'account') {
261
    ckeditor_user_customize($form, $form_state, 'user_profile_form');
262
  }
263
}
264

    
265
/**
266
 * Implementation of hook_element_info_alter().
267
 *
268
 * Replace the textarea with CKEditor using a callback function (ckeditor_pre_render_text_format).
269
 */
270
function ckeditor_element_info_alter(&$types) {
271
  $types['text_format']['#pre_render'][] = 'ckeditor_pre_render_text_format';
272
}
273

    
274
/**
275
 * This function creates the HTML objects required for CKEditor.
276
 *
277
 * @param $element
278
 *   A fully populated form element to add the editor to.
279
 * @return
280
 *   The same $element with extra CKEditor markup and initialization.
281
 */
282
function ckeditor_pre_render_text_format($element) {
283
  static $init = FALSE;
284
  if (!isset($element['#format'])) {
285
    return $element;
286
  }
287

    
288
  module_load_include('inc', 'ckeditor', 'includes/ckeditor.lib');
289
  if ($init === FALSE) {
290
    $input_formats = ckeditor_profiles_compile();
291
    drupal_add_js(array('ckeditor' => array('input_formats' => $input_formats, 'plugins' => array())), 'setting');
292
    $init = TRUE;
293
  }
294

    
295
  if (isset($element['value'])) {
296
    if (!isset($element['format'])) {
297
      return $element;
298
    }
299
    if (isset($element['summary'])) {
300
      $element['value'] = ckeditor_load_by_field($element['value'], $element['format']['format'], TRUE, $element['summary']['#id']);
301
      $element['summary'] = ckeditor_load_by_field($element['summary'], $element['format']['format'], FALSE);
302
    }
303
    else {
304
      $element['value'] = ckeditor_load_by_field($element['value'], $element['format']['format']);
305
    }
306
  }
307
  else {
308
    $element = ckeditor_load_by_field($element, $element['#format']);
309
  }
310

    
311
  return $element;
312
}
313

    
314
/**
315
 * Load all profiles. Just load one profile if $name is passed in.
316
 */
317
function ckeditor_profile_load($name = '', $clear = FALSE, $check_access = TRUE) {
318
  static $profiles = array();
319
  global $user;
320

    
321
  if (empty($profiles) || $clear === TRUE) {
322
    $result = db_select('ckeditor_settings', 's')->fields('s')->execute();
323
    foreach ($result as $data) {
324
      $data->settings = unserialize($data->settings);
325
      $data->input_formats = array();
326

    
327
      $profiles[$data->name] = $data;
328
    }
329
    if ($check_access === FALSE) {
330
      // don't check if user has access to filter formats, needed for exporting as feature with drush
331
      $input_formats = filter_formats();
332
    } else {
333
      $input_formats = filter_formats($user);
334
    }
335
    $result = db_select('ckeditor_input_format', 'f')->fields('f')->execute();
336
    foreach ($result as $data) {
337
      if (isset($input_formats[$data->format])) {
338
        $profiles[$data->name]->input_formats[$data->format] = $input_formats[$data->format]->name;
339
      }
340
    }
341
  }
342

    
343
  return ($name ? (isset($profiles[urldecode($name)]) ? $profiles[urldecode($name)] : FALSE) : $profiles);
344
}
345

    
346
/**
347
 * Generate base path of the Drupal installation.
348
 *
349
 * @return
350
 *   Path of the Drupal installation.
351
 */
352
function ckeditor_base_path($mode = 'relative') {
353
  if ($mode == 'local') {
354
    return $cke_base_local_path = '.';
355
  }
356
  return rtrim(base_path(), '/');
357
}
358

    
359
/**
360
 * Generate module path of the CKEditor module.
361
 *
362
 * @return
363
 *   Path of CKEditor module.
364
 */
365
function ckeditor_module_path($mode = 'relative') {
366
  switch ($mode) {
367
    default:
368
    case 'relative':
369
      return ckeditor_base_path('relative') . '/' . drupal_get_path('module', 'ckeditor');
370
    case 'local':
371
      return ckeditor_base_path('local') . '/' . drupal_get_path('module', 'ckeditor');
372
    case 'url':
373
      return drupal_get_path('module', 'ckeditor');
374
  }
375
}
376

    
377
/**
378
 * Generate library path of the Drupal installation.
379
 *
380
 * @return
381
 *   Path of library in the Drupal installation.
382
 */
383
function ckeditor_library_path($mode = 'relative') {
384
  $lib_path = 'sites/all/libraries';
385

    
386
  if (function_exists('libraries_get_path')) {
387
    $path = libraries_get_path('ckeditor');
388
    if ($path !== FALSE) {
389
      $lib_path = drupal_substr($path, 0, strlen($path) - 9);
390
    }
391
  }
392
  switch ($mode) {
393
    default:
394
    case 'relative':
395
      return ckeditor_base_path('relative') . '/' . $lib_path;
396
    case 'local':
397
      return ckeditor_base_path('local') . '/' . $lib_path;
398
    case 'url':
399
      return $lib_path;
400
  }
401
}
402

    
403
/**
404
 * Read the CKEditor path from the Global profile.
405
 *
406
 * @return
407
 *   Path to CKEditor folder.
408
 */
409
function ckeditor_path($mode = 'relative', $refresh = FALSE) {
410
  static $cke_static;
411

    
412
  if (!isset($cke_static)) {
413
    $cke_static = array();
414
  }
415

    
416
  if ($refresh || !isset($cke_static[$mode])) {
417
    $global_profile = ckeditor_profile_load('CKEditor Global Profile', $refresh);
418
    switch ($mode) {
419
      default:
420
      case 'relative':
421
        if ($global_profile && isset($global_profile->settings['ckeditor_path'])) {
422
          // http:// OR https:// OR //
423
          if (preg_match("|^(http(s)?:)?//|i", $global_profile->settings['ckeditor_path'])) {
424
            return '<URL>';
425
          }
426
          $cke_path = $global_profile->settings['ckeditor_path'];
427
          $cke_path = strtr($cke_path, array("%b" => ckeditor_base_path('relative'), "%m" => ckeditor_module_path('relative'), "%l" => ckeditor_library_path('relative')));
428
          $cke_path = str_replace('\\', '/', $cke_path);
429
          $cke_path = str_replace('//', '/', $cke_path);
430
          return $cke_static[$mode] = $cke_path;
431
        }
432
        return $cke_static[$mode] = ckeditor_module_path('relative') . '/ckeditor';
433
      case 'local':
434
        if ($global_profile) {
435
          if (!empty($global_profile->settings['ckeditor_local_path'])) {
436
            return $cke_static[$mode] = $global_profile->settings['ckeditor_local_path'];
437
          }
438
          if (isset($global_profile->settings['ckeditor_path'])) {
439
            // http:// OR https:// OR //
440
            if (preg_match("|^(http(s)?:)?//|i", $global_profile->settings['ckeditor_path'])) {
441
              return '<URL>';
442
            }
443
            $cke_local_path = $global_profile->settings['ckeditor_path'];
444
            $cke_local_path = strtr($cke_local_path, array("%b" => ckeditor_base_path('local'), "%m" => ckeditor_module_path('local'), "%l" => ckeditor_library_path('local')));
445
            return $cke_static[$mode] = $cke_local_path;
446
          }
447
        }
448
        return $cke_static[$mode] = ckeditor_module_path('local') . '/ckeditor';
449
      case 'url':
450
        if ($global_profile && isset($global_profile->settings['ckeditor_path'])) {
451
          // http:// OR https:// OR //
452
          if (preg_match("|^(http(s)?:)?//|i", $global_profile->settings['ckeditor_path'])) {
453
            $cke_path = $global_profile->settings['ckeditor_path'];
454
          }
455
          else {
456
            $cke_path = $global_profile->settings['ckeditor_path'];
457
            $cke_path = strtr($cke_path, array("%m" => ckeditor_module_path('url'), "%l" => ckeditor_library_path('url')));
458
            $cke_path = str_replace('\\', '/', $cke_path);
459
            $cke_path = str_replace('//', '/', $cke_path);
460
            //In D7 base path in URL mode is not needed, so we need to remove it with trailing slash (if exists)
461
            $cke_path = str_replace(array("%b/", "%b"), '', $cke_path);
462
          }
463
          return $cke_static[$mode] = $cke_path;
464
        }
465
        return $cke_static[$mode] = ckeditor_module_path('url') . '/ckeditor';
466
    }
467
  }
468
  return $cke_static[$mode];
469
}
470

    
471
/**
472
 * Read the CKEditor plugins path from the Global profile.
473
 *
474
 * @return
475
 *   Path to CKEditor plugins folder.
476
 */
477
function ckeditor_plugins_path($mode = 'relative', $refresh = FALSE) {
478
  static $cke_static;
479

    
480
  if (!isset($cke_static)) {
481
    $cke_static = array();
482
  }
483

    
484
  if ($refresh || !isset($cke_static[$mode])) {
485
    $global_profile = ckeditor_profile_load('CKEditor Global Profile', $refresh);
486
    switch ($mode) {
487
      default:
488
      case 'relative':
489
        if ($global_profile && isset($global_profile->settings['ckeditor_plugins_path'])) {
490
          $cke_plugins_path = $global_profile->settings['ckeditor_plugins_path'];
491
          $cke_plugins_path = strtr($cke_plugins_path, array("%b" => ckeditor_base_path('relative'), "%m" => ckeditor_module_path('relative'), "%l" => ckeditor_library_path('relative')));
492
          $cke_plugins_path = str_replace('\\', '/', $cke_plugins_path);
493
          $cke_plugins_path = str_replace('//', '/', $cke_plugins_path);
494
          $cke_plugins_path = rtrim($cke_plugins_path, ' \/');
495
          return $cke_static[$mode] = $cke_plugins_path;
496
        }
497
        return $cke_static[$mode] = ckeditor_module_path('relative') . '/plugins';
498
      case 'local':
499
        if ($global_profile) {
500
          if (!empty($global_profile->settings['ckeditor_plugins_local_path'])) {
501
            return $cke_static[$mode] = $global_profile->settings['ckeditor_plugins_local_path'];
502
          }
503
          if (isset($global_profile->settings['ckeditor_plugins_path'])) {
504
            $cke_plugins_local_path = $global_profile->settings['ckeditor_plugins_path'];
505
            $cke_plugins_local_path = strtr($cke_plugins_local_path, array("%b" => ckeditor_base_path('local'), "%m" => ckeditor_module_path('local'), "%l" => ckeditor_library_path('local')));
506
            return $cke_static[$mode] = $cke_plugins_local_path;
507
          }
508
        }
509
        return $cke_static[$mode] = ckeditor_module_path('local') . '/plugins';
510
      case 'url':
511
        if ($global_profile && isset($global_profile->settings['ckeditor_plugins_path'])) {
512
          $cke_plugins_path = $global_profile->settings['ckeditor_plugins_path'];
513
          $cke_plugins_path = strtr($cke_plugins_path, array("%m" => ckeditor_module_path('url'), "%l" => ckeditor_library_path('url')));
514
          $cke_plugins_path = str_replace('\\', '/', $cke_plugins_path);
515
          $cke_plugins_path = str_replace('//', '/', $cke_plugins_path);
516
          $cke_plugins_path = rtrim($cke_plugins_path, ' \/');
517
          //In D7 base path in URL mode is not needed, so we need to remove it with trailing slash (if exists)
518
          $cke_plugins_path = str_replace(array("%b/", "%b"), '', $cke_plugins_path);
519
          return $cke_static[$mode] = $cke_plugins_path;
520
        }
521
        return $cke_static[$mode] = ckeditor_module_path('url') . '/plugins';
522
    }
523
  }
524
  return $cke_static[$mode];
525
}
526

    
527
/**
528
 * Read the CKFinder path from the Global profile.
529
 *
530
 * @return
531
 *   Path to CKFinder folder.
532
 */
533
function ckfinder_path($mode = 'relative', $refresh = FALSE) {
534
 static $cke_static;
535

    
536
  if (!isset($cke_static)) {
537
    $cke_static = array();
538
  }
539

    
540
  if ($refresh || !isset($cke_static[$mode])) {
541
    $global_profile = ckeditor_profile_load('CKEditor Global Profile', $refresh);
542
    switch ($mode) {
543
      default:
544
      case 'relative':
545
        if ($global_profile && isset($global_profile->settings['ckfinder_path'])) {
546
          $ckfinder_path = $global_profile->settings['ckfinder_path'];
547
          $ckfinder_path = strtr($ckfinder_path, array("%b" => ckeditor_base_path('relative'), "%m" => ckeditor_module_path('relative'), "%l" => ckeditor_library_path('relative')));
548
          $ckfinder_path = str_replace('\\', '/', $ckfinder_path);
549
          $ckfinder_path = str_replace('//', '/', $ckfinder_path);
550
          return $cke_static[$mode] = $ckfinder_path;
551
        }
552
        return $cke_static[$mode] = ckeditor_module_path('relative') . '/ckfinder';
553
      case 'local':
554
        if ($global_profile) {
555
          if (!empty($global_profile->settings['ckfinder_local_path'])) {
556
            return $cke_static[$mode] = $global_profile->settings['ckfinder_local_path'];
557
          }
558
          if (isset($global_profile->settings['ckfinder_path'])) {
559
            $ckfinder_path = $global_profile->settings['ckfinder_path'];
560
            $ckfinder_path = strtr($ckfinder_path, array("%b" => ckeditor_base_path('local'), "%m" => ckeditor_module_path('local'), "%l" => ckeditor_library_path('local')));
561
            return $cke_static[$mode] = $ckfinder_path;
562
          }
563
        }
564
        return $cke_static[$mode] = ckeditor_module_path('local') . '/ckfinder';
565
      case 'url':
566
        if ($global_profile && isset($global_profile->settings['ckfinder_path'])) {
567
          $ckfinder_path = $global_profile->settings['ckfinder_path'];
568
          $ckfinder_path = strtr($ckfinder_path, array("%m" => ckeditor_module_path('url'), "%l" => ckeditor_library_path('url')));
569
          $ckfinder_path = str_replace('\\', '/', $cke_plugins_path);
570
          $ckfinder_path = str_replace('//', '/', $cke_plugins_path);
571
          //In D7 base path in URL mode is not needed, so we need to remove it with trailing slash (if exists)
572
          $ckfinder_path = str_replace(array("%b/", "%b"), '', $ckfinder_path);
573
          return $cke_static[$mode] = $ckfinder_path;
574
        }
575
        return $cke_static[$mode] = ckeditor_module_path('url') . '/ckfinder';
576
    }
577
  }
578
  return $cke_static[$mode];
579
}
580

    
581
/**
582
 * Implementation of hook_features_api().
583
 *
584
 * Allow exporting of CKEditor profiles by the Features module.
585
 */
586
function ckeditor_features_api() {
587
  return array(
588
    'ckeditor_profile' => array(
589
      'name' => t('CKEditor profiles'),
590
      'feature_source' => TRUE,
591
      'default_hook' => 'ckeditor_profile_defaults',
592
      'default_file' => FEATURES_DEFAULTS_INCLUDED,
593
      'file' => drupal_get_path('module', 'ckeditor') . '/includes/ckeditor.features.inc',
594
    )
595
  );
596
}
597

    
598
/**
599
 * Implementation of hook_file_download().
600
 * Support for private downloads.
601
 * CKEditor does not implement any kind of potection on private files.
602
 */
603
function ckeditor_file_download($uri) {
604
  if ($path = file_create_url($uri)) {
605
    $result = db_query("SELECT f.* FROM {file_managed} f WHERE uri = :uri", array(':uri' => $uri));
606
    foreach ($result as $record) {
607
      return NULL;
608
    }
609
    //No info in DB? Probably a file uploaded with FCKeditor / CKFinder
610
    $global_profile = ckeditor_profile_load("CKEditor Global Profile");
611
    //Assume that files inside of ckeditor directory belong to the CKEditor. If private directory is set, let the decision about protection to the user.
612
    $private_dir_db = $private_dir = isset($global_profile->settings['private_dir']) ? trim($global_profile->settings['private_dir'], '\/') : '';
613
    $private_dir_db = str_replace(array('\\%u', '\\%n'), array('', ''), $private_dir_db);
614
    $private_dir = preg_quote($private_dir, '#');
615
    $private_dir = strtr($private_dir, array('%u' => '(\d+)', '%n' => '([\x80-\xF7 \w@.-]+)')); // regex for %n taken from user_validate_name() in user.module
616
    $private_dir = trim($private_dir, '\/');
617

    
618
    $regex = '#^' . preg_quote('private://', '#') . $private_dir . '#';
619

    
620
    if (!strstr($uri, 'private://') && !strstr($uri, 'public://')) {
621
      $path = 'private://' . $uri;
622
    }
623
    else {
624
      $path = $uri;
625
    }
626
    //check if CKEditor's "Enable access to files located in the private folder" option is disabled or enabled
627
    $allow_download_private_files = FALSE;
628
    if (isset($global_profile->settings['ckeditor_allow_download_private_files']) && $global_profile->settings['ckeditor_allow_download_private_files'] === 't') {
629
      $allow_download_private_files = TRUE;
630
    }
631
    //denied access to file if private upload is set and CKEditor's "Enable access to files located in the private folder" option is disabled
632
    if ($allow_download_private_files == FALSE)
633
      return NULL;
634
    //check if file can be served by comparing regex and path to file
635
    if (preg_match($regex, $path)) {
636
      $info = image_get_info($uri);
637
      return array('Content-Type' => $info['mime_type']);
638
    }
639
  }
640
}
641

    
642
/**
643
 * Implementation of hook_modules_enabled().
644
 *
645
 * Enable disabled plugins by hook_modules_disabled().
646
 */
647
function ckeditor_modules_enabled($modules) {
648
  module_load_include('inc', 'ckeditor', 'includes/ckeditor.lib');
649
  if (in_array('libraries', $modules)) {
650
    // Check and update path to CKEditor in the global profile
651
    _ckeditor_requirements_isinstalled();
652
  }
653
  $profiles_list = ckeditor_profile_input_formats();
654
  $plugins_list = ckeditor_load_plugins();
655
  foreach ($profiles_list AS $_profile => $_inputs) {
656
    $changed = FALSE;
657
    $profile = ckeditor_profile_load($_profile);
658
    if (!isset($profile->settings['loadPlugins'])) continue;
659
    foreach (array_keys((array) $profile->settings['loadPlugins']) as $plugin_name) {
660
      if (isset($profile->settings['loadPlugins'][$plugin_name]['active']) && $profile->settings['loadPlugins'][$plugin_name]['active'] == 0 && array_key_exists($plugin_name, $plugins_list)) {
661
        $profile->settings['loadPlugins'][$plugin_name]['active'] = 1;
662
        $changed = TRUE;
663
      }
664
    }
665
    if ($changed === TRUE) {
666
      db_update('ckeditor_settings')
667
          ->fields(array(
668
            'settings' => serialize($profile->settings)
669
          ))
670
          ->condition('name', $profile->name, '=')
671
          ->execute();
672
    }
673
  }
674
}
675

    
676
/**
677
 * Implementation of hook_modules_disabled().
678
 *
679
 * Disable enabled plugins in CKEditor profiles added by disabled modules.
680
 */
681
function ckeditor_modules_disabled($modules) {
682
  module_load_include('inc', 'ckeditor', 'includes/ckeditor.lib');
683
  $profiles_list = ckeditor_profile_input_formats();
684
  $plugins_list = ckeditor_load_plugins();
685
  foreach ($profiles_list AS $_profile => $_inputs) {
686
    $changed = FALSE;
687
    $profile = ckeditor_profile_load($_profile);
688
    if (!isset($profile->settings['loadPlugins'])) continue;
689
    foreach (array_keys((array) $profile->settings['loadPlugins']) as $plugin_name) {
690
      if (!array_key_exists($plugin_name, $plugins_list)) {
691
        $profile->settings['loadPlugins'][$plugin_name]['active'] = 0;
692
        $changed = TRUE;
693
      }
694
    }
695
    if ($changed === TRUE) {
696
      db_update('ckeditor_settings')
697
          ->fields(array(
698
            'settings' => serialize($profile->settings)
699
          ))
700
          ->condition('name', $profile->name, '=')
701
          ->execute();
702
    }
703
  }
704
}
705

    
706
/**
707
 * Implementation of hook_modules_uninstalled().
708
 *
709
 * Remove enabled plugins in CKEditor profiles added by uninstalled modules.
710
 */
711
function ckeditor_modules_uninstalled($modules) {
712
  module_load_include('inc', 'ckeditor', 'includes/ckeditor.lib');
713
  $profiles_list = ckeditor_profile_input_formats();
714
  $plugins_list = ckeditor_load_plugins();
715
  foreach ($profiles_list AS $_profile => $_inputs) {
716
    $changed = FALSE;
717
    $profile = ckeditor_profile_load($_profile);
718
    if (!isset($profile->settings['loadPlugins'])) continue;
719
    foreach (array_keys((array) $profile->settings['loadPlugins']) as $plugin_name) {
720
      if (!array_key_exists($plugin_name, $plugins_list)) {
721
        unset($profile->settings['loadPlugins'][$plugin_name]);
722
        $changed = TRUE;
723
      }
724
    }
725
    if ($changed === TRUE) {
726
      db_update('ckeditor_settings')
727
          ->fields(array(
728
            'settings' => serialize($profile->settings)
729
          ))
730
          ->condition('name', $profile->name, '=')
731
          ->execute();
732
    }
733
  }
734
}
735

    
736

    
737
/**
738
 * Implements hook_field_extra_fields().
739
 */
740
function ckeditor_field_extra_fields() {
741
  $fields['user']['user']['form']['ckeditor'] = array(
742
    'label' => t('Rich text editor settings'),
743
    'description' => t('Rich text editor settings'),
744
    'weight' => 10,
745
  );
746
  return $fields;
747
}
748