Projet

Général

Profil

Paste
Télécharger (25 ko) Statistiques
| Branche: | Révision:

root / drupal7 / sites / all / modules / ckeditor / ckeditor.module @ 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
 * 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
define('CKEDITOR_LATEST', '4.14.0');
45

    
46
global $_ckeditor_configuration;
47
global $_ckeditor_ids;
48

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

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

    
54
/**
55
 * Implements hook_hook_info().
56
 */
57
function ckeditor_hook_info() {
58
  $hooks = array(
59
    'ckeditor_plugin',
60
    'ckeditor_plugin_alter',
61
    'ckeditor_security_filter',
62
    'ckeditor_security_filter_alter',
63
    'ckeditor_settings_alter',
64
  );
65

    
66
  return array_fill_keys($hooks, array('group' => 'ckeditor'));
67
}
68

    
69
/**
70
 * Implementation of hook_menu().
71
 */
72
function ckeditor_menu() {
73
  $items = array();
74

    
75
  $items['ckeditor/xss'] = array(
76
    'title' => 'XSS Filter',
77
    'description' => 'XSS Filter.',
78
    'page callback' => 'ckeditor_filter_xss',
79
    'file' => 'includes/ckeditor.page.inc',
80
    'access callback' => TRUE,
81
    'type' => MENU_CALLBACK,
82
  );
83

    
84
  $items['ckeditor/disable/wysiwyg/%'] = array(
85
    'title' => 'Disable the WYSIWYG module',
86
    'description' => 'Disable WYSIWYG module.',
87
    'page callback' => 'ckeditor_disable_wysiwyg',
88
    'page arguments' => array(3),
89
    'file' => 'includes/ckeditor.admin.inc',
90
    'access arguments' => array('administer ckeditor'),
91
    'access callback' => TRUE,
92
    'type' => MENU_CALLBACK,
93
  );
94

    
95
  $items['admin/config/content/ckeditor'] = array(
96
    'title' => 'CKEditor',
97
    'description' => 'Configure the rich text editor.',
98
    'page callback' => 'ckeditor_admin_main',
99
    'file' => 'includes/ckeditor.admin.inc',
100
    'access arguments' => array('administer ckeditor'),
101
    'type' => MENU_NORMAL_ITEM,
102
  );
103

    
104
  $items['admin/config/content/ckeditor/skinframe'] = array(
105
    'title' => 'Change skin of CKEditor',
106
    'description' => 'Configure skin for CKEditor.',
107
    'page callback' => 'ckeditor_skinframe',
108
    'file' => 'includes/ckeditor.admin.inc',
109
    'access arguments' => array('administer ckeditor'),
110
    'type' => MENU_CALLBACK,
111
  );
112

    
113
  $items['admin/config/content/ckeditor/add'] = array(
114
    'title' => 'Add a new CKEditor profile',
115
    'description' => 'Configure the rich text editor.',
116
    'page callback' => 'drupal_get_form',
117
    'page arguments' => array('ckeditor_admin_profile_form', 'add'),
118
    'file' => 'includes/ckeditor.admin.inc',
119
    'access arguments' => array('administer ckeditor'),
120
    'type' => MENU_CALLBACK,
121
  );
122

    
123
  $items['admin/config/content/ckeditor/clone/%ckeditor_profile'] = array(
124
    'title' => 'Clone the CKEditor profile',
125
    'description' => 'Configure the rich text editor.',
126
    'page callback' => 'drupal_get_form',
127
    'page arguments' => array('ckeditor_admin_profile_clone_form', 'clone', 5),
128
    'file' => 'includes/ckeditor.admin.inc',
129
    'access arguments' => array('administer ckeditor'),
130
    'type' => MENU_CALLBACK,
131
  );
132

    
133
  $items['admin/config/content/ckeditor/edit/%ckeditor_profile'] = array(
134
    'title' => 'Edit the CKEditor profile',
135
    'description' => 'Configure the rich text editor.',
136
    'page callback' => 'drupal_get_form',
137
    'page arguments' => array('ckeditor_admin_profile_form', 'edit', 5),
138
    'file' => 'includes/ckeditor.admin.inc',
139
    'access arguments' => array('administer ckeditor'),
140
    'type' => MENU_CALLBACK,
141
  );
142

    
143
  $items['admin/config/content/ckeditor/delete/%ckeditor_profile'] = array(
144
    'title' => 'Delete the CKEditor profile',
145
    'description' => 'Configure the rich text editor.',
146
    'page callback' => 'drupal_get_form',
147
    'page arguments' => array('ckeditor_admin_profile_delete_form', 5),
148
    'file' => 'includes/ckeditor.admin.inc',
149
    'access arguments' => array('administer ckeditor'),
150
    'type' => MENU_CALLBACK,
151
  );
152

    
153
  $items['admin/config/content/ckeditor/addg'] = array(
154
    'title' => 'Add the CKEditor Global profile',
155
    'description' => 'Configure the rich text editor.',
156
    'page callback' => 'drupal_get_form',
157
    'page arguments' => array('ckeditor_admin_global_profile_form', 'add'),
158
    'file' => 'includes/ckeditor.admin.inc',
159
    'access arguments' => array('administer ckeditor'),
160
    'type' => MENU_CALLBACK,
161
  );
162

    
163
  $items['admin/config/content/ckeditor/editg'] = array(
164
    'title' => 'Edit the CKEditor Global profile',
165
    'description' => 'Configure the rich text editor.',
166
    'page callback' => 'drupal_get_form',
167
    'page arguments' => array('ckeditor_admin_global_profile_form', 'edit'),
168
    'file' => 'includes/ckeditor.admin.inc',
169
    'access arguments' => array('administer ckeditor'),
170
    'type' => MENU_CALLBACK,
171
  );
172

    
173
  return $items;
174
}
175

    
176
/**
177
 * Implementation of hook_permission().
178
 *
179
 * People -> Permissions
180
 */
