| [ Index ] |
PHP Cross Reference of Drupal 6 (yi-drupal) |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * CKEditor - The text editor for the Internet - http://ckeditor.com 4 * Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved. 5 * 6 * == BEGIN LICENSE == 7 * 8 * Licensed under the terms of any of the following licenses of your 9 * choice: 10 * 11 * - GNU General Public License Version 2 or later (the "GPL") 12 * http://www.gnu.org/licenses/gpl.html 13 * 14 * - GNU Lesser General Public License Version 2.1 or later (the "LGPL") 15 * http://www.gnu.org/licenses/lgpl.html 16 * 17 * - Mozilla Public License Version 1.1 or later (the "MPL") 18 * http://www.mozilla.org/MPL/MPL-1.1.html 19 * 20 * == END LICENSE == 21 * 22 * @file 23 * CKEditor Module for Drupal 6.x 24 * 25 * This module allows Drupal to replace textarea fields with CKEditor. 26 * 27 * CKEditor is an online rich text editor that can be embedded inside web pages. 28 * It is a WYSIWYG (What You See Is What You Get) editor which means that the 29 * text edited in it looks as similar as possible to the results end users will 30 * see after the document gets published. It brings to the Web popular editing 31 * features found in desktop word processors such as Microsoft Word and 32 * OpenOffice.org Writer. CKEditor is truly lightweight and does not require any 33 * kind of installation on the client computer. 34 */ 35 36 /** 37 * Main administrative page 38 */ 39 function ckeditor_admin_main() { 40 module_load_include('inc', 'ckeditor', 'includes/ckeditor.lib'); 41 $editor_path = ckeditor_path(TRUE); 42 $ckconfig_file = $editor_path .'/config.js'; 43 if (!_ckeditor_requirements_isinstalled()) { 44 drupal_set_message(t( 45 'Checking for !filename or !file.', 46 array( 47 '!filename' => '<code>' . $ckconfig_file . '</code>', 48 '!file' => '<code>sites/all/libraries/ckeditor/ckeditor.js</code>' 49 ) 50 )); 51 drupal_set_message(t( 52 '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.', 53 array( 54 '!ckeditorlink' => l(t('CKEditor homepage'), 'http://ckeditor.com/download'), 55 '!readme' => l(t('README.txt'), drupal_get_path('module', 'ckeditor') . '/README.txt', array('absolute' => TRUE)), 56 '!ckeditorpath' => '<code>' . $editor_path . '</code>', 57 '!ckeditorsubdir' => '<code>' . $editor_path . '/editor</code>', 58 '!ckeditorfile' => '<code>' . $editor_path . '/ckeditor.js</code>', 59 '!ckeditorlibrary' => '<code>sites/all/libraries/ckeditor/ckeditor.js</code>', 60 '!librarypath' => '<code>sites/all/libraries/ckeditor</code>' 61 ) 62 ), 'error'); 63 drupal_set_message(t( 64 'If you have CKEditor already installed, edit the <strong>!editg</strong> and update the CKEditor path.', 65 array( 66 '!editg' => l(t('CKEditor Global Profile'), 'admin/settings/ckeditor/editg') 67 ) 68 ), 'warning'); 69 return FALSE; 70 } 71 72 if (module_exists('wysiwyg')) { 73 drupal_set_message(t( 74 '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").', 75 array( 76 '!wysiwygdisablelink' => l(t('click here to disable'), 'ckeditor/disable/wysiwyg/' . drupal_get_token('ckeditorDisableWysiwyg')) 77 ) 78 ), 'warning'); 79 } 80 81 $access_ckeditor_roles = user_roles(FALSE, 'access ckeditor'); 82 if (!$access_ckeditor_roles) { 83 drupal_set_message(t( 84 'There is currently no role with the "access ckeditor" permission. Visit the !acl administration section.', 85 array( 86 '!acl' => l(t('Permissions'), 'admin/user/permissions') 87 ) 88 ), 'warning'); 89 } 90 else { 91 $result = db_query_range("SELECT name FROM {ckeditor_settings} WHERE name<>'CKEditor Global Profile'", 0, 1); 92 $has_profiles = FALSE; 93 //find profile other than Global 94 if (($obj = db_fetch_object($result))) { 95 $has_profiles = TRUE; 96 } 97 98 //find roles with profiles 99 $result = db_query("SELECT rid FROM {ckeditor_role}"); 100 $rids = array(); 101 while (($obj = db_fetch_object($result))) { 102 $rids[] = $obj->rid; 103 } 104 $rids = array_unique($rids); 105 if (!$has_profiles) { 106 drupal_set_message(t('No CKEditor profiles found. Right now nobody is able to use CKEditor. Create a new profile below.'), 'error'); 107 } 108 else { 109 //not all roles with access ckeditor has their CKEditor profile assigned 110 $diff = array_diff(array_keys($access_ckeditor_roles), $rids); 111 if ($diff) { 112 $list = "<ul>"; 113 foreach ($diff as $rid) { 114 $list .= "<li>". $access_ckeditor_roles[$rid] ."</li>"; 115 } 116 $list .= "</ul>"; 117 drupal_set_message(t( 118 'Not all roles with the "!access" permission are associated with CKEditor profiles. As a result, users with the following roles may be unable to use CKEditor: !list Create new or edit existing CKEditor profiles below and check the "Roles allowed to use this profile" option in the <strong>Basic setup</strong> section.', 119 array( 120 '!access' => l(t('access ckeditor'), 'admin/user/permissions'), 121 '!list' => $list 122 ) 123 ), 'warning'); 124 } 125 } 126 } 127 128 return ckeditor_profile_overview(); 129 } 130 131 /** 132 * Controller for CKEditor profiles. 133 */ 134 function ckeditor_profile_overview() { 135 $output = ''; 136 137 $profiles = ckeditor_profile_load(); 138 if ($profiles) { 139 $access_ckeditor_roles = user_roles(FALSE, 'access ckeditor'); 140 $header = array(t('Profile'), t('Roles'), t('Operations')); 141 foreach ($profiles as $p) { 142 $rids = $p->rids; 143 if ($p->name !== "CKEditor Global Profile") { 144 foreach (array_keys($p->rids) as $rid) { 145 if (!isset($access_ckeditor_roles[$rid])) { 146 unset($rids[$rid]); 147 } 148 } 149 $rows[] = array( 150 array('data' => $p->name, 'valign' => 'top'), 151 array('data' => implode("<br />\n", $rids)), 152 array( 153 'data' => 154 l(t('edit'), 'admin/settings/ckeditor/edit/'. urlencode($p->name)) .' '. 155 l(t('clone'), 'admin/settings/ckeditor/clone/'. urlencode($p->name)) .' '. 156 l(t('delete'), 'admin/settings/ckeditor/delete/'. urlencode($p->name)), 157 'valign' => 'top' 158 ) 159 ); 160 } 161 } 162 $output .= '<h3>' . t('Profiles') .'</h3>'; 163 $output .= theme('table', $header, $rows); 164 $output .= '<p>' . l(t('Create a new profile'), 'admin/settings/ckeditor/add') . '</p>'; 165 } 166 else { 167 drupal_set_message(t( 168 'No profiles found. Click here to !create.', 169 array( 170 '!create' => l(t('create a new profile'), 'admin/settings/ckeditor/add') 171 ) 172 )); 173 } 174 175 $rows = array(); 176 if (!isset($profiles['CKEditor Global Profile'])) { 177 drupal_set_message(t( 178 'The global profile can not be found. Click here to !create.', 179 array( 180 '!create' => l(t('create the global profile'), 'admin/settings/ckeditor/addg') 181 ) 182 )); 183 } 184 else { 185 $output .= "<h3>" . t("Global settings") ."</h3>"; 186 $rows[] = array( 187 array('data' => t('CKEditor Global Profile'), 'valign' => 'top'), 188 array( 189 'data' => 190 l(t('edit'), 'admin/settings/ckeditor/editg') . " " . 191 l(t('delete'), 'admin/settings/ckeditor/delete/CKEditor Global Profile'), 192 'valign' => 'top' 193 ) 194 ); 195 $output .= theme('table', array(t('Profile'), t('Operations')), $rows); 196 } 197 return $output; 198 } 199 200 /** 201 * Clone profile 202 */ 203 function ckeditor_admin_profile_clone_form($form_state, $oldprofile) { 204 return ckeditor_admin_profile_form($form_state, $oldprofile); 205 } 206 207 function ckeditor_admin_profile_clone_form_validate($form_state, $oldprofile) { 208 ckeditor_admin_profile_form_validate($form_state, $oldprofile); 209 } 210 211 function ckeditor_admin_profile_clone_form_submit($form, &$form_state) { 212 $edit =& $form_state['values']; 213 drupal_set_message(t('Your CKEditor profile was created.')); 214 $settings = ckeditor_admin_values_to_settings($edit); 215 db_query("INSERT INTO {ckeditor_settings} (name, settings) VALUES ('%s', '%s')", $edit['name'], $settings); 216 ckeditor_rebuild_selectors($edit['name']); 217 if (!empty($edit['rids'])) { 218 foreach (array_keys($edit['rids']) as $rid) { 219 if ($edit['rids'][$rid]!=0) { 220 db_query("INSERT INTO {ckeditor_role} (name, rid) VALUES ('%s', %d)", $edit['name'], $rid); 221 } 222 } 223 } 224 $form_state['redirect'] = 'admin/settings/ckeditor'; 225 } 226 227 /** 228 * Form builder for a normal profile 229 */ 230 function ckeditor_admin_profile_form($form_state, $profile = NULL) { 231 global $theme; 232 if ($profile != NULL) { 233 $form['_profile'] = array( 234 '#type' => 'value', 235 '#value' => $profile, 236 ); 237 } 238 else { 239 $profile = new stdClass(); 240 } 241 242 module_load_include('inc', 'ckeditor', 'includes/ckeditor.lib'); 243 244 $skin_options = ckeditor_load_skin_options(); 245 $lang_options = ckeditor_load_lang_options(); 246 247 // Only display the roles that currently don't have a ckeditor profile. One 248 // profile per role. 249 $orig_roles = user_roles(FALSE, 'access ckeditor'); 250 $roles = $orig_roles; 251 252 if (!empty($profile->rids) && !user_roles(FALSE, 'access ckeditor')) { 253 drupal_set_message(t( 254 'You have not assigned the "access ckeditor" !permissions yet. It is recommended to assign the "access ckeditor" !permissions before updating CKEditor profiles.', 255 array( 256 '!permissions' => l(t('permissions'), 'admin/user/permissions') 257 ) 258 ), 'warning'); 259 } 260 261 if (empty($profile->name)) { 262 $result = db_query("SELECT DISTINCT(rid) FROM {ckeditor_role}"); 263 while (($data = db_fetch_object($result))) { 264 if ((empty($profile->rids) || !in_array($data->rid, array_keys((array) $profile->rids))) && !form_get_errors()) { 265 unset($roles[$data->rid]); 266 } 267 } 268 if (count($orig_roles) != count($roles)) { 269 drupal_set_message(t('Not all user roles are shown since they already have CKEditor profiles assigned. You must first remove the assignment of profiles in order to add them to a new one.')); 270 } 271 } 272 273 $form['basic'] = array( 274 '#type' => 'fieldset', 275 '#title' => t('Basic setup'), 276 '#collapsible' => TRUE, 277 '#collapsed' => TRUE 278 ); 279 280 281 switch (arg(3)) { 282 case 'clone': 283 //load all profiles to check their names 284 $profiles = ckeditor_profile_load(); 285 $oldname = $profile->name; 286 $maxsize=128; //default max name length 287 288 $res=array(); 289 $pat = "/^(.*?)_([0-9]+)$/"; 290 if (preg_match($pat, $oldname, $res)) { // oldname like 'name_nr' 291 $name=$res[1]; 292 $num=$res[2]+1; 293 } 294 else{ 295 $name=$oldname; 296 $num=2; 297 } 298 299 $newname=substr($name, 0, $maxsize-3) .'_'. $num; // +limit 300 while (isset($profiles[$newname])) { //find next free number 301 $num++; 302 $newname=substr($name, 0, $maxsize-3) .'_'. $num; 303 } 304 //dont clone rids 305 $profile->settings['rids']=array(); 306 $profile->rids=array(); 307 break; 308 case 'edit': 309 $newname = $profile->name; 310 break; 311 } 312 313 $global_profile = ckeditor_profile_load("CKEditor Global Profile"); 314 $toolbar_wizard = !empty($global_profile->settings['toolbar_wizard']) ? $global_profile->settings['toolbar_wizard'] : 't'; 315 drupal_add_js(array('ckeditor_toolbar_wizard' => $toolbar_wizard), 'setting'); 316 317 $form['basic']['name'] = array( 318 '#type' => 'textfield', 319 '#title' => t('Profile name'), 320 '#default_value' => !empty($profile->name) ? $newname : '', 321 '#size' => 40, 322 '#maxlength' => 128, 323 '#description' => t('Enter a name for this profile. This name is only visible within the CKEditor administration page.'), 324 '#required' => TRUE 325 ); 326 327 $form['basic']['rids'] = array( 328 '#type' => 'checkboxes', 329 '#title' => t('Roles allowed to use this profile'), 330 '#default_value' => !empty($profile->rids) ? array_keys((array) $profile->rids) : array(), 331 '#options' => $roles, 332 '#description' => t( 333 'Only roles with the "access ckeditor" permission will be shown here. If no role is available, make sure that you have assigned the "access ckeditor" <a href="!permission">permission</a>.', 334 array( 335 '!permission' => l(t('permission'), 'admin/user/permissions') 336 ) 337 ), 338 '#required' => TRUE 339 ); 340 341 $form['basic']['allow_user_conf'] = array( 342 '#type' => 'radios', 343 '#title' => t('Allow users to customize CKEditor appearance'), 344 '#default_value' => !empty($profile->settings['allow_user_conf']) ? $profile->settings['allow_user_conf'] : 'f', 345 '#options' => array( 346 'f' => t('No'), 347 't' => t('Yes') 348 ), 349 '#description' => t('If allowed, users will be able to override the "Editor appearance" by visiting their profile page.'), 350 ); 351 352 $form['security'] = array( 353 '#type' => 'fieldset', 354 '#title' => t('Security'), 355 '#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>', 356 '#collapsible' => TRUE, 357 '#collapsed' => TRUE 358 ); 359 360 $all = filter_list_all(); 361 362 $form['security']['filters'] = array( 363 '#type' => 'fieldset', 364 '#title' => t('Security filters'), 365 '#description' => t('Please choose all filters that protect your content (probably not all filters listed below are security filters).'), 366 '#tree' => TRUE, 367 ); 368 369 //don't bother administrator with filters that definitely are not security filters 370 $modules_with_filters_to_skip = array('amazon_filter', 'asy', 'bbcode', 'biblio', 'blockquote', 'bookpost', 'chessboard', 'citation_filter', 'codefilter', 'collapse_text', 'contextlinks', 'coolfilter', 'dialectic', 'dript', 'dme', 'drutex', 'embedfilter', 'ext_link_page', 'extlink', 'elf', 'flickr', 'flickrstickr', 'footnotes', 'formdefaults', 'freelinking', 'gallery', 'geogebra', 'geshifilter', 'gotwo', 'googtube', 'gotcha', 'gtspam', 'hidden_content', 'img_assist', 'image_filter', 'imagebrowser', 'inlinetags', 'insert_view', 'insertframe', 'insertnode', 'interwiki', 'jlightbox', 'jsmath', 'language_sections', 'link_node', 'lootz', 'markdown', 'marksmarty', 'mobile_codes', 'mykml', 'nofollowlist', 'oagwt', 'paging', 'pathfilter', 'pearwiki_filter', 'php', 'pirate', 'reptag', 'scrippet', 'scripturefilter', 'signwriter', 'slideshowpro', 'smartlinebreakconverter', 'smartypants', 'smileys', 'spamspan', 'spam_tokens', 'spoiler', 'table_altrow', 'tablemanager', 'tableofcontents', 'textile', 'tooltips', 'twikifilter', 'typogrify', 'unwrap', 'urlclass', 'urlicon', 'url_replace_filter', 'username_highlighter', 'video_filter', 'quote'); 371 372 if (!isset($profile->settings['ss'])) { 373 $profile->settings['filters']['filter/0'] = 1; 374 } 375 376 foreach ($all as $id => $filter) { 377 if (in_array(strtolower($filter->module), $modules_with_filters_to_skip)) { 378 continue; 379 } 380 //skip line break converter and email -> link 381 if ($filter->module == 'filter' && in_array($filter->delta, array(1, 2))) { 382 continue; 383 } 384 $form['security']['filters'][$id] = array( 385 '#type' => 'checkbox', 386 '#title' => check_plain($filter->name), 387 '#default_value' => !empty($profile->settings['filters'][$id]), 388 '#description' => check_plain(module_invoke($filter->module, 'filter', 'description', $filter->delta)), 389 ); 390 } 391 392 $form['security']['ss'] = array( 393 '#type' => 'radios', 394 '#title' => t('Security settings'), 395 '#default_value' => isset($profile->settings['ss']) ? $profile->settings['ss'] : '2', 396 '#options' => array( 397 '2' => t('Always run security filters for CKEditor.'), 398 '1' => t('Run security filters only when CKEditor is set to start automatically.'), 399 ), 400 '#description' => t('There are two ways of starting CKEditor: automatically and manually (via toggle or in a popup). If you decide to apply security filters only when CKEditor starts automatically, you will not be protected when toggling manually from plain textarea to CKEditor or when using CKEditor in the popup mode. Choose this option only if you can detect various attacks (mainly XSS) by yourself just by looking at the HTML code.'), 401 ); 402 403 $form['ckeditor_exclude_settings'] = array( 404 '#type' => 'fieldset', 405 '#title' => t('Visibility settings'), 406 '#collapsible' => TRUE, 407 '#collapsed' => TRUE, 408 '#description' => t('The following settings are combined with the visibility settings of the global profile.'), 409 ); 410 411 $form['ckeditor_exclude_settings']['min_rows'] = array( 412 '#type' => 'textfield', 413 '#title' => t('Minimum rows'), 414 '#default_value' => !empty($profile->settings['min_rows']) ? $profile->settings['min_rows'] : '1', 415 '#description' => t("CKEditor will be triggered if the textarea has more rows than the number given here. Enter '1' if you do not want to use this feature."), 416 ); 417 418 $form['ckeditor_exclude_settings']['excl_mode'] = array( 419 '#type' => 'radios', 420 '#title' => t('Use inclusion or exclusion mode'), 421 '#default_value' => (empty($profile->settings['excl_mode']) || in_array($profile->settings['excl_mode'], array(0, 2))) ? 0 : 1, 422 '#options' => array( 423 '0' => t('Exclude'), 424 '1' => t('Include') 425 ), 426 '#description' => t('Choose the way of disabling/enabling CKEditor on selected fields/paths (see below). Use <strong>Exclude</strong> to disable CKEditor on selected fields/paths. Use <strong>Include</strong> if you want to load CKEditor only on selected paths/fields.'), 427 ); 428 429 /** 430 * get excluded fields - so we can have normal textareas too 431 * split the phrase by any number of commas or space characters, 432 * which include " ", \r, \t, \n and \f 433 */ 434 $form['ckeditor_exclude_settings']['excl'] = array( 435 '#type' => 'textarea', 436 '#title' => t('Fields to exclude/include'), 437 '#cols' => 60, 438 '#rows' => 5, 439 '#prefix' => '<div style="margin-left:20px">', 440 '#suffix' => '</div>', 441 '#default_value' => !empty($profile->settings['excl']) ? $profile->settings['excl'] : '', 442 '#description' => t('Enter the paths to the textarea fields for which you want to enable or disable CKEditor.') . 443 ' ' . 444 t('See the !helppagelink for more information about defining field names. Short instruction is available below.', 445 array( 446 '!helppagelink' => l(t('Help page'), 'admin/help/ckeditor', array('fragment' => 'fieldinclexcl')) 447 ) 448 ) . 449 ' <ul><li>' . 450 t('Path structure: <strong>theme_name:content_type@path.element_id</strong>') . 451 '</li><li>' . 452 t('The following wildcards are available: "*", "?".') . 453 '</li><li>' . 454 t('Content type and theme name is optional. You may even just specify the path or the field ID.') . 455 '</li><li>' . 456 t('Examples:') . 457 '<ul><li><em>garland:blog@*.edit-body</em> - ' . 458 t('matches all fields of type <code>blog</code> called <code>edit-body</code> in the garland theme, on any page.') . 459 '<li><em>node/add/*.edit-user-*</em> - ' . 460 t('matches fields starting with <code>edit-user-</code> on pages starting with <code>node/add/</code>') . 461 '</li></ul></li></ul>', 462 '#wysiwyg' => FALSE, 463 ); 464 465 $form['ckeditor_exclude_settings']['simple_incl'] = array( 466 '#type' => 'textarea', 467 '#title' => t('Force simplified toolbar on the following fields'), 468 '#cols' => 60, 469 '#rows' => 5, 470 '#default_value' => !empty($profile->settings['simple_incl']) ? $profile->settings['simple_incl'] : '', 471 '#description' => t('Enter the paths to the textarea fields for which you want to force the simplified toolbar.') . 472 ' ' . 473 t( 474 'Please see the !helppagelink for more information about defining field names. Take a look at the exclusion settings (above) for a short instruction.', 475 array( 476 '!helppagelink' => l(t('Help page'), 'admin/help/ckeditor', array('fragment' => 'fieldinclexcl')) 477 ) 478 ), 479 '#wysiwyg' => FALSE, 480 ); 481 482 $form['appearance'] = array( 483 '#type' => 'fieldset', 484 '#title' => t('Editor appearance'), 485 '#collapsible' => TRUE, 486 '#collapsed' => TRUE, 487 ); 488 489 $form['appearance']['default'] = array( 490 '#type' => 'radios', 491 '#title' => t('Default state'), 492 '#default_value' => !empty($profile->settings['default']) ? $profile->settings['default'] : 't', 493 '#options' => array( 494 't' => t('Enabled'), 495 'f' => t('Disabled') 496 ), 497 '#description' => t('Default editor state. If disabled, the rich text editor may still be enabled by using toggle or popup window.'), 498 ); 499 500 $form['appearance']['show_toggle'] = array( 501 '#type' => 'radios', 502 '#title' => t('Show the disable/enable rich text editor toggle'), 503 '#default_value' => !empty($profile->settings['show_toggle']) ? $profile->settings['show_toggle'] : 't', 504 '#options' => array( 505 't' => t('Show'), 506 'f' => t('Hide') 507 ), 508 '#description' => t('Whether or not to show the disable/enable rich text editor toggle below the textarea. Works only if CKEditor is not running in a popup window (see below).'), 509 ); 510 511 $form['appearance']['popup'] = array( 512 '#type' => 'radios', 513 '#title' => t('Use CKEditor in a popup window'), 514 '#default_value' => !empty($profile->settings['popup']) ? $profile->settings['popup'] : 'f', 515 '#options' => array( 516 'f' => t('No'), 517 't' => t('Yes') 518 ), 519 '#description' => t('If this option is enabled, a link to a popup window will be used instead of a textarea replace.'), 520 ); 521 522 $form['appearance']['skin'] = array( 523 '#type' => 'select', 524 '#title' => t('Skin'), 525 '#default_value' => !empty($profile->settings['skin']) ? $profile->settings['skin'] : 'default', 526 '#options' => $skin_options, 527 '#description' => t('Choose a CKEditor skin.'), 528 ); 529 530 $ui_colors = array( 531 "default" => t('CKEditor default'), 532 "custom" => t('Select manually') 533 ); 534 if (function_exists('color_get_palette')) { 535 // apparently $theme is not initialized (?) 536 if (empty($theme)) { 537 init_theme(); 538 } 539 $palette = @color_get_palette($theme, FALSE); //[#652274] 540 $color_palette['default'] = '#D3D3D3'; 541 if (!empty($palette)) { 542 if (!empty($palette['base'])) { 543 $color_palette['color_base'] = $palette['base']; 544 $ui_colors["color_base"] = t('Color module: base'); 545 } 546 if (!empty($palette['top'])) { 547 $color_palette['color_top'] = $palette['top']; 548 $ui_colors["color_top"] = t('Color module: top'); 549 } 550 if (!empty($palette['bottom'])) { 551 $color_palette['color_bottom'] = $palette['bottom']; 552 $ui_colors["color_bottom"] = t('Color module: bottom'); 553 } 554 } 555 drupal_add_js(array('ckeditor_uicolor' => $color_palette), 'setting'); 556 } 557 558 $editor_path = ckeditor_path(FALSE); 559 $module_drupal_path = drupal_get_path('module', 'ckeditor'); 560 561 drupal_set_html_head('<script type="text/javascript">window.CKEDITOR_BASEPATH = "' . $editor_path . '/";</script>'); 562 drupal_set_html_head('<script type="text/javascript" src="'. $editor_path .'/ckeditor.js?I"></script>'); 563 drupal_add_js($module_drupal_path . '/ckeditor.config.js', 'file'); 564 drupal_add_js($module_drupal_path . '/includes/ckeditor.admin.js', 'file'); 565 566 if ($toolbar_wizard == 't') { 567 if (module_exists('jquery_ui')) { 568 if (!module_exists('jquery_update') || jquery_update_get_version() <= 1.2 ) 569 drupal_add_js($module_drupal_path . '/includes/jqueryUI/jquery-1.4.4.min.js', 'core'); 570 if (jquery_ui_get_version() > 1.6) { 571 jquery_ui_add(array('ui.sortable')); 572 } 573 else { 574 drupal_add_js($module_drupal_path . '/includes/jqueryUI/jquery-ui.min.js', 'file'); 575 drupal_add_js($module_drupal_path . '/includes/jqueryUI/jquery.ui.widget.min.js', 'file'); 576 drupal_add_js($module_drupal_path . '/includes/jqueryUI/jquery.ui.sortable.min.js', 'file'); 577 } 578 } 579 else { 580 if (!module_exists('jquery_update') || jquery_update_get_version() <= 1.2 ) 581 drupal_add_js($module_drupal_path . '/includes/jqueryUI/jquery-1.4.4.min.js', 'core'); 582 drupal_add_js($module_drupal_path . '/includes/jqueryUI/jquery-ui.min.js', 'file'); 583 drupal_add_js($module_drupal_path . '/includes/jqueryUI/jquery.ui.widget.min.js', 'file'); 584 drupal_add_js($module_drupal_path . '/includes/jqueryUI/jquery.ui.sortable.min.js', 'file'); 585 } 586 drupal_add_js($module_drupal_path . '/includes/jqueryUI/sort.js', 'file'); 587 } 588 589 $form['appearance']['uicolor'] = array( 590 '#type' => 'select', 591 '#title' => t('User interface color'), 592 '#default_value' => !empty($profile->settings['uicolor']) ? $profile->settings['uicolor'] : 'default', 593 '#options' => $ui_colors, 594 '#description' => t( 595 'Works only with the "!skin" skin.', 596 array( 597 '!skin' => 'Kama' 598 )), 599 ); 600 $form['appearance']['uicolor_textarea'] = array( 601 '#type' => 'textarea', 602 '#title' => '', 603 '#default_value' => 'Click the <strong>UI Color Picker</strong> button to set your color preferences.', 604 '#attributes' => array('style' => 'display:none', 'class' => 'ckeditor_ui_demo'), 605 '#resizable' => FALSE, 606 '#wysiwyg' => FALSE 607 ); 608 $form['appearance']['uicolor_user'] = array( 609 '#type' => 'hidden', 610 '#default_value' => !empty($profile->settings['uicolor_user']) ? $profile->settings['uicolor_user'] : 'default', 611 ); 612 613 $form['appearance']['toolbar'] = array( 614 '#type' => 'textarea', 615 '#title' => t('Toolbar'), 616 '#default_value' => !empty($profile->settings['toolbar']) ? $profile->settings['toolbar'] : '', 617 '#description' => t('Load sample toolbar: <a href="#" id="cke_toolbar_DrupalBasic" class="cke_load_toolbar">Basic</a> | <a href="#" id="cke_toolbar_DrupalAdvanced" class="cke_load_toolbar">Advanced</a> | <a href="#" id="cke_toolbar_DrupalFull" class="cke_load_toolbar">Full</a>'), 618 '#wysiwyg' => FALSE, 619 '#rows' => 15 620 ); 621 622 if ($toolbar_wizard == 't') { 623 $form['appearance']['toolbar_wizzard_used'] = array( 624 '#type' => 'markup', 625 '#value' => '<div>' . t('Used buttons') . '</div><div class="sortableList" id="groupLayout"></div><br/>', 626 '#description' => t('Currently used buttons'), 627 ); 628 629 drupal_add_js(array('cke_toolbar_buttons_all' => ckeditor_toolbar_buttons_all()), 'setting'); 630 631 $form['appearance']['toolbar_wizzard_all'] = array( 632 '#type' => 'markup', 633 '#value' => '<div>' . t('All buttons') . '</div><div id="allButtons" class="sortableList"></div><br/>', 634 '#description' => t('All available buttons'), 635 ); 636 } 637 638 $plugin_list = ckeditor_load_plugins(); 639 $plugins = array(); 640 if (isset($profile->settings['loadPlugins'])) { 641 foreach ($plugin_list AS $key => $val) { 642 $plugins[$key] = $val['desc']; 643 } 644 } 645 else { 646 $default_plugins = array(); 647 foreach ($plugin_list AS $key => $val) { 648 $plugins[$key] = $val['desc']; 649 if (isset($val['default']) && $val['default'] == 't') { 650 $default_plugins[] = $key; 651 } 652 } 653 } 654 655 $form['appearance']['loadPlugins'] = array( 656 '#type' => 'checkboxes', 657 '#title' => t('Plugins'), 658 '#default_value' => isset($profile->settings['loadPlugins']) ? array_keys((array) $profile->settings['loadPlugins']) : $default_plugins, 659 '#options' => $plugins, 660 '#description' => t('Choose the plugins that you want to enable in CKEditor.') 661 ); 662 663 $form['appearance']['expand'] = array( 664 '#type' => 'radios', 665 '#title' => t('Toolbar state on startup'), 666 '#default_value' => !empty($profile->settings['expand']) ? $profile->settings['expand'] : 't', 667 '#options' => array( 668 't' => t('Expanded'), 669 'f' => t('Collapsed') 670 ), 671 '#description' => t('The toolbar will start in an expanded or collapsed state.'), 672 ); 673 674 $form['appearance']['width'] = array( 675 '#type' => 'textfield', 676 '#title' => t('Editor width'), 677 '#default_value' => !empty($profile->settings['width']) ? $profile->settings['width'] : '100%', 678 '#description' => t("Editor interface width in pixels or percent. Examples: 400, 100%."), 679 '#size' => 40, 680 '#maxlength' => 128, 681 ); 682 683 $form['appearance']['lang'] = array( 684 '#type' => 'select', 685 '#title' => t('Language'), 686 '#default_value' => !empty($profile->settings['lang']) ? $profile->settings['lang'] : 'en', 687 '#options' => $lang_options, 688 '#description' => t('The language for the CKEditor user interface.') 689 ); 690 691 $form['appearance']['auto_lang'] = array( 692 '#type' => 'radios', 693 '#title' => t('Auto-detect language'), 694 '#default_value' => !empty($profile->settings['auto_lang']) ? $profile->settings['auto_lang'] : 't', 695 '#options' => array( 696 't' => t('Enabled'), 697 'f' => t('Disabled') 698 ), 699 '#description' => t('Automatically detect the user language.') 700 ); 701 702 $form['appearance']['language_direction'] = array( 703 '#type' => 'select', 704 '#title' => t('Language direction'), 705 '#default_value' => !empty($profile->settings['language_direction']) ? $profile->settings['language_direction'] : 'default', 706 '#options' => array( 707 'default' => t('Get from current locale (default)'), 708 'ltr' => t('Left-To-Right'),// language like English 709 'rtl' => t('Right-To-Left') // languages like Arabic 710 ), 711 '#description' => t( 712 '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.', 713 array( 714 '!bidiltr' => 'BidiLtr', 715 '!bidirtl' => 'BidiRtl' 716 ) 717 ) 718 ); 719 720 $form['output'] = array( 721 '#type' => 'fieldset', 722 '#title' => t('Cleanup and output'), 723 '#collapsible' => TRUE, 724 '#collapsed' => TRUE, 725 ); 726 727 $form['output']['enter_mode'] = array( 728 '#type' => 'select', 729 '#title' => t('Enter mode'), 730 '#default_value' => !empty($profile->settings['enter_mode']) ? $profile->settings['enter_mode'] : 'p', 731 '#options' => array( 732 'p' => '<p>', 733 'br' => '<br>', 734 'div' => '<div>' 735 ), 736 '#description' => t('Set which tag should be used by CKEditor when the <em>Enter</em> key is pressed.') 737 ); 738 739 $form['output']['shift_enter_mode'] = array( 740 '#type' => 'select', 741 '#title' => t('Shift+Enter mode'), 742 '#default_value' => !empty($profile->settings['shift_enter_mode']) ? $profile->settings['shift_enter_mode'] : 'br', 743 '#options' => array( 744 'p' => '<p>', 745 'br' => '<br>', 746 'div' => '<div>' 747 ), 748 '#description' => t('Set which tag should be used by CKEditor when the <em>Shift+Enter</em> key combination is pressed.') 749 ); 750 751 $form['output']['font_format'] = array( 752 '#type' => 'textfield', 753 '#title' => t('Font formats'), 754 '#default_value' => !empty($profile->settings['font_format']) ? $profile->settings['font_format'] : 'p;div;pre;address;h1;h2;h3;h4;h5;h6', 755 '#size' => 40, 756 '#maxlength' => 250, 757 '#description' => t( 758 'Semicolon-separated list of HTML font formats. Allowed values are: !allowed_values', 759 array( 760 '!allowed_values' => '<code>p;div;pre;address;h1;h2;h3;h4;h5;h6</code>' 761 ) 762 ) 763 ); 764 765 if (!empty($profile->settings['formatting']['custom_formatting_options'])) 766 foreach ($profile->settings['formatting']['custom_formatting_options'] as $k => $v) { 767 if ($v === 0) { 768 unset($profile->settings['formatting']['custom_formatting_options'][$k]); 769 } 770 } 771 772 $form['output']['custom_formatting'] = array( 773 '#type' => 'radios', 774 '#title' => t('Use custom formatting options'), 775 '#default_value' => !empty($profile->settings['custom_formatting']) ? $profile->settings['custom_formatting'] : 'f', 776 '#options' => array( 777 't' => t('Yes'), 778 'f' => t('No'), 779 ), 780 ); 781 782 $form['output']['formatting'] = array( 783 '#type' => 'fieldset', 784 '#title' => t('Custom formatting options'), 785 '#tree' => TRUE, 786 ); 787 788 $form['output']['formatting']['custom_formatting_options'] = array( 789 '#type' => 'checkboxes', 790 '#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'), 791 '#options' => array( 792 'indent' => t('Indent the element contents.'), 793 'breakBeforeOpen' => t('Break line before the opening tag.'), 794 'breakAfterOpen' => t('Break line after the opening tag.'), 795 'breakBeforeClose' => t('Break line before the closing tag.'), 796 'breakAfterClose' => t('Break line after the closing tag.'), 797 'pre_indent' => t('Indent the <code><pre></code> element contents.'), 798 ), 799 ); 800 801 $form['css'] = array( 802 '#type' => 'fieldset', 803 '#title' => t('CSS'), 804 '#collapsible' => TRUE, 805 '#collapsed' => TRUE 806 ); 807 808 $form['css']['css_mode'] = array( 809 '#type' => 'select', 810 '#title' => t('Editor CSS'), 811 '#default_value' => !empty($profile->settings['css_mode']) ? $profile->settings['css_mode'] : 'theme', 812 '#options' => array( 813 'theme' => t('Use theme CSS'), 814 'self' => t('Define CSS'), 815 'none' => t('CKEditor default') 816 ), 817 '#description' => t( 818 'Defines the CSS to be used in the editor area.!title_theme_css – load the !style_css file from the current site theme.!title_define_css – enter the CSS file path below.!title_ckeditor_default – use the default editor CSS.', 819 array( 820 '!title_theme_css' => '<br /><strong>' . t('Use theme CSS') . '</strong>', 821 '!title_define_css' => '<br /><strong>' . t('Define CSS') . '</strong>', 822 '!title_ckeditor_default' => '<br /><strong>' . t('CKEditor default') . '</strong>', 823 '!style_css' => '<code>style.css</code>' 824 ) 825 ) 826 ); 827 828 $form['css']['css_path'] = array( 829 '#type' => 'textfield', 830 '#title' => t('CSS file path'), 831 '#default_value' => !empty($profile->settings['css_path']) ? $profile->settings['css_path'] : "", 832 '#size' => 40, 833 '#maxlength' => 255, 834 '#description' => t( 835 'Enter the path to the CSS file (Example: !example1) or a list of CSS files separated with a comma (Example: !example2). Make sure you select the <strong>Define CSS</strong> option above.', 836 array( 837 '!example1' => '<code>"css/editor.css"</code>', 838 '!example2' => '<code>"/themes/garland/style.css,http://example.com/style.css"</code>', 839 )) . 840 '<br />' . 841 t( 842 'Available placeholders:!h - host name (!host).!t - path to theme (!theme).', 843 array( 844 '!h' => '<br /><code>%h</code>', 845 '!t' => '<br /><code>%t</code>', 846 '!host' => base_path(), 847 '!theme' => base_path() . path_to_theme() .'/' 848 ) 849 ) 850 ); 851 852 $form['css']['css_style'] = array( 853 '#type' => 'select', 854 '#title' => t('Predefined styles'), 855 '#default_value' => !empty($profile->settings['css_style']) ? $profile->settings['css_style'] : 'theme', 856 '#options' => array( 857 'theme' => t('Use theme ckeditor.styles.js'), 858 'self' => t('Define path to ckeditor.styles.js'), 859 'default' => t('CKEditor default') 860 ), 861 '#description' => t( 862 '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.', 863 array( 864 '!ckeditor_styles_js_file' => '<code>ckeditor.styles.js</code>', 865 '!ckeditor_styles_js_path' => '<code>' . ckeditor_path(TRUE) .'/ckeditor.styles.js</code>', 866 '!theme' => '<code>' . path_to_theme() . '/ckeditor.styles.js</code>' 867 ) 868 ) 869 ); 870 871 $form['css']['styles_path'] = array( 872 '#type' => 'textfield', 873 '#title' => t('Predefined styles path'), 874 '#default_value' => !empty($profile->settings['styles_path']) ? $profile->settings['styles_path'] : "", 875 '#size' => 40, 876 '#maxlength' => 255, 877 '#description' => t( 878 'Enter the path to a file with predefined styles (Example: !example1). Make sure you select the <strong>Define path to ckeditor.styles.js</strong> option above.', 879 array( 880 '!example1' => '<code>/ckeditor.styles.js</code>' 881 ) 882 ) . 883 '<br />' . 884 t( 885 'Available placeholders:!h – host name (!host).!t – path to theme !theme.!m – path to the CKEditor module !module.', 886 array( 887 '!h' => '<br /><code>%h</code>', 888 '!t' => '<br /><code>%t</code>', 889 '!m' => '<br /><code>%m</code>', 890 '!host' => '<code>' . base_path() . '</code>', 891 '!theme' => '<code>' . base_path() . path_to_theme() . '/</code>', 892 '!module' => '<code>' . drupal_get_path('module', 'ckeditor') . '</code>' 893 ) 894 ) 895 ); 896 897 $form['ckeditor_upload_settings'] = array( 898 '#type' => 'fieldset', 899 '#title' => t('File browser settings'), 900 '#collapsible' => TRUE, 901 '#collapsed' => TRUE, 902 '#description' => t( 903 'Set the file browser settings. A file browser will allow you to browse the files stored on the server and embed them as links, images, or Flash movies. CKEditor is compatible with such Drupal modules as !imce, !ib, !webfm or !elfinder. CKEditor can be also integrated with !ckfinder, an advanced Ajax file manager.', 904 array( 905 '!imce' => l(t('IMCE'), 'http://drupal.org/project/imce'), 906 '!ib' => l(t('Image Browser'), 'http://drupal.org/project/imagebrowser'), 907 '!webfm' => l(t('Web File Manager'), 'http://drupal.org/project/webfm'), 908 '!ckfinder' => l(t('CKFinder'), 'http://ckfinder.com'), 909 '!elfinder' => l(t('elFinder'), 'http://drupal.org/project/elfinder') 910 ) 911 ) 912 ); 913 914 $filebrowsers = array( 915 'none' => t('None'), 916 'ckfinder' => t('CKFinder'), 917 ); 918 919 $filebrowsers_dialogs = array( 920 '' => t('Same as in the Link dialog window'), 921 'ckfinder' => t('CKFinder'), 922 ); 923 924 if (module_exists('imce')) { 925 $filebrowsers['imce'] = t('IMCE'); 926 $filebrowsers_dialogs['imce'] = t('IMCE'); 927 } 928 929 if (module_exists('tinybrowser')) { 930 $filebrowsers['tinybrowser'] = t('TinyBrowser'); 931 $filebrowsers_dialogs['tinybrowser'] = t('TinyBrowser'); 932 } 933 934 if (module_exists('imagebrowser')) { 935 $filebrowsers['ib'] = t('Image Browser'); 936 $filebrowsers_dialogs['ib'] = t('Image Browser'); 937 } 938 939 if (module_exists('webfm_popup')) { 940 $filebrowsers['webfm'] = t('Web File Manager'); 941 $filebrowsers_dialogs['webfm'] = t('Web File Manager'); 942 } 943 944 if (module_exists('elfinder')) { 945 $filebrowsers['elfinder'] = t('elFinder'); 946 $filebrowsers_dialogs['elfinder'] = t('elFinder'); 947 } 948 949 $form['ckeditor_upload_settings']['filebrowser'] = array( 950 '#type' => 'select', 951 '#title' => t('File browser type (Link dialog window)'), 952 '#default_value' => !empty($profile->settings['filebrowser']) ? $profile->settings['filebrowser'] : 'none', 953 '#options' => $filebrowsers, 954 '#description' => t('Select the file browser that you would like to use to upload files.'), 955 ); 956 957 $form['ckeditor_upload_settings']['filebrowser_image'] = array( 958 '#type' => 'select', 959 '#title' => t('File browser type (Image dialog window)'), 960 '#default_value' => !empty($profile->settings['filebrowser_image']) ? $profile->settings['filebrowser_image'] : 'none', 961 '#options' => $filebrowsers_dialogs, 962 '#description' => t('Select the file browser that you would like to use to upload images.'), 963 ); 964 965 $form['ckeditor_upload_settings']['filebrowser_flash'] = array( 966 '#type' => 'select', 967 '#title' => t('File browser type (Flash dialog window)'), 968 '#default_value' => !empty($profile->settings['filebrowser_flash']) ? $profile->settings['filebrowser_flash'] : 'none', 969 '#options' => $filebrowsers_dialogs, 970 '#description' => t('Select the file browser that you would like to use to upload Flash movies.'), 971 ); 972 973 $current_user_files_path = empty($profile->settings['UserFilesPath']) ? "%b%f/" : $profile->settings['UserFilesPath']; 974 $current_user_files_path = strtr($current_user_files_path, array("%f" => file_directory_path(), "%u" => "UID", "%b" => base_path(), "%n" => "UNAME")); 975 976 $current_user_files_absolute_path = empty($profile->settings['UserFilesAbsolutePath']) ? "%d%b%f/" : $profile->settings['UserFilesAbsolutePath']; 977 $current_user_files_absolute_path = strtr($current_user_files_absolute_path, array("%f" => file_directory_path(), "%u" => "UID", "%b" => base_path(), "%d" => $_SERVER['DOCUMENT_ROOT'], "%n" => "UNAME")); 978 979 if (variable_get('file_downloads', '') != FILE_DOWNLOADS_PRIVATE) { 980 981 $form['ckeditor_upload_settings']['UserFilesPath'] = array( 982 '#type' => 'textfield', 983 '#prefix' => '<fieldset><legend>' . t('CKFinder settings') .'</legend>', 984 '#title' => t('Path to uploaded files'), 985 '#default_value' => !empty($profile->settings['UserFilesPath']) ? $profile->settings['UserFilesPath'] : "%b%f/", 986 '#size' => 40, 987 '#maxlength' => 255, 988 '#description' => t('Path to uploaded files relative to the document root.') . 989 '<br />' . 990 t( 991 'Available placeholders:!b – the base URL path of the Drupal installation <code>!base</code>.!f – Drupal file system path where the files are stored <code>!files</code>.!u – User ID.!n – Username.', 992 array( 993 '!n' => '<br /><code>%n</code>', 994 '!u' => '<br /><code>%u</code>', 995 '!f' => '<br/><code>%f</code>', 996 '!b' => '<br/><code>%b</code>', 997 '!files' => file_directory_path(), 998 '!base' => base_path() 999 ) 1000 ) . 1001 '<br />' . 1002 t('Current path: !path', 1003 array( 1004 '!path' => '<code>' . $current_user_files_path . '</code>' 1005 ) 1006 ) 1007 ); 1008 1009 $form['ckeditor_upload_settings']['UserFilesAbsolutePath'] = array( 1010 '#type' => 'textfield', 1011 '#title' => t('Absolute path to uploaded files'), 1012 '#default_value' => !empty($profile->settings['UserFilesAbsolutePath']) ? $profile->settings['UserFilesAbsolutePath'] : "%d%b%f/", 1013 '#size' => 40, 1014 '#maxlength' => 255, 1015 '#suffix' => '</fieldset>', 1016 '#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.') . 1017 '<br />' . 1018 t( 1019 'Available placeholders:!d – the server path to document root !root.!b – base URL path of the Drupal installation !base.!f – Drupal file system path where the files are stored !files.!u – User ID.!n – Username.', 1020 array( 1021 '!u' => '<br /><code>%u</code>', 1022 '!n' => '<br /><code>%n</code>', 1023 '!d' => '<br/><code>%d</code>', 1024 '!b' => '<br /><code>%b</code>', 1025 '!f' => '<br/><code>%f</code>', 1026 '!files' => '<code>' . file_directory_path() . '</code>', 1027 '!base' => '<code>' . base_path() . '</code>', 1028 '!root' => '<code>' . $_SERVER['DOCUMENT_ROOT'] . '</code>' 1029 ) 1030 ) . 1031 '<br />' . 1032 t('Current path: !path', 1033 array( 1034 '!path' => '<code>' . $current_user_files_absolute_path . '</code>' 1035 ) 1036 ) 1037 ); 1038 } 1039 1040 if (variable_get('file_downloads', '') == FILE_DOWNLOADS_PRIVATE) { 1041 $form['ckeditor_upload_settings']['private_path_descrption'] = array( 1042 '#value' => '<div>' . t( 1043 '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>.', 1044 array( 1045 '!url' => l(t('CKEditor Global Profile'), 'admin/settings/ckeditor/editg') 1046 ) 1047 ) . 1048 '</div>' 1049 ); 1050 } 1051 1052 $form['advanced'] = array( 1053 '#type' => 'fieldset', 1054 '#title' => t('Advanced options'), 1055 '#collapsible' => TRUE, 1056 '#collapsed' => TRUE, 1057 ); 1058 $form['advanced']['ckeditor_load_method'] = array( 1059 '#type' => 'select', 1060 '#title' => t('Loading method'), 1061 '#default_value' => !empty($profile->settings['ckeditor_load_method']) ? $profile->settings['ckeditor_load_method'] : 'ckeditor.js', 1062 '#options' => _ckeditor_load_methods(), 1063 '#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.', 1064 array( 1065 '!ckeditor_basic_js' => '<code>ckeditor_basic.js</code>' 1066 ) 1067 ) 1068 ); 1069 $form['advanced']['ckeditor_load_time_out'] = array( 1070 '#type' => 'textfield', 1071 '#title' => t('Loading timeout'), 1072 '#default_value' => !empty($profile->settings['ckeditor_load_time_out']) ? $profile->settings['ckeditor_load_time_out'] : "0", 1073 '#size' => 40, 1074 '#maxlength' => 255, 1075 '#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.', 1076 array( 1077 '!ckeditor_basic_js' => '<code>ckeditor_basic.js</code>' 1078 ) 1079 ) 1080 ); 1081 $form['advanced']['forcePasteAsPlainText'] = array( 1082 '#type' => 'select', 1083 '#title' => t('Force pasting as plain text'), 1084 '#default_value' => !empty($profile->settings['forcePasteAsPlainText']) ? $profile->settings['forcePasteAsPlainText'] : "f", 1085 '#options' => array( 1086 't' => t('Enabled'), 1087 'f' => t('Disabled') 1088 ), 1089 '#description' => t('If enabled, HTML content will be automatically changed to plain text when pasting.'), 1090 ); 1091 $form['advanced']['html_entities'] = array( 1092 '#type' => 'radios', 1093 '#title' => t('HTML Entities'), 1094 '#default_value' => !empty($profile->settings['html_entities']) ? $profile->settings['html_entities'] : 't', 1095 '#description' => t('Convert all applicable characters to HTML entities.'), 1096 '#options' => array( 1097 'f' => t('No'), 1098 't' => t('Yes') 1099 ), 1100 ); 1101 $form['advanced']['scayt_autoStartup'] = array( 1102 '#type' => 'radios', 1103 '#title' => t('Spellchecker'), 1104 '#default_value' => !empty($profile->settings['scayt_autoStartup']) ? $profile->settings['scayt_autoStartup'] : 'f', 1105 '#description' => t('If enabled, turns on SCAYT (Spell Check As You Type) automatically after loading the editor.'), 1106 '#options' => array( 1107 'f' => t('No'), 1108 't' => t('Yes') 1109 ), 1110 ); 1111 $form['advanced']['theme_config_js'] = array( 1112 '#type' => 'radios', 1113 '#title' => t('Load !ckeditor_config_js from the theme path', 1114 array( 1115 '!ckeditor_config_js' => '<code>ckeditor.config.js</code>' 1116 ) 1117 ), 1118 '#default_value' => !empty($profile->settings['theme_config_js']) ? $profile->settings['theme_config_js'] : 'f', 1119 '#options' => array( 1120 't' => t('Yes'), 1121 'f' => t('No') 1122 ), 1123 '#description' => t('When enabled, the editor will try to load the !ckeditor_config_js file from the theme directory.', 1124 array( 1125 '!ckeditor_config_js' => '<code>ckeditor.config.js</code>' 1126 ) 1127 ), 1128 ); 1129 $form['advanced']['js_conf'] = array( 1130 '#type' => 'textarea', 1131 '#title' => t('Custom JavaScript configuration'), 1132 '#default_value' => !empty($profile->settings['js_conf']) ? $profile->settings['js_conf'] : "", 1133 '#cols' => 60, 1134 '#rows' => 5, 1135 '#description' => t( 1136 '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.', 1137 array( 1138 '!ckeditor_config' => '<code>' . drupal_get_path('module', 'ckeditor') . "/ckeditor.config.js</code>", 1139 '!docs' => l(t('CKEditor documentation'), 'http://docs.cksource.com/ckeditor_api/symbols/CKEDITOR.config.html'), 1140 '@code' => "config.fontSize_sizes = '16/16px;24/24px;48/48px;'\nconfig.font_names = 'Arial;Times New Roman;Verdana'" 1141 ) 1142 ), 1143 '#wysiwyg' => FALSE 1144 ); 1145 1146 $form['submit'] = array( 1147 '#type' => 'submit', 1148 '#value' => t('Save') 1149 ); 1150 1151 return $form; 1152 } 1153 1154 /** 1155 * Profile validation. 1156 */ 1157 function ckeditor_admin_profile_form_validate($form, &$form_state) { 1158 $edit =& $form_state['values']; 1159 1160 //include mode and all other fields are empty, invalid 1161 if ($edit['excl_mode'] == 1 && empty($edit['excl'])) { 1162 form_set_error('excl_mode', t('Include mode selected, but no paths given. Enter at least one path where CKEditor should appear.')); 1163 } 1164 else { 1165 ckeditor_admin_profile_validate_fieldpaths('excl', $edit['excl']); 1166 } 1167 1168 ckeditor_admin_profile_validate_fieldpaths('simple_incl', $edit['simple_incl']); 1169 1170 if (!preg_match('/^\d+$/', trim($edit['min_rows']))) { 1171 form_set_error('min_rows', t('Minimum rows must be a valid number.')); 1172 } 1173 1174 if ($edit['default'] == 't' && $edit['popup'] == 't') { 1175 form_set_error('popup', t('If CKEditor is enabled by default, the popup window must be disabled.')); 1176 } 1177 1178 if ($edit['show_toggle'] == 't' && $edit['popup'] == 't') { 1179 form_set_error('popup', t('If toggle is enabled, the popup window must be disabled.')); 1180 } 1181 1182 if (!$edit['name']) { 1183 form_set_error('name', t('You must give a profile name.')); 1184 } 1185 elseif (!preg_match('/^[A-Za-z0-9_]+$/', $edit['name'])) { 1186 form_set_error('name', t('Enter a valid profile name. Only alphanumeric and underscore characters are allowed.')); 1187 } 1188 elseif ($edit['name'] == 'CKEditor Global Profile') { 1189 form_set_error('name', t('This profile name is reserved. Please choose a different name.')); 1190 } 1191 elseif (!isset($edit['_profile']) || ($edit['_profile']->name != $edit['name'])) { 1192 $result = ckeditor_profile_load($edit['name']); 1193 if (!empty($result)) { 1194 form_set_error('name', t('The profile name must be unique. A profile with this name already exists.')); 1195 } 1196 } 1197 1198 if (!preg_match('/^\d+%?$/', $edit['width'])) { 1199 form_set_error('width', t('Enter a valid width value. Examples: 400, 100%.')); 1200 } 1201 1202 if (!empty($edit['css_path'])) { 1203 if ($edit['css_mode'] != 'self') { 1204 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.')); 1205 } 1206 elseif (FALSE !== strpos($edit['css_path'], '"')) { 1207 form_set_error('css_path', t('Double quotes are not allowed in the CSS path.')); 1208 } 1209 elseif (substr($edit['css_path'], 0, 1) == "'" && substr($edit['css_path'], -1) == "'") { 1210 form_set_error('css_path', t('Enter a valid CSS path, do not surround it with quotes.')); 1211 } 1212 } 1213 1214 if (!empty($edit['styles_path'])) { 1215 if ($edit['css_style'] != 'self') { 1216 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.')); 1217 } 1218 elseif (FALSE !== strpos($edit['styles_path'], '"')) { 1219 form_set_error('styles_path', t('Double quotes are not allowed in the styles path.')); 1220 } 1221 elseif (substr($edit['styles_path'], 0, 1) == "'" && substr($edit['styles_path'], -1) == "'") { 1222 form_set_error('styles_path', t('Enter a valid styles path, do not surround it with quotes.')); 1223 } 1224 } 1225 1226 if (!empty($edit['font_format'])) { 1227 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'])) { 1228 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).')); 1229 } 1230 } 1231 1232 if (variable_get('file_downloads', '') !== FILE_DOWNLOADS_PRIVATE) { 1233 if (!empty($edit['UserFilesAbsolutePath']) && empty($edit['UserFilesPath'])) { 1234 form_set_error('UserFilesPath', t('The path to uploaded files is required.')); 1235 } 1236 if (!empty($edit['UserFilesPath']) && empty($edit['UserFilesAbsolutePath'])) { 1237 form_set_error('UserFilesPath', t('An absolute path to uploaded files is required.')); 1238 } 1239 } 1240 $load_methods=_ckeditor_load_methods(); 1241 if (!isset($load_methods[$edit['ckeditor_load_method']])) { 1242 form_set_error('ckeditor_load_method', t('Set a valid loading method.')); 1243 } 1244 if (!preg_match('#\d+#', $edit['ckeditor_load_time_out'])) { 1245 form_set_error('ckeditor_load_time_out', t('Enter a valid loading timeout in seconds.')); 1246 } 1247 1248 if (!preg_match('#^\s*\[(?:\s*(?:\{\s*[\w:\'" ,]*\s*\[(?:\s*([\'\"\"])(?:\w+|-)\1\s*[,]?\s*)+\]\s*\}|([\'\"\"])\/\2)\s*[,]?\s*)+\]\s*$#U', $edit['toolbar']) && !preg_match('#^\s*\[(?:\s*(?:\[(?:\s*([\'\"\"])(?:\w+|-)\1\s*[,]?\s*)+\]|([\'\"\"])\/\2)\s*[,]?\s*)+\]\s*$#', $edit['toolbar'])) { 1249 form_set_error('toolbar', t('Enter a valid toolbar configuration.')); 1250 } 1251 } 1252 1253 function ckeditor_admin_profile_form_submit($form, &$form_state) { 1254 $edit =& $form_state['values']; 1255 1256 if (isset($edit['_profile'])) { 1257 db_query("DELETE FROM {ckeditor_settings} WHERE name = '%s'", $edit['_profile']->name); 1258 db_query("DELETE FROM {ckeditor_role} WHERE name = '%s'", $edit['_profile']->name); 1259 drupal_set_message(t('Your CKEditor profile was updated.')); 1260 } 1261 else { 1262 drupal_set_message(t('Your CKEditor profile was created.')); 1263 } 1264 1265 $settings = ckeditor_admin_values_to_settings($edit); 1266 db_query("INSERT INTO {ckeditor_settings} (name, settings) VALUES ('%s', '%s')", $edit['name'], $settings); 1267 ckeditor_rebuild_selectors($edit['name']); 1268 if (!empty($edit['rids'])) { 1269 foreach (array_keys($edit['rids']) as $rid) { 1270 if ($edit['rids'][$rid]!=0) { 1271 db_query("INSERT INTO {ckeditor_role} (name, rid) VALUES ('%s', %d)", $edit['name'], $rid); 1272 } 1273 } 1274 } 1275 1276 $form_state['redirect'] = 'admin/settings/ckeditor'; 1277 } 1278 1279 function ckeditor_admin_global_profile_form($form_state, $mode = 'add') { 1280 module_load_include('inc', 'ckeditor', 'includes/ckeditor.lib'); 1281 if ($mode == 'edit') { 1282 $profile = ckeditor_profile_load('CKEditor Global Profile'); 1283 1284 $form['_profile'] = array( 1285 '#type' => 'value', 1286 '#value' => $profile, 1287 ); 1288 } 1289 else { 1290 $profile = new stdClass(); 1291 } 1292 1293 if ($mode == 'add') { 1294 $data = ckeditor_profile_load('CKEditor Global Profile'); 1295 if (!empty($data)) { 1296 drupal_set_message(t('The global profile already exists. Only one global profile is allowed.'), 'error'); 1297 drupal_not_found(); 1298 } 1299 1300 $btn = t('Create a global profile'); 1301 } 1302 else { 1303 $btn = t('Update the global profile'); 1304 } 1305 1306 $toolbar_wizard = !empty($profile->settings['toolbar_wizard']) ? $profile->settings['toolbar_wizard'] : 't'; 1307 drupal_add_js(array('ckeditor_toolbar_wizard' => $toolbar_wizard), 'setting'); 1308 1309 $form['common'] = array( 1310 '#type' => 'fieldset', 1311 '#title' => t('Main setup'), 1312 '#collapsible' => TRUE, 1313 '#collapsed' => TRUE 1314 ); 1315 1316 $roles = ckeditor_sorted_roles(); 1317 $rids = $rtext = array(); 1318 foreach ($roles as $rid => $name) { 1319 $rids[] = $rid; 1320 $rtext[] = '<strong>'. $rid .' - </strong>'. $name; 1321 } 1322 $form['common']['rank'] = array( 1323 '#type' => 'textfield', 1324 '#title' => t('Role precedence'), 1325 '#default_value' => implode('>', $rids), 1326 '#description' => t('A user with <strong>multiple roles</strong> gets the permissions of the highest one. Sort role IDs according to their <strong>precedence from higher to lower</strong> by putting the ">" character in between.'), 1327 ); 1328 if ($rids) { 1329 $form['common']['rank']['#description'] .= '<br />'. t('The following list contains the ID-name pairs of roles with access to CKEditor:') .'<div>'. implode('<br />', $rtext) .'</div>'; 1330 } 1331 else { 1332 $form['common']['rank']['#description'] .= '<br />'. t( 1333 'You have not assigned the "access ckeditor" !permissions yet.', 1334 array( 1335 '!permissions' => l(t('permissions'), 'admin/user/permissions') 1336 ) 1337 ); 1338 } 1339 1340 $form['ckeditor_exclude_settings'] = array( 1341 '#type' => 'fieldset', 1342 '#title' => t('Visibility settings'), 1343 '#collapsible' => TRUE, 1344 '#collapsed' => TRUE, 1345 '#description' => t('The following settings are combined with the visibility settings of the specific profile.'), 1346 ); 1347 1348 $form['ckeditor_exclude_settings']['excl_mode'] = array( 1349 '#type' => 'radios', 1350 '#title' => t('Use inclusion or exclusion mode'), 1351 '#default_value' => (empty($profile->settings['excl_mode']) || in_array($profile->settings['excl_mode'], array(0, 2))) ? 0 : 1, 1352 '#options' => array( 1353 '0' => t('Exclude'), 1354 '1' => t('Include') 1355 ), 1356 '#description' => t('Choose the way of disabling/enabling CKEditor on selected fields/paths (see below). Use <strong>Exclude</strong> to disable CKEditor on selected fields/paths. Use <strong>Include</strong> if you want to load CKEditor only on selected paths/fields.'), 1357 ); 1358 /** 1359 * get excluded fields - so we can have normal textareas too 1360 * split the phrase by any number of commas or space characters, 1361 * which include " ", \r, \t, \n and \f 1362 */ 1363 $form['ckeditor_exclude_settings']['excl'] = array( 1364 '#type' => 'textarea', 1365 '#title' => t('Fields to exclude/include'), 1366 '#cols' => 60, 1367 '#rows' => 5, 1368 '#prefix' => '<div style="margin-left:20px">', 1369 '#suffix' => '</div>', 1370 '#default_value' => !empty($profile->settings['excl']) ? $profile->settings['excl'] : '', 1371 '#description' => t('Enter the paths to the textarea fields for which you want to enable or disable CKEditor.') . 1372 ' ' . 1373 t( 1374 'See the !helppagelink for more information about defining field names. Short instruction is available below.', 1375 array( 1376 '!helppagelink' => l(t('Help page'), 'admin/help/ckeditor', array('fragment' => 'fieldinclexcl')) 1377 ) 1378 ) . 1379 ' <ul><li>' . 1380 t('Path structure: <strong>theme_name:content_type@path.element_id</strong>') . 1381 '</li><li>' . 1382 t('The following wildcards are available: "*", "?".') . 1383 '</li><li>' . 1384 t('Content type and theme name is optional. You may even specify only path or field id.') . 1385 '</li><li>' . 1386 t('Examples:') . 1387 '<ul><li><em>garland:blog@*.edit-body</em> - ' . 1388 t('matches all fields of type "blog" called edit-body in garland theme, on any page.') . 1389 '<li><em>node/add/*.edit-user-*</em> - ' . 1390 t('matches fields starting with "edit-user-" on pages starting with "node/add/') . 1391 '</li></ul></li></ul>', 1392 '#wysiwyg' => FALSE, 1393 ); 1394 1395 $form['ckeditor_exclude_settings']['simple_incl'] = array( 1396 '#type' => 'textarea', 1397 '#title' => t('Force simplified toolbar on the following fields'), 1398 '#cols' => 60, 1399 '#rows' => 5, 1400 '#default_value' => !empty($profile->settings['simple_incl']) ? $profile->settings['simple_incl'] : '', 1401 '#description' => t('Enter the paths to the textarea fields for which you want to force the simplified toolbar.') . 1402 ' ' . 1403 t( 1404 'See the !helppagelink for more information about defining field names. Take a look at the exclusion settings (above) for a short instruction.', 1405 array( 1406 '!helppagelink' => l(t('Help page'), 'admin/help/ckeditor', array('fragment' => 'fieldinclexcl')) 1407 ) 1408 ), 1409 '#wysiwyg' => FALSE, 1410 ); 1411 1412 $module_drupal_path = drupal_get_path('module', 'ckeditor'); 1413 1414 drupal_add_js($module_drupal_path . '/includes/ckeditor.admin.js', 'file'); 1415 1416 if ($toolbar_wizard == 't') { 1417 if (module_exists('jquery_ui')) { 1418 if (!module_exists('jquery_update') || jquery_update_get_version() <= 1.2 ) 1419 drupal_add_js($module_drupal_path . '/includes/jqueryUI/jquery-1.4.4.min.js', 'core'); 1420 if (jquery_ui_get_version() > 1.6) { 1421 jquery_ui_add(array('ui.sortable')); 1422 } 1423 else { 1424 drupal_add_js($module_drupal_path . '/includes/jqueryUI/jquery-ui.min.js', 'file'); 1425 drupal_add_js($module_drupal_path . '/includes/jqueryUI/jquery.ui.widget.min.js', 'file'); 1426 drupal_add_js($module_drupal_path . '/includes/jqueryUI/jquery.ui.sortable.min.js', 'file'); 1427 } 1428 } 1429 else { 1430 if (!module_exists('jquery_update') || jquery_update_get_version() <= 1.2 ) 1431 drupal_add_js($module_drupal_path . '/includes/jqueryUI/jquery-1.4.4.min.js', 'core'); 1432 drupal_add_js($module_drupal_path . '/includes/jqueryUI/jquery-ui.min.js', 'file'); 1433 drupal_add_js($module_drupal_path . '/includes/jqueryUI/jquery.ui.widget.min.js', 'file'); 1434 drupal_add_js($module_drupal_path . '/includes/jqueryUI/jquery.ui.sortable.min.js', 'file'); 1435 } 1436 drupal_add_js($module_drupal_path . '/includes/jqueryUI/sort.js', 'file'); 1437 } 1438 1439 $form['ckeditor_exclude_settings']['simple_toolbar'] = array( 1440 '#id' => 'edit-toolbar', 1441 '#type' => 'textarea', 1442 '#title' => t('Simplified toolbar'), 1443 '#default_value' => isset($profile->settings['simple_toolbar']) ? $profile->settings['simple_toolbar'] : "[ [ 'Format', 'Bold', 'Italic', '-', 'NumberedList','BulletedList', '-', 'Link', 'Unlink', 'Image' ] ]", 1444 '#wysiwyg' => FALSE, 1445 '#rows' => 15 1446 ); 1447 1448 if ($toolbar_wizard == 't') { 1449 $form['ckeditor_exclude_settings']['toolbar_wizzard_used'] = array( 1450 '#type' => 'markup', 1451 '#value' => '<div>' . t('Used buttons') . '</div><div class="sortableList" id="groupLayout"></div><br/>', 1452 '#description' => t('Currently used buttons'), 1453 ); 1454 1455 drupal_add_js(array('cke_toolbar_buttons_all' => ckeditor_toolbar_buttons_all(FALSE)), 'setting'); 1456 1457 $form['ckeditor_exclude_settings']['toolbar_wizzard_all'] = array( 1458 '#type' => 'markup', 1459 '#value' => '<div>' . t('All buttons') . '</div><div id="allButtons" class="sortableList"></div><br/>', 1460 '#description' => t('All available buttons'), 1461 ); 1462 } 1463 1464 $form['ckeditor_advanced_settings'] = array( 1465 '#type' => 'fieldset', 1466 '#title' => t('Advanced settings'), 1467 '#collapsible' => TRUE, 1468 '#collapsed' => TRUE, 1469 ); 1470 1471 $module_drupal_path = drupal_get_path('module', 'ckeditor'); 1472 1473 $form['ckeditor_advanced_settings']['ckeditor_path'] = array( 1474 '#type' => 'textfield', 1475 '#title' => t('Path to CKEditor'), 1476 '#default_value' => !empty($profile->settings['ckeditor_path']) ? $profile->settings['ckeditor_path'] : '%m/ckeditor', 1477 '#size' => 40, 1478 '#maxlength' => 128, 1479 '#description' => t( 1480 'The path to CKEditor (the WYSIWYG rich text editor downloaded from !ckeditorcom) relative to the document root.', 1481 array( 1482 '!ckeditorcom' => l(t('ckeditor.com'), 'http://ckeditor.com/download') 1483 ) 1484 ) . 1485 '<br />'. 1486 t( 1487 'Available placeholders:!b – base URL path of the Drupal installation (!base).!m – base URL path where the CKEditor module is stored (!files).!l – base URL path to the libraries directory (!library).<br />Current path: !path', 1488 array( 1489 '!b' => '<br /><code>%b</code>', 1490 '!m' => '<br /><code>%m</code>', 1491 '!l' => '<br /><code>%l</code>', 1492 '!path' => '<code>' . ckeditor_path(FALSE) . '</code>', 1493 '!base' => '<code>' . base_path() . '</code>', 1494 '!files' => '<code>' . base_path() . $module_drupal_path . '</code>', 1495 '!library' => '<code>' . base_path() . 'sites/all/libraries/</code>' 1496 ) 1497 ), 1498 '#required' => TRUE 1499 ); 1500 1501 $form['ckeditor_advanced_settings']['ckeditor_local_path'] = array( 1502 '#type' => 'textfield', 1503 '#title' => t('Local path to CKEditor'), 1504 '#default_value' => isset($profile->settings['ckeditor_local_path'])?$profile->settings['ckeditor_local_path']:'', 1505 '#size' => 40, 1506 '#maxlength' => 128, 1507 '#description' => t( 1508 '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.', 1509 array( 1510 '!indexphp' => '<code>index.php</code>' 1511 ) 1512 ) . 1513 '<br />' . 1514 t('Current path: !path', 1515 array( 1516 '!path' => '<code>' . ckeditor_path(TRUE) . '</code>' 1517 ) 1518 ) 1519 ); 1520 1521 $form['ckeditor_advanced_settings']['ckeditor_plugins_path'] = array( 1522 '#type' => 'textfield', 1523 '#title' => t('Path to the CKEditor plugins directory'), 1524 '#default_value' => !empty($profile->settings['ckeditor_plugins_path']) ? $profile->settings['ckeditor_plugins_path'] : '%m/plugins', 1525 '#size' => 40, 1526 '#maxlength' => 128, 1527 '#description' => t('Path to the CKEditor plugins directory relative to the document root.') . 1528 '<br />' . 1529 t( 1530 'Available placeholders:!b – the base URL path of the Drupal installation (!base).!m – the base URL path where the CKEditor module is stored (!files).!l – the base URL path to the libraries directory (!library).', 1531 array( 1532 '!b' => '<br /><code>%b</code>', 1533 '!m' => '<br /><code>%m</code>', 1534 '!l' => '<br /><code>%l</code>', 1535 '!base' => '<code>' . base_path() . '</code>', 1536 '!files' => '<code>' . base_path() . $module_drupal_path . '</code>' , 1537 '!library' => '<code>' . base_path() . 'sites/all/libraries/</code>' 1538 ) 1539 ) . 1540 '<br />' . 1541 t('Current path: !path', 1542 array( 1543 '!path' => '<code>' . ckeditor_plugins_path() . '</code>' 1544 ) 1545 ) 1546 ); 1547 1548 $form['ckeditor_advanced_settings']['ckeditor_plugins_local_path'] = array( 1549 '#type' => 'textfield', 1550 '#title' => t('Local path to the CKEditor plugins directory'), 1551 '#default_value' => isset($profile->settings['ckeditor_plugins_local_path'])?$profile->settings['ckeditor_plugins_local_path']:'', 1552 '#size' => 40, 1553 '#maxlength' => 128, 1554 '#description' => t( 1555 '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.<br />Current path: !path', 1556 array( 1557 '!indexphp' => '<code>index.php</code>' 1558 ) 1559 ) . 1560 '<br />' . 1561 t('Current path: !path', 1562 array( 1563 '!path' => '<code>' . ckeditor_plugins_path(TRUE) . '</code>' 1564 ) 1565 ) 1566 ); 1567 1568 $form['ckeditor_advanced_settings']['ckfinder_path'] = array( 1569 '#type' => 'textfield', 1570 '#title' => t('Path to CKFinder'), 1571 '#default_value' => !empty($profile->settings['ckfinder_path']) ? $profile->settings['ckfinder_path'] : '%m/ckfinder', 1572 '#size' => 40, 1573 '#maxlength' => 128, 1574 '#description' => t( 1575 'The path to CKFinder (AJAX based file manager downloaded from !ckfindercom) relative to the document root.', 1576 array( 1577 '!ckfindercom' => l(t('ckdiner.com'), 'http://ckfinder.com/download') 1578 ) 1579 ) . 1580 '<br />' . 1581 t( 1582 'Available placeholders:!b – the base URL path of the Drupal installation (!base).!m – path where the CKEditor module is stored (!files).!l – path to the libraries directory (!library).', 1583 array( 1584 '!b' => '<br /><code>%b</code>', 1585 '!m' => '<br /><code>%m</code>', 1586 '!l' => '<br /><code>%l</code>', 1587 '!base' => '<code>' . base_path() . '</code>', 1588 '!files' => '<code>' . base_path() . $module_drupal_path . '</code>', 1589 '!library' => '<code>' . base_path() . 'sites/all/libraries/</code>' 1590 ) 1591 ) . 1592 '<br />' . 1593 t('Current path: !path', 1594 array( 1595 '!path' => '<code>' . ckfinder_path() . '</code>' 1596 ) 1597 ) 1598 ); 1599 1600 $form['ckeditor_advanced_settings']['show_fieldnamehint'] = array( 1601 '#type' => 'radios', 1602 '#title' => t('Show field name hint below each rich text editor'), 1603 '#default_value' => !empty($profile->settings['show_fieldnamehint']) ? $profile->settings['show_fieldnamehint'] : 't', 1604 '#options' => array( 1605 't' => t('Yes'), 1606 'f' => t('No') 1607 ), 1608 '#description' => t('This only applies to users with the "administer ckeditor" permissions.'), 1609 ); 1610 1611 if (variable_get('file_downloads', '') == FILE_DOWNLOADS_PRIVATE) { 1612 $form['ckeditor_advanced_settings']['ckeditor_allow_download_private_files'] = array( 1613 '#type' => 'checkbox', 1614 '#title' => t('Enable access to files located in the private folder'), 1615 '#default_value' => !empty($profile->settings['ckeditor_allow_download_private_files']), 1616 '#return_value' => 't', 1617 '#description' => t( 1618 '<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.', 1619 array( 1620 '!private_path' => '<code>' . realpath(file_directory_path()) . '</code>' 1621 ) 1622 ), 1623 '#required' => FALSE 1624 ); 1625 1626 $current_private_dir = !empty($profile->settings['private_dir']) ? $profile->settings['private_dir'] : ''; 1627 $form['ckeditor_advanced_settings']['private_dir'] = array( 1628 '#type' => 'textfield', 1629 '#title' => t('Location of files uploaded with CKEditor in the private folder'), 1630 '#default_value' => !empty($profile->settings['private_dir']) ? $profile->settings['private_dir'] : '', 1631 '#size' => 40, 1632 '#maxlength' => 255, 1633 '#description' => t('The path relative to the location of the private directory where CKEditor should store uploaded files.') . 1634 '<br />' . 1635 t('System path to the private folder is: !system_path.', 1636 array( 1637 '!system_path' => '<code>' . realpath(file_directory_path()) . DIRECTORY_SEPARATOR . '</code>' 1638 ) 1639 ) . 1640 '<br />' . 1641 t('Available wildcard characters: !u – User ID.!n – Username', 1642 array( 1643 '!u' => '<br/><code>%u</code>', 1644 '!n' => '<br /><code>%n</code>' 1645 ) 1646 ) . 1647 '<br />' . 1648 t('Current path: !path', 1649 array( 1650 '!path' => '<code>' . $current_private_dir . ' (' . str_replace('/', DIRECTORY_SEPARATOR, file_create_path(str_replace(array('%u', '%n'), array('UID', 'UNAME'), $current_private_dir))) . ')</code>' 1651 ) 1652 ) 1653 ); 1654 } 1655 1656 if (function_exists('linktocontent_node_menu') && function_exists('pathfilter_filter')) { 1657 $form['ckeditor_advanced_settings']['linktoc'] = array( 1658 '#type' => 'select', 1659 '#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')), 1660 '#title' => t('Path Filter & Link To Content integration'), 1661 '#default_value' => empty($profile->settings['linktoc']) ? 'p' : $profile->settings['linktoc'], 1662 '#description' => t( 1663 'With the !plink extension it is possible to use internal: links. By default the !link extension is linking to nodes using paths.', 1664 array( 1665 '!plink' => l(t('Path Filter'), 'http://drupal.org/project/pathfilter'), 1666 '!link' => l(t('Link To Content'), 'http://drupal.org/project/linktocontent') 1667 ) 1668 ) 1669 ); 1670 } 1671 1672 $form['ckeditor_advanced_settings']['toolbar_wizard'] = array( 1673 '#type' => 'radios', 1674 '#title' => t('Use toolbar Drag&Drop feature'), 1675 '#default_value' => !empty($profile->settings['toolbar_wizard']) ? $profile->settings['toolbar_wizard'] : 't', 1676 '#options' => array( 1677 't' => t('Enabled'), 1678 'f' => t('Disabled') 1679 ), 1680 '#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.'), 1681 ); 1682 1683 $form['submit'] = array( 1684 '#type' => 'submit', 1685 '#value' => $btn 1686 ); 1687 1688 return $form; 1689 } 1690 1691 function ckeditor_admin_global_profile_form_validate($form, &$form_state) { 1692 $edit =& $form_state['values']; 1693 1694 if (!preg_match('#^\s*\[(?:\s*(?:\{\s*[\w:\'" ,]*\s*\[(?:\s*([\'\"\"])(?:\w+|-)\1\s*[,]?\s*)+\]\s*\}|([\'\"\"])\/\2)\s*[,]?\s*)+\]\s*$#U', $edit['simple_toolbar']) && !preg_match('#^\s*\[(?:\s*(?:\[(?:\s*([\'\"\"])(?:\w+|-)\1\s*[,]?\s*)+\]|([\'\"\"])\/\2)\s*[,]?\s*)+\]\s*$#', $edit['simple_toolbar'])) { 1695 form_set_error('simple_toolbar', t('Enter a valid toolbar configuration.')); 1696 } 1697 1698 //include mode and all other fields are empty, invalid 1699 if ($edit['excl_mode'] == 1 && empty($edit['excl'])) { 1700 form_set_error('excl_mode', t('Include mode selected, but no paths given. Enter at least one path where CKEditor should appear.')); 1701 } 1702 else { 1703 ckeditor_admin_profile_validate_fieldpaths('excl', $edit['excl']); 1704 } 1705 1706 ckeditor_admin_profile_validate_fieldpaths('simple_incl', $edit['simple_incl']); 1707 } 1708 1709 function ckeditor_admin_global_profile_form_submit($form, &$form_state) { 1710 module_load_include('inc', 'ckeditor', 'includes/ckeditor.lib'); 1711 $edit =& $form_state['values']; 1712 $edit['name'] = 'CKEditor Global Profile'; 1713 1714 if (isset($edit['rank'])) { 1715 $edit['rank'] = explode('>', str_replace(' ', '', $edit['rank'])); 1716 } 1717 1718 if (isset($edit['_profile'])) { 1719 db_query("DELETE FROM {ckeditor_settings} WHERE name = '%s'", $edit['_profile']->name); 1720 db_query("DELETE FROM {ckeditor_role} WHERE name = '%s'", $edit['_profile']->name); 1721 } 1722 1723 //strip whitespaces 1724 if (empty($edit['ckeditor_local_path'])) { 1725 $edit['ckeditor_local_path'] = ''; 1726 } 1727 else { 1728 $edit['ckeditor_local_path'] = trim($edit['ckeditor_local_path']); 1729 } 1730 1731 //strip slash from the end 1732 if (empty($edit['ckeditor_path'])) { 1733 $edit['ckeditor_path'] = ''; 1734 } 1735 $edit['ckeditor_path'] = trim(rtrim($edit['ckeditor_path'], "/")); 1736 if ($edit['ckeditor_path'] && 0 !== strpos($edit['ckeditor_path'], "/") && 0 !== strpos($edit['ckeditor_path'], "%")) { 1737 //ensure that slash is at the beginning 1738 $edit['ckeditor_path'] = "/". $edit['ckeditor_path']; 1739 } 1740 //no slash at the end 1741 $edit['ckeditor_local_path'] = trim(rtrim($edit['ckeditor_local_path'], "/")); 1742 1743 //strip whitespaces 1744 if (empty($edit['ckeditor_plugins_local_path'])) { 1745 $edit['ckeditor_plugins_local_path'] = ''; 1746 } 1747 else { 1748 $edit['ckeditor_plugins_local_path'] = trim($edit['ckeditor_plugins_local_path']); 1749 } 1750 1751 //strip slash from the end 1752 if (empty($edit['ckeditor_plugins_path'])) { 1753 $edit['ckeditor_plugins_path'] = ''; 1754 } 1755 $edit['ckeditor_plugins_path'] = trim(rtrim($edit['ckeditor_plugins_path'], "/")); 1756 if ($edit['ckeditor_plugins_path'] && 0 !== strpos($edit['ckeditor_plugins_path'], "/") && 0 !== strpos($edit['ckeditor_plugins_path'], "%")) { 1757 //ensure that slash is at the beginning 1758 $edit['ckeditor_plugins_path'] = "/". $edit['ckeditor_plugins_path']; 1759 } 1760 //no slash at the end 1761 $edit['ckeditor_plugins_path'] = trim(rtrim($edit['ckeditor_plugins_path'], "/")); 1762 1763 //strip slash from the end 1764 if (empty($edit['ckfinder_path'])) { 1765 $edit['ckfinder_path'] = ''; 1766 } 1767 $edit['ckfinder_path'] = trim(rtrim($edit['ckfinder_path'], "/")); 1768 if ($edit['ckfinder_path'] && 0 !== strpos($edit['ckfinder_path'], "/") && 0 !== strpos($edit['ckfinder_path'], "%")) { 1769 //ensure that slash is at the beginning 1770 $edit['ckfinder_path'] = "/" . $edit['ckfinder_path']; 1771 } 1772 1773 $settings = ckeditor_admin_values_to_settings($edit); 1774 db_query("INSERT INTO {ckeditor_settings} (name, settings) VALUES ('%s', '%s')", $edit['name'], $settings); 1775 ckeditor_rebuild_selectors($edit['name']); 1776 1777 drupal_set_message(t('The CKEditor Global Profile was saved.')); 1778 $form_state['redirect'] = 'admin/settings/ckeditor'; 1779 } 1780 1781 /** 1782 * Converts an array of form values to a serialized array that does not 1783 * contain Drupal Form API values 1784 */ 1785 function ckeditor_admin_values_to_settings($values) { 1786 $plugins = array(); 1787 if (isset($values['loadPlugins'])) { 1788 $plugins = $values['loadPlugins']; 1789 } 1790 unset($values['name'], $values['rids'], $values['_profile'], $values['op'], $values['submit'], $values['form_build_id'], $values['form_token'], $values['form_id'], $values['loadPlugins']); 1791 1792 module_load_include('inc', 'ckeditor', 'includes/ckeditor.lib'); 1793 $plugin_list = ckeditor_load_plugins(); 1794 $values['loadPlugins'] = array(); 1795 if (!empty($plugins)) { 1796 foreach (array_keys($plugins) as $plugin) { 1797 if ($plugins[$plugin] != '0') { 1798 $values['loadPlugins'][$plugin] = $plugin_list[$plugin]; 1799 } 1800 } 1801 } 1802 1803 return serialize($values); 1804 } 1805 1806 function ckeditor_admin_profile_validate_fieldpaths($fieldname, $paths) { 1807 $myerrors = array(); 1808 1809 $rules = preg_split('/[\s,]+/', $paths); 1810 1811 foreach ($rules as $rule) { 1812 $rule = trim($rule); 1813 if (!empty($rule) && strpos($rule, '.') === FALSE && strpos($rule, '/') === FALSE && strpos($rule, '-') === FALSE) { 1814 $myerrors[] = t( 1815 'Rule %rule is ambiguous: please append .* if %rule is a path or prepend *. if %rule is a field.', 1816 array( 1817 '%rule' => $rule 1818 ) 1819 ); 1820 } 1821 } 1822 1823 if (!empty($myerrors)) { 1824 form_set_error($fieldname, check_plain(implode('<br/>', $myerrors))); 1825 } 1826 } 1827 1828 function ckeditor_admin_profile_delete_form($form_state, $profile) { 1829 $form = array(); 1830 1831 $form['_profile'] = array( 1832 '#type' => 'value', 1833 '#value' => $profile, 1834 ); 1835 1836 $form['question'] = array( 1837 '#type' => 'item', 1838 '#value' => t( 1839 'Are you sure that you want to delete the CKEditor profile <strong>%profile</strong>?', 1840 array( 1841 '%profile' => $profile->name 1842 ) 1843 ) 1844 ); 1845 1846 $form['delete'] = array( 1847 '#type' => 'submit', 1848 '#id' => 'delete', 1849 '#value' => t('Delete'), 1850 ); 1851 1852 $form['back'] = array( 1853 '#type' => 'submit', 1854 '#id' => 'back', 1855 '#value' => t('Cancel'), 1856 ); 1857 1858 return $form; 1859 } 1860 1861 function ckeditor_admin_profile_delete_form_submit($form, &$form_state) { 1862 $v =& $form_state['values']; 1863 1864 if ($form_state['clicked_button']['#id'] == 'delete') { 1865 ckeditor_profile_delete($v['_profile']->name); 1866 drupal_set_message(t('The CKEditor profile was deleted.')); 1867 } 1868 1869 $form_state['redirect'] = 'admin/settings/ckeditor'; 1870 } 1871 1872 /** 1873 * Rebuilds the regular expression that is used to match the inclusion/exclusion rules 1874 * and the simplified toolbar rules 1875 * 1876 * @param string $name Name of the profile to process. If omitted, all profiles are rebuilt 1877 */ 1878 function ckeditor_rebuild_selectors($name = NULL) { 1879 if ($name == NULL) { 1880 $result = db_query("SELECT * FROM {ckeditor_settings}"); 1881 } 1882 else { 1883 $result = db_query("SELECT * FROM {ckeditor_settings} WHERE name = '%s'", $name); 1884 } 1885 1886 while (($data = db_fetch_object($result))) { 1887 if ($data->settings) { 1888 $settings = unserialize($data->settings); 1889 // [#654626] 1890 if (!isset($settings['excl'])) { 1891 $settings['excl'] = ''; 1892 } 1893 if (!isset($settings['simple_incl'])) { 1894 $settings['simple_incl'] = ''; 1895 } 1896 1897 foreach (array('excl', 'simple_incl') as $var) { 1898 $settings[$var .'_regex'] = ''; 1899 $rules = preg_split('/[\s,]+/', $settings[$var]); 1900 $regex = array(); 1901 1902 if (!empty($rules)) { 1903 foreach ($rules as $rule) { 1904 if (!empty($rule)) { 1905 $rule = ckeditor_parse_rule($rule); 1906 $regex[] = '(?:'. ckeditor_rule_to_regex($rule) .')'; 1907 } 1908 } 1909 1910 if (!empty($regex)) { 1911 $settings[$var .'_regex'] = '#'. implode('|', $regex) .'#'; 1912 } 1913 } 1914 } 1915 1916 db_query("UPDATE {ckeditor_settings} SET settings='%s' WHERE name='%s'", serialize($settings), $data->name); 1917 } 1918 } 1919 } 1920 1921 function ckeditor_rule_create($nodetype = '*', $path = '*', $fieldname = '*') { 1922 global $theme; 1923 1924 $rule = new stdClass(); 1925 $rule->nodetype = $nodetype; 1926 $rule->path = $path; 1927 $rule->field = $fieldname; 1928 $rule->theme = $theme; 1929 1930 return $rule; 1931 } 1932 1933 function ckeditor_parse_rule($rule) { 1934 $ruleobj = new stdClass(); 1935 1936 $colonpos = strpos($rule, ':'); 1937 if ($colonpos !== FALSE) { 1938 $ruleobj->theme = substr($rule, 0, $colonpos); 1939 $rule = substr($rule, $colonpos + 1); 1940 } 1941 else { 1942 $ruleobj->theme = '*'; 1943 } 1944 1945 $atpos = strpos($rule, '@'); 1946 if ($atpos !== FALSE) { 1947 $ruleobj->nodetype = substr($rule, 0, $atpos); 1948 $rule = substr($rule, $atpos + 1); 1949 } 1950 else { 1951 $ruleobj->nodetype = '*'; 1952 } 1953 1954 $dotpos = strpos($rule, '.'); 1955 if ($dotpos === FALSE) { 1956 if (strpos($rule, '/') === FALSE && strpos($rule, '-') !== FALSE) { 1957 // assume it's a field 1958 $ruleobj->path = '*'; 1959 $ruleobj->field = $rule; 1960 } 1961 elseif (strpos($rule, '/') !== FALSE) { 1962 // assume it's a path 1963 $ruleobj->path = $rule; 1964 $ruleobj->field = '*'; 1965 } 1966 else { 1967 return NULL; 1968 } 1969 } 1970 else { 1971 $ruleobj->path = substr($rule, 0, $dotpos); 1972 $ruleobj->field = str_replace('\.', '.', substr($rule, $dotpos + 1)); 1973 } 1974 1975 return $ruleobj; 1976 } 1977 1978 function ckeditor_rule_to_regex($rule) { 1979 static $replace = array('\*' => '.*', '\?' => '.'); 1980 1981 $field = str_replace('.', '\.', $rule->field); 1982 $regex = '^'. preg_quote($rule->theme, '#') . ':' . preg_quote($rule->nodetype, '#') .'@'. preg_quote($rule->path, '#') .'\.'. preg_quote($field, '#') .'$'; 1983 $regex = strtr($regex, $replace); 1984 1985 return $regex; 1986 } 1987 1988 function ckeditor_rule_to_string($rule) { 1989 $field = str_replace('.', '\.', $rule->field); 1990 $rulestr = $rule->theme . ':'; 1991 if ($rule->nodetype != '*') { 1992 $rulestr .= $rule->nodetype .'@'; 1993 } 1994 return $rulestr . $rule->path .'.'. $field; 1995 } 1996 1997 /** 1998 * Remove a profile from the database. 1999 */ 2000 function ckeditor_profile_delete($name) { 2001 db_query("DELETE FROM {ckeditor_settings} WHERE name = '%s'", $name); 2002 db_query("DELETE FROM {ckeditor_role} WHERE name = '%s'", $name); 2003 } 2004 2005 function _ckeditor_load_methods() { 2006 $result = array('ckeditor.js' => 'ckeditor.js'); 2007 if (file_exists(ckeditor_path(TRUE) . '/ckeditor_basic.js')) { 2008 $result['ckeditor_basic.js'] = 'ckeditor_basic.js'; 2009 } 2010 if (file_exists(ckeditor_path(TRUE) . '/ckeditor_source.js')) { 2011 $result['ckeditor_source.js'] = 'ckeditor_source.js (' . t('for developers only') . ')'; 2012 } 2013 return $result; 2014 } 2015 2016 /* 2017 * Disable WYSIWYG module 2018 */ 2019 function ckeditor_disable_wysiwyg($token) { 2020 if (!drupal_valid_token($token, 'ckeditorDisableWysiwyg')) { 2021 exit(); 2022 } 2023 module_disable(array('wysiwyg')); 2024 drupal_set_message(t('The WYSIWYG module is disabled.')); 2025 2026 drupal_goto('admin/settings/ckeditor'); 2027 } 2028 2029 /* 2030 * Get all available toolbar buttons 2031 */ 2032 function ckeditor_toolbar_buttons_all($addPlugins = TRUE) { 2033 $path = base_path() . drupal_get_path('module', 'ckeditor'); 2034 2035 //CKEditor default buttons 2036 $buttons = array( 2037 'Source' => array('name' => 'Source', 'icon' => $path . '/images/buttons/source.png', 'title' => 'Source', 'row' => 1), 2038 'Save' => array('name' => 'Save', 'icon' => $path . '/images/buttons/save.png', 'title' => 'Save', 'row' => 1), 2039 'NewPage' => array('name' => 'NewPage', 'icon' => $path . '/images/buttons/newPage.png', 'title' => 'New Page', 'row' => 1), 2040 'Preview' => array('name' => 'Preview', 'icon' => $path . '/images/buttons/preview.png', 'title' => 'Preview', 'row' => 1), 2041 'Templates' => array('name' => 'Templates', 'icon' => $path . '/images/buttons/templates.png', 'title' => 'Templates', 'row' => 1), 2042 'Cut' => array('name' => 'Cut', 'icon' => $path . '/images/buttons/cut.png', 'title' => 'Cut', 'row' => 1), 2043 'Copy' => array('name' => 'Copy', 'icon' => $path . '/images/buttons/copy.png', 'title' => 'Copy', 'row' => 1), 2044 'Paste' => array('name' => 'Paste', 'icon' => $path . '/images/buttons/paste.png', 'title' => 'Paste', 'row' => 1), 2045 'PasteText' => array('name' => 'PasteText', 'icon' => $path . '/images/buttons/pastePlainText.png', 'title' => 'Paste as plain text', 'row' => 1), 2046 'PasteFromWord' => array('name' => 'PasteFromWord', 'icon' => $path . '/images/buttons/pasteWord.png', 'title' => 'Paste from Word', 'row' => 1), 2047 'Print' => array('name' => 'Print', 'icon' => $path . '/images/buttons/print.png', 'title' => 'Print', 'row' => 1), 2048 'SpellChecker' => array('name' => 'SpellChecker', 'icon' => $path . '/images/buttons/checkSpelling.png', 'title' => 'Check Spelling', 'row' => 1), 2049 'Scayt' => array('name' => 'Scayt', 'icon' => $path . '/images/buttons/checkSpelling.png', 'title' => 'Spell Check As you Type', 'row' => 1), //TODO sprawdzic ta opcje 2050 'Undo' => array('name' => 'Undo', 'icon' => $path . '/images/buttons/undo.png', 'title' => 'Undo', 'row' => 1), 2051 'Redo' => array('name' => 'Redo', 'icon' => $path . '/images/buttons/redo.png', 'title' => 'Redo', 'row' => 1), 2052 'Find' => array('name' => 'Find', 'icon' => $path . '/images/buttons/find.png', 'title' => 'Find', 'row' => 1), 2053 'Replace' => array('name' => 'Replace', 'icon' => $path . '/images/buttons/replace.png', 'title' => 'Replace', 'row' => 1), 2054 'SelectAll' => array('name' => 'SelectAll', 'icon' => $path . '/images/buttons/selectAll.png', 'title' => 'Select All', 'row' => 1), 2055 'RemoveFormat' => array('name' => 'RemoveFormat', 'icon' => $path . '/images/buttons/removeFormat.png', 'title' => 'Remove Format', 'row' => 1), 2056 'Form' => array('name' => 'Form', 'icon' => $path . '/images/buttons/form.png', 'title' => 'Form', 'row' => 1), 2057 'Checkbox' => array('name' => 'Checkbox', 'icon' => $path . '/images/buttons/checkbox.png', 'title' => 'Checkbox', 'row' => 1), 2058 'Radio' => array('name' => 'Radio', 'icon' => $path . '/images/buttons/radioButton.png', 'title' => 'Radio Button', 'row' => 1), 2059 'TextField' => array('name' => 'TextField', 'icon' => $path . '/images/buttons/textField.png', 'title' => 'Text Field', 'row' => 1), 2060 'Select' => array('name' => 'Select', 'icon' => $path . '/images/buttons/selectionField.png', 'title' => 'Selection Field', 'row' => 1), 2061 'Button' => array('name' => 'Button', 'icon' => $path . '/images/buttons/button.png', 'title' => 'Button', 'row' => 1), 2062 'ImageButton' => array('name' => 'ImageButton', 'icon' => $path . '/images/buttons/imageButton.png', 'title' => 'Image Button', 'row' => 1), 2063 'HiddenField' => array('name' => 'HiddenField', 'icon' => $path . '/images/buttons/hiddenField.png', 'title' => 'Hidden Field', 'row' => 1), 2064 'Bold' => array('name' => 'Bold', 'icon' => $path . '/images/buttons/bold.png', 'title' => 'Bold', 'row' => 2), 2065 'Italic' => array('name' => 'Italic', 'icon' => $path . '/images/buttons/italic.png', 'type' => 'command' , 'title' => 'Italic', 'row' => 2), 2066 'Underline' => array('name' => 'Underline', 'icon' => $path . '/images/buttons/underline.png', 'title' => 'Underline', 'row' => 2), 2067 'Strike' => array('name' => 'Strike', 'icon' => $path . '/images/buttons/strike.png', 'title' => 'Strike Through', 'row' => 2), 2068 'Subscript' => array('name' => 'Subscript', 'icon' => $path . '/images/buttons/subscript.png', 'title' => 'Subscript', 'row' => 2), 2069 'Superscript' => array('name' => 'Superscript', 'icon' => $path . '/images/buttons/superscript.png', 'title' => 'Superscript', 'row' => 2), 2070 'NumberedList' => array('name' => 'NumberedList', 'icon' => $path . '/images/buttons/numberedList.png', 'title' => 'Insert/Remove Numbered List', 'row' => 2), 2071 'BulletedList' => array('name' => 'BulletedList', 'icon' => $path . '/images/buttons/bulletedList.png', 'title' => 'Insert/Remove Bulleted List', 'row' => 2), 2072 'Outdent' => array('name' => 'Outdent', 'icon' => $path . '/images/buttons/decreaseIndent.png', 'title' => 'Decrease Indent', 'row' => 2), 2073 'Indent' => array('name' => 'Indent', 'icon' => $path . '/images/buttons/increaseIndent.png', 'title' => 'Increase Indent', 'row' => 2), 2074 'Blockquote' => array('name' => 'Blockquote', 'icon' => $path . '/images/buttons/blockQuote.png', 'title' => 'Block Quote', 'row' => 2), 2075 'CreateDiv' => array('name' => 'CreateDiv', 'icon' => $path . '/images/buttons/createDivContainer.png', 'title' => 'Create Div Container', 'row' => 2), 2076 'JustifyLeft' => array('name' => 'JustifyLeft', 'icon' => $path . '/images/buttons/leftJustify.png', 'title' => 'Left Justify', 'row' => 2), 2077 'JustifyCenter' => array('name' => 'JustifyCenter', 'icon' => $path . '/images/buttons/centerJustify.png', 'title' => 'Center Justify', 'row' => 2), 2078 'JustifyRight' => array('name' => 'JustifyRight', 'icon' => $path . '/images/buttons/rightJustify.png', 'title' => 'Right Justify', 'row' => 2), 2079 'JustifyBlock' => array('name' => 'JustifyBlock', 'icon' => $path . '/images/buttons/blockJustify.png', 'title' => 'Block Justify', 'row' => 2), 2080 'BidiLtr' => array('name' => 'BidiLtr', 'icon' => $path . '/images/buttons/bidiLeft.png', 'title' => 'Text direction from left to right', 'row' => 2), 2081 'BidiRtl' => array('name' => 'BidiRtl', 'icon' => $path . '/images/buttons/bidiRight.png', 'title' => 'Text direction from right to left', 'row' => 2), 2082 'Link' => array('name' => 'Link', 'icon' => $path . '/images/buttons/link.png', 'title' => 'Link', 'row' => 2), 2083 'Unlink' => array('name' => 'Unlink', 'icon' => $path . '/images/buttons/unlink.png', 'title' => 'Unlink', 'row' => 2), 2084 'Anchor' => array('name' => 'Anchor', 'icon' => $path . '/images/buttons/anchor.png', 'title' => 'Anchor', 'row' => 2), 2085 'Image' => array('name' => 'Image', 'icon' => $path . '/images/buttons/image.png', 'title' => 'Image', 'row' => 2), 2086 'Flash' => array('name' => 'Flash', 'icon' => $path . '/images/buttons/flash.png', 'title' => 'Flash', 'row' => 2), 2087 'Table' => array('name' => 'Table', 'icon' => $path . '/images/buttons/table.png', 'title' => 'Table', 'row' => 2), 2088 'HorizontalRule' => array('name' => 'HorizontalRule', 'icon' => $path . '/images/buttons/horizontalLine.png', 'title' => 'Insert Horizontal Line', 'row' => 2), 2089 'Smiley' => array('name' => 'Smiley', 'icon' => $path . '/images/buttons/smiley.png', 'title' => 'Smiley', 'row' => 2), 2090 'SpecialChar' => array('name' => 'SpecialChar', 'icon' => $path . '/images/buttons/specialCharacter.png', 'title' => 'Inseert Special Character', 'row' => 2), 2091 'PageBreak' => array('name' => 'PageBreak', 'icon' => $path . '/images/buttons/pageBreakPrinting.png', 'title' => 'Insert Page Break for Printing', 'row' => 2), 2092 'Styles' => array('name' => 'Styles', 'icon' => $path . '/images/buttons/styles.png', 'title' => 'Formatting Styles', 'row' => 3), 2093 'Format' => array('name' => 'Format', 'icon' => $path . '/images/buttons/format.png', 'title' => 'Paragraph Format', 'row' => 3), 2094 'Font' => array('name' => 'Font', 'icon' => $path . '/images/buttons/font.png', 'title' => 'Font Name', 'row' => 3), 2095 'FontSize' => array('name' => 'FontSize', 'icon' => $path . '/images/buttons/fontSize.png', 'title' => 'Font Size', 'row' => 3), 2096 'TextColor' => array('name' => 'TextColor', 'icon' => $path . '/images/buttons/textColor.png', 'title' => 'Text Color', 'row' => 3), 2097 'BGColor' => array('name' => 'BGColor', 'icon' => $path . '/images/buttons/backgroundColor.png', 'title' => 'Background Color', 'row' => 3), 2098 'Maximize' => array('name' => 'Maximize', 'icon' => $path . '/images/buttons/maximize.png', 'title' => 'Maximize', 'row' => 3), 2099 'ShowBlocks' => array('name' => 'ShowBlocks', 'icon' => $path . '/images/buttons/showBlocks.png', 'title' => 'Show Blocks', 'row' => 3), 2100 'Iframe' => array('name' => 'Iframe', 'icon' => $path . '/images/buttons/iframe.png', 'title' => 'IFrame', 'row' => 3), 2101 'About' => array('name' => 'About', 'icon' => $path . '/images/buttons/about.png', 'title' => 'About', 'row' => 3), 2102 '__spacer' => array('name' => FALSE, 'icon' => $path . '/images/buttons/spacer.png', 'title' => 'Spacer', 'row' => 4), 2103 '__group' => array('name' => FALSE, 'icon' => $path . '/images/buttons/group.png', 'title' => 'Group', 'row' => 4) 2104 ); 2105 2106 if ($addPlugins === TRUE) { 2107 $plugins = ckeditor_load_plugins(TRUE); 2108 foreach ($plugins as $plugin_name => $plugin) { 2109 if (!isset($plugin['buttons']) || $plugin['buttons'] == FALSE) continue; 2110 foreach ((array) $plugin['buttons'] as $button_name => $button) { 2111 $buttons[$button_name] = array('name' => $button_name, 'icon' => $plugin['path'] . $button['icon'], 'title' => t($button['label']), 'row' => 4); 2112 } 2113 } 2114 } 2115 2116 return $buttons; 2117 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
| Generated: Mon Jul 9 18:01:44 2012 | Cross-referenced by PHPXref 0.7 |