181
function ckeditor_permission() {
182
  $arr = array();
183
  $arr['administer ckeditor'] = array(
184
    'title' => t('Administer CKEditor access'),
185
    'description' => t('Allow users to change CKEditor settings.')
186
  );
187

    
188
  $arr['customize ckeditor'] = array(
189
    'title' => t('Customize CKEditor appearance'),
190
    'description' => t('Allow users to customize CKEditor appearance.')
191
  );
192

    
193
  if (file_exists(ckfinder_path('local'))) {
194
    $arr['allow CKFinder file uploads'] = array(
195
      'title' => t('CKFinder access'),
196
      'description' => t('Allow users to use CKFinder.')
197
    );
198
  }
199
  return $arr;
200
}
201

    
202
/**
203
 * Implementation of hook_help().
204
 *
205
 * This function delegates the execution to ckeditor_help_delegate() in includes/ckeditor.page.inc to
206
 * lower the amount of code in ckeditor.module.
207
 */
208
function ckeditor_help($path, $arg) {
209
  module_load_include('inc', 'ckeditor', 'includes/ckeditor.page');
210
  return module_invoke('ckeditor', 'help_delegate', $path, $arg);
211
}
212

    
213
/**
214
 * Check CKEditor version
215
 */
216
function ckeditor_get_version($main_version = FALSE) {
217
  static $ckeditor_version = FALSE;
218

    
219
  if ($ckeditor_version !== FALSE) {
220
    if (!$main_version) {
221
      return $ckeditor_version;
222
    }
223
    $version = explode('.', $ckeditor_version);
224
    return trim($version[0]);
225
  }
226

    
227
  $editor_path = ckeditor_path('local', TRUE);
228
  if ($editor_path == '<URL>') {
229
    $url = ckeditor_path('url', TRUE);
230
    $matches = array();
231
    if (preg_match("|cdn.ckeditor.com/(\d(\.\d+)+.*)/|i", $url, $matches)) {
232
      $ckeditor_version = $matches[1];
233
      return $matches[1];
234
    }
235
    return $ckeditor_version = NULL;
236
  }
237

    
238
  $jspath = $editor_path . '/ckeditor.js';
239

    
240
  $configcontents = @file_get_contents($jspath);
241
  if (!$configcontents) {
242
    return $ckeditor_version = NULL;
243
  }
244
  $matches = array();
245
  if (preg_match('#,version:[\'\"]{1}(.*?)[\'\"]{1},#', $configcontents, $matches)) {
246
    $ckeditor_version = $matches[1];
247
    if ($ckeditor_version == '%VERSION%') {
248
      $ckeditor_version = '4.0.0';
249
    }
250
    if (!$main_version) {
251
      return $ckeditor_version;
252
    }
253
    $version = explode('.', $ckeditor_version);
254
    return trim($version[0]);
255
  }
256
  return $ckeditor_version = NULL;
257
}
258

    
259
/**
260
 * Implements hook_page_build().
261
 */
262
function ckeditor_page_build(&$page) {
263
  // Add our CSS file that adds common needed classes, such as align-left,
264
  // align-right, underline, indent, etc.
265
  $page['page_bottom']['ckeditor']['#attached']['css'] = array(
266
    drupal_get_path('module', 'ckeditor') . '/css/ckeditor.css' => array(
267
      'every_page' => TRUE,
268
    ),
269
  );
270
}
271

    
272
/**
273
 * Implements hook_form_FORM_ID_alter() for user_profile_form().
274
 */
275
function ckeditor_form_user_profile_form_alter(&$form, &$form_state) {
276
  if ($form['#user_category'] == 'account') {
277
    ckeditor_user_customize($form, $form_state, 'user_profile_form');
278
  }
279
}
280

    
281
/**
282
 * Implementation of hook_element_info_alter().
283
 *
284
 * Replace the textarea with CKEditor using a callback function (ckeditor_pre_render_text_format).
285
 */
286
function ckeditor_element_info_alter(&$types) {
287
  $types['text_format']['#pre_render'][] = 'ckeditor_pre_render_text_format';
288
}
289

    
290
/**
291
 * This function creates the HTML objects required for CKEditor.
292
 *
293
 * @param $element
294
 *   A fully populated form element to add the editor to.
295
 * @return
296
 *   The same $element with extra CKEditor markup and initialization.
297
 */
298
function ckeditor_pre_render_text_format($element) {
299
  static $init = FALSE;
300
  if (!isset($element['#format'])) {
301
    return $element;
302
  }
303

    
304
  module_load_include('inc', 'ckeditor', 'includes/ckeditor.lib');
305
  if ($init === FALSE) {
306
    $input_formats = ckeditor_profiles_compile();
307
    drupal_add_js(array('ckeditor' => array('input_formats' => $input_formats, 'plugins' => array())), 'setting');
308
    $init = TRUE;
309
  }
310

    
311
  if (isset($element['value'])) {
312
    if (!isset($element['format'])) {
313
      return $element;
314
    }
315
    if (isset($element['summary'])) {
316
      $element['value'] = ckeditor_load_by_field($element['value'], $element['format']['format'], TRUE, $element['summary']['#id']);
317
      $element['summary'] = ckeditor_load_by_field($element['summary'], $element['format']['format'], FALSE);
318
    }
319
    else {
320
      $element['value'] = ckeditor_load_by_field($element['value'], $element['format']['format']);
321
    }
322
  }
323
  else {
324
    $element = ckeditor_load_by_field($element, $element['#format']);
325
  }
326

    
327
  return $element;
328
}
329

    
330
/**
331
 * Load all profiles. Just load one profile if $name is passed in.
332
 */
333
function ckeditor_profile_load($name = '', $clear = FALSE, $check_access = TRUE) {
334
  static $profiles = array();
335
  global $user;
336

    
337
  if (empty($profiles) || $clear === TRUE) {
338
    $result = db_select('ckeditor_settings', 's')->fields('s')->execute();
339
    foreach ($result as $data) {
340
      $data->settings = unserialize($data->settings);
341
      $data->input_formats = array();
342

    
343
      $profiles[$data->name] = $data;
344
    }
345
    if ($check_access === FALSE) {
346
      // don't check if user has access to filter formats, needed for exporting as feature with drush
347
      $input_formats = filter_formats();
348
    } else {
349
      $input_formats = filter_formats($user);
350
    }
351
    $result = db_select('ckeditor_input_format', 'f')->fields('f')->execute();
352
    foreach ($result as $data) {
353
      if (isset($input_formats[$data->format])) {
354
        $profiles[$data->name]->input_formats[$data->format] = $input_formats[$data->format]->name;
355
      }
356
    }
357
  }
358

    
359
  return ($name ? (isset($profiles[urldecode($name)]) ? $profiles[urldecode($name)] : FALSE) : $profiles);
360
}
361

    
362
/**
363
 * Generate base path of the Drupal installation.
364
 *
365
 * @return
366
 *   Path of the Drupal installation.
367
 */
368
function ckeditor_base_path($mode = 'relative') {
369
  if ($mode == 'local') {
370
    return $cke_base_local_path = '.';
371
  }
372
  return rtrim(base_path(), '/');
373
}
374

    
375
/**
376
 * Generate module path of the CKEditor module.
377
 *
378
 * @return
379
 *   Path of CKEditor module.
380
 */
381
function ckeditor_module_path($mode = 'relative') {
382
  switch ($mode) {
383
    default:
384
    case 'relative':
385
      return ckeditor_base_path('relative') . '/' . drupal_get_path('module', 'ckeditor');
386
    case 'local':
387
      return ckeditor_base_path('local') . '/' . drupal_get_path('module', 'ckeditor');
388
    case 'url':
389
      return drupal_get_path('module', 'ckeditor');
390
  }
391
}
392

    
393
/**
394
 * Generate library path of the Drupal installation.
395
 *
396
 * @return
397
 *   Path of library in the Drupal installation.
398
 */
399
function ckeditor_library_path($mode = 'relative') {
400
  $lib_path = 'sites/all/libraries';
401

    
402
  if (function_exists('libraries_get_path')) {
403
    $path = libraries_get_path('ckeditor');
404
    if ($path !== FALSE) {
405
      $lib_path = drupal_substr($path, 0, strlen($path) - 9);
406
    }
407
  }
408
  switch ($mode) {
409
    default:
410
    case 'relative':
411
      return ckeditor_base_path('relative') . '/' . $lib_path;
412
    case 'local':
413
      return ckeditor_base_path('local') . '/' . $lib_path;
414
    case 'url':
415
      return $lib_path;
416
  }
417
}
418

    
419
/**
420
 * Read the CKEditor path from the Global profile.
421
 *
422
 * @return
423
 *   Path to CKEditor folder.
424
 */
425
function ckeditor_path($mode = 'relative', $refresh = FALSE) {
426
  static $cke_static;
427

    
428
  if (!isset($cke_static)) {
429
    $cke_static = array();
430
  }
431

    
432
  if ($refresh || !isset($cke_static[$mode])) {
433
    $global_profile = ckeditor_profile_load('CKEditor Global Profile', $refresh);
434
    switch ($mode) {
435
      default:
436
      case 'relative':
437
        if ($global_profile && isset($global_profile->settings['ckeditor_path'])) {
438
          // http:// OR https:// OR //
439
          if (preg_match("|^(http(s)?:)?//|i", $global_profile->settings['ckeditor_path'])) {
440
            return '<URL>';
441
          }
442
          $cke_path = $global_profile->settings['ckeditor_path'];
443
          $cke_path = strtr($cke_path, array("%b" => ckeditor_base_path('relative'), "%m" => ckeditor_module_path('relative'), "%l" => ckeditor_library_path('relative')));
444
          $cke_path = str_replace('\\', '/', $cke_path);
445
          $cke_path = str_replace('//', '/', $cke_path);
446
          return $cke_static[$mode] = $cke_path;
447
        }
448
        return $cke_static[$mode] = ckeditor_module_path('relative') . '/ckeditor';
449
      case 'local':
450
        if ($global_profile) {
451
          if (!empty($global_profile->settings['ckeditor_local_path'])) {
452
            return $cke_static[$mode] = $global_profile->settings['ckeditor_local_path'];
453
          }
454
          if (isset($global_profile->settings['ckeditor_path'])) {
455
            // http:// OR https:// OR //
456
            if (preg_match("|^(http(s)?:)?//|i", $global_profile->settings['ckeditor_path'])) {
457
              return '<URL>';
458
            }
459
            $cke_local_path = $global_profile->settings['ckeditor_path'];
460
            $cke_local_path = strtr($cke_local_path, array("%b" => ckeditor_base_path('local'), "%m" => ckeditor_module_path('local'), "%l" => ckeditor_library_path('local')));
461
            return $cke_static[$mode] = $cke_local_path;
462
          }
463
        }
464
        return $cke_static[$mode] = ckeditor_module_path('local') . '/ckeditor';
465
      case 'url':
466
        if ($global_profile && isset($global_profile->settings['ckeditor_path'])) {
467
          // http:// OR https:// OR //
468
          if (preg_match("|^(http(s)?:)?//|i", $global_profile->settings['ckeditor_path'])) {
469
            $cke_path = $global_profile->settings['ckeditor_path'];
470
          }
471
          else {
472
            $cke_path = $global_profile->settings['ckeditor_path'];
473
            $cke_path = strtr($cke_path, array("%m" => ckeditor_module_path('url'), "%l" => ckeditor_library_path('url')));
474
            $cke_path = str_replace('\\', '/', $cke_path);
475
            $cke_path = str_replace('//', '/', $cke_path);
476
            //In D7 base path in URL mode is not needed, so we need to remove it with trailing slash (if exists)
477
            $cke_path = str_replace(array("%b/", "%b"), '', $cke_path);
478
          }
479
          return $cke_static[$mode] = $cke_path;
480
        }
481
        return $cke_static[$mode] = ckeditor_module_path('url') . '/ckeditor';
482
    }
483
  }
484
  return $cke_static[$mode];
485
}
486

    
487
/**
488
 * Read the CKEditor plugins path from the Global profile.
489
 *
490
 * @return
491
 *   Path to CKEditor plugins folder.
492
 */
493
function ckeditor_plugins_path($mode = 'relative', $refresh = FALSE) {
494
  static $cke_static;
495

    
496
  if (!isset($cke_static)) {
497
    $cke_static = array();
498
  }
499

    
500
  if ($refresh || !isset($cke_static[$mode])) {
501
    $global_profile = ckeditor_profile_load('CKEditor Global Profile', $refresh);
502
    switch ($mode) {
503
      default:
504
      case 'relative':
505
        if ($global_profile && isset($global_profile->settings['ckeditor_plugins_path'])) {
506
          $cke_plugins_path = $global_profile->settings['ckeditor_plugins_path'];
507
          $cke_plugins_path = strtr($cke_plugins_path, array("%b" => ckeditor_base_path('relative'), "%m" => ckeditor_module_path('relative'), "%l" => ckeditor_library_path('relative')));
508
          $cke_plugins_path = str_replace('\\', '/', $cke_plugins_path);
509
          $cke_plugins_path = str_replace('//', '/', $cke_plugins_path);
510
          $cke_plugins_path = rtrim($cke_plugins_path, ' \/');
511
          return $cke_static[$mode] = $cke_plugins_path;
512
        }
513
        return $cke_static[$mode] = ckeditor_module_path('relative') . '/plugins';
514
      case 'local':
515
        if ($global_profile) {
516
          if (!empty($global_profile->settings['ckeditor_plugins_local_path'])) {
517
            return $cke_static[$mode] = $global_profile->settings['ckeditor_plugins_local_path'];
518
          }
519
          if (isset($global_profile->settings['ckeditor_plugins_path'])) {
520
            $cke_plugins_local_path = $global_profile->settings['ckeditor_plugins_path'];
521
            $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')));
522
            return $cke_static[$mode] = $cke_plugins_local_path;
523
          }
524
        }
525
        return $cke_static[$mode] = ckeditor_module_path('local') . '/plugins';
526
      case 'url':
527
        if ($global_profile && isset($global_profile->settings['ckeditor_plugins_path'])) {
528
          $cke_plugins_path = $global_profile->settings['ckeditor_plugins_path'];
529
          $cke_plugins_path = strtr($cke_plugins_path, array("%m" => ckeditor_module_path('url'), "%l" => ckeditor_library_path('url')));
530
          $cke_plugins_path = str_replace('\\', '/', $cke_plugins_path);
531
          $cke_plugins_path = str_replace('//', '/', $cke_plugins_path);
532
          $cke_plugins_path = rtrim($cke_plugins_path, ' \/');
533
          //In D7 base path in URL mode is not needed, so we need to remove it with trailing slash (if exists)
534
          $cke_plugins_path = str_replace(array("%b/", "%b"), '', $cke_plugins_path);
535
          return $cke_static[$mode] = $cke_plugins_path;
536
        }
537
        return $cke_static[$mode] = ckeditor_module_path('url') . '/plugins';
538
    }
539
  }
540
  return $cke_static[$mode];
541
}
542

    
543
/**
544
 * Read the CKFinder path from the Global profile.
545
 *
546
 * @return
547
 *   Path to CKFinder folder.
548
 */
549
function ckfinder_path($mode = 'relative', $refresh = FALSE) {
550
 static $cke_static;
551

    
552
  if (!isset($cke_static)) {
553
    $cke_static = array();
554
  }
555

    
556
  if ($refresh || !isset($cke_static[$mode])) {
557
    $global_profile = ckeditor_profile_load('CKEditor Global Profile', $refresh);
558
    switch ($mode) {
559
      default:
560
      case 'relative':
561
        if ($global_profile && isset($global_profile->settings['ckfinder_path'])) {
562
          $ckfinder_path = $global_profile->settings['ckfinder_path'];
563
          $ckfinder_path = strtr($ckfinder_path, array("%b" => ckeditor_base_path('relative'), "%m" => ckeditor_module_path('relative'), "%l" => ckeditor_library_path('relative')));
564
          $ckfinder_path = str_replace('\\', '/', $ckfinder_path);
565
          $ckfinder_path = str_replace('//', '/', $ckfinder_path);
566
          return $cke_static[$mode] = $ckfinder_path;
567
        }
568
        return $cke_static[$mode] = ckeditor_module_path('relative') . '/ckfinder';
569
      case 'local':
570
        if ($global_profile) {
571
          if (!empty($global_profile->settings['ckfinder_local_path'])) {
572
            return $cke_static[$mode] = $global_profile->settings['ckfinder_local_path'];
573
          }
574
          if (isset($global_profile->settings['ckfinder_path'])) {
575
            $ckfinder_path = $global_profile->settings['ckfinder_path'];
576
            $ckfinder_path = strtr($ckfinder_path, array("%b" => ckeditor_base_path('local'), "%m" => ckeditor_module_path('local'), "%l" => ckeditor_library_path('local')));
577
            return $cke_static[$mode] = $ckfinder_path;
578
          }
579
        }
580
        return $cke_static[$mode] = ckeditor_module_path('local') . '/ckfinder';
581
      case 'url':
582
        if ($global_profile && isset($global_profile->settings['ckfinder_path'])) {
583
          $ckfinder_path = $global_profile->settings['ckfinder_path'];
584
          $ckfinder_path = strtr($ckfinder_path, array("%m" => ckeditor_module_path('url'), "%l" => ckeditor_library_path('url')));
585
          $ckfinder_path = str_replace('\\', '/', $cke_plugins_path);
586
          $ckfinder_path = str_replace('//', '/', $cke_plugins_path);
587
          //In D7 base path in URL mode is not needed, so we need to remove it with trailing slash (if exists)
588
          $ckfinder_path = str_replace(array("%b/", "%b"), '', $ckfinder_path);
589
          return $cke_static[$mode] = $ckfinder_path;
590
        }
591
        return $cke_static[$mode] = ckeditor_module_path('url') . '/ckfinder';
592
    }
593
  }
594
  return $cke_static[$mode];
595
}
596

    
597
/**
598
 * Implementation of hook_features_api().
599
 *
600
 * Allow exporting of CKEditor profiles by the Features module.
601
 */
602
function ckeditor_features_api() {
603
  return array(
604
    'ckeditor_profile' => array(
605
      'name' => t('CKEditor profiles'),
606
      'feature_source' => TRUE,
607
      'default_hook' => 'ckeditor_profile_defaults',
608
      'default_file' => FEATURES_DEFAULTS_INCLUDED,
609
      'file' => drupal_get_path('module', 'ckeditor') . '/includes/ckeditor.features.inc',
610
    )
611
  );
612
}
613

    
614
/**
615
 * Implementation of hook_file_download().
616
 * Support for private downloads.
617
 * CKEditor does not implement any kind of potection on private files.
618
 */
619
function ckeditor_file_download($uri) {
620
  $result = db_query("SELECT f.* FROM {file_managed} f WHERE uri = :uri", array(':uri' => $uri));
621
  foreach ($result as $record) {
622
    return NULL;
623
  }
624
  if ($path = file_create_url($uri)) {
625
    //No info in DB? Probably a file uploaded with FCKeditor / CKFinder
626
    $global_profile = ckeditor_profile_load("CKEditor Global Profile");
627
    //Assume that files inside of ckeditor directory belong to the CKEditor. If private directory is set, let the decision about protection to the user.
628
    $private_dir_db = $private_dir = isset($global_profile->settings['private_dir']) ? trim($global_profile->settings['private_dir'], '\/') : '';
629
    $private_dir_db = str_replace(array('\\%u', '\\%n'), array('', ''), $private_dir_db);
630
    $private_dir = preg_quote($private_dir, '#');
631
    $private_dir = strtr($private_dir, array('%u' => '(\d+)', '%n' => '([\x80-\xF7 \w@.-]+)')); // regex for %n taken from user_validate_name() in user.module
632
    $private_dir = trim($private_dir, '\/');
633

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

    
636
    if (!strstr($uri, 'private://') && !strstr($uri, 'public://')) {
637
      $path = 'private://' . $uri;
638
    }
639
    else {
640
      $path = $uri;
641
    }
642
    //check if CKEditor's "Enable access to files located in the private folder" option is disabled or enabled
643
    $allow_download_private_files = FALSE;
644
    if (isset($global_profile->settings['ckeditor_allow_download_private_files']) && $global_profile->settings['ckeditor_allow_download_private_files'] === 't') {
645
      $allow_download_private_files = TRUE;
646
    }
647
    //denied access to file if private upload is set and CKEditor's "Enable access to files located in the private folder" option is disabled
648
    if ($allow_download_private_files == FALSE)
649
      return NULL;
650
    //check if file can be served by comparing regex and path to file
651
    if (preg_match($regex, $path)) {
652
      $info = image_get_info($uri);
653
      return array('Content-Type' => $info['mime_type']);
654
    }
655
  }
656
}
657

    
658
/**
659
 * Implementation of hook_modules_uninstalled().
660
 *
661
 * Remove enabled plugins in CKEditor profiles added by uninstalled modules.
662
 */
663
function ckeditor_modules_uninstalled($modules) {
664
  module_load_include('inc', 'ckeditor', 'includes/ckeditor.lib');
665
  $profiles_list = ckeditor_profile_input_formats();
666
  $plugins_list = ckeditor_load_plugins();
667
  foreach ($profiles_list as $_profile => $_inputs) {
668
    $changed = FALSE;
669
    $profile = ckeditor_profile_load($_profile);
670
    if (!isset($profile->settings['loadPlugins'])) continue;
671
    foreach (array_keys((array) $profile->settings['loadPlugins']) as $plugin_name) {
672
      if (!array_key_exists($plugin_name, $plugins_list)) {
673
        unset($profile->settings['loadPlugins'][$plugin_name]);
674
        $changed = TRUE;
675
      }
676
    }
677
    if ($changed) {
678
      db_update('ckeditor_settings')
679
        ->fields(array(
680
          'settings' => serialize($profile->settings)
681
        ))
682
        ->condition('name', $profile->name, '=')
683
        ->execute();
684
    }
685
  }
686
}
687

    
688
/**
689
 * Implements hook_field_extra_fields().
690
 */
691
function ckeditor_field_extra_fields() {
692
  $fields['user']['user']['form']['ckeditor'] = array(
693
    'label' => t('Rich text editor settings'),
694
    'description' => t('Rich text editor settings'),
695
    'weight' => 10,
696
  );
697
  return $fields;
698
}