[ Index ]

PHP Cross Reference of phpwcms V1.4.7 _r403 (01.11.10)

title

Body

[close]

/include/inc_ext/ckeditor/ -> ckeditor_php5.php (source)

   1  <?php
   2  /*
   3  * Copyright (c) 2003-2010, CKSource - Frederico Knabben. All rights reserved.
   4  * For licensing, see LICENSE.html or http://ckeditor.com/license
   5  */
   6  
   7  /**
   8   * \brief CKEditor class that can be used to create editor
   9   * instances in PHP pages on server side.
  10   * @see http://ckeditor.com
  11   *
  12   * Sample usage:
  13   * @code
  14   * $CKEditor = new CKEditor();
  15   * $CKEditor->editor("editor1", "<p>Initial value.</p>");
  16   * @endcode
  17   */
  18  class CKEditor
  19  {
  20      /**
  21       * The version of %CKEditor.
  22       */
  23      const version = '3.4.1';
  24      /**
  25       * A constant string unique for each release of %CKEditor.
  26       */
  27      const timestamp = 'A8LE4JO';
  28  
  29      /**
  30       * URL to the %CKEditor installation directory (absolute or relative to document root).
  31       * If not set, CKEditor will try to guess it's path.
  32       *
  33       * Example usage:
  34       * @code
  35       * $CKEditor->basePath = '/ckeditor/';
  36       * @endcode
  37       */
  38      public $basePath;
  39      /**
  40       * An array that holds the global %CKEditor configuration.
  41       * For the list of available options, see http://docs.cksource.com/ckeditor_api/symbols/CKEDITOR.config.html
  42       *
  43       * Example usage:
  44       * @code
  45       * $CKEditor->config['height'] = 400;
  46       * // Use @@ at the beggining of a string to ouput it without surrounding quotes.
  47       * $CKEditor->config['width'] = '@@screen.width * 0.8';
  48       * @endcode
  49       */
  50      public $config = array();
  51      /**
  52       * A boolean variable indicating whether CKEditor has been initialized.
  53       * Set it to true only if you have already included
  54       * &lt;script&gt; tag loading ckeditor.js in your website.
  55       */
  56      public $initialized = false;
  57      /**
  58       * Boolean variable indicating whether created code should be printed out or returned by a function.
  59       *
  60       * Example 1: get the code creating %CKEditor instance and print it on a page with the "echo" function.
  61       * @code
  62       * $CKEditor = new CKEditor();
  63       * $CKEditor->returnOutput = true;
  64       * $code = $CKEditor->editor("editor1", "<p>Initial value.</p>");
  65       * echo "<p>Editor 1:</p>";
  66       * echo $code;
  67       * @endcode
  68       */
  69      public $returnOutput = false;
  70      /**
  71       * An array with textarea attributes.
  72       *
  73       * When %CKEditor is created with the editor() method, a HTML &lt;textarea&gt; element is created,
  74       * it will be displayed to anyone with JavaScript disabled or with incompatible browser.
  75       */
  76      public $textareaAttributes = array( "rows" => 8, "cols" => 60 );
  77      /**
  78       * A string indicating the creation date of %CKEditor.
  79       * Do not change it unless you want to force browsers to not use previously cached version of %CKEditor.
  80       */
  81      public $timestamp = "A8LE4JO";
  82      /**
  83       * An array that holds event listeners.
  84       */
  85      private $events = array();
  86      /**
  87       * An array that holds global event listeners.
  88       */
  89      private $globalEvents = array();
  90  
  91      /**
  92       * Main Constructor.
  93       *
  94       *  @param $basePath (string) URL to the %CKEditor installation directory (optional).
  95       */
  96  	function __construct($basePath = null) {
  97          if (!empty($basePath)) {
  98              $this->basePath = $basePath;
  99          }
 100      }
 101  
 102      /**
 103       * Creates a %CKEditor instance.
 104       * In incompatible browsers %CKEditor will downgrade to plain HTML &lt;textarea&gt; element.
 105       *
 106       * @param $name (string) Name of the %CKEditor instance (this will be also the "name" attribute of textarea element).
 107       * @param $value (string) Initial value (optional).
 108       * @param $config (array) The specific configurations to apply to this editor instance (optional).
 109       * @param $events (array) Event listeners for this editor instance (optional).
 110       *
 111       * Example usage:
 112       * @code
 113       * $CKEditor = new CKEditor();
 114       * $CKEditor->editor("field1", "<p>Initial value.</p>");
 115       * @endcode
 116       *
 117       * Advanced example:
 118       * @code
 119       * $CKEditor = new CKEditor();
 120       * $config = array();
 121       * $config['toolbar'] = array(
 122       *     array( 'Source', '-', 'Bold', 'Italic', 'Underline', 'Strike' ),
 123       *     array( 'Image', 'Link', 'Unlink', 'Anchor' )
 124       * );
 125       * $events['instanceReady'] = 'function (ev) {
 126       *     alert("Loaded: " + ev.editor.name);
 127       * }';
 128       * $CKEditor->editor("field1", "<p>Initial value.</p>", $config, $events);
 129       * @endcode
 130       */
 131  	public function editor($name, $value = "", $config = array(), $events = array())
 132      {
 133          $attr = "";
 134          foreach ($this->textareaAttributes as $key => $val) {
 135              $attr.= " " . $key . '="' . str_replace('"', '&quot;', $val) . '"';
 136          }
 137          $out = "<textarea name=\"" . $name . "\"" . $attr . ">" . htmlspecialchars($value) . "</textarea>\n";
 138          if (!$this->initialized) {
 139              $out .= $this->init();
 140          }
 141  
 142          $_config = $this->configSettings($config, $events);
 143  
 144          $js = $this->returnGlobalEvents();
 145          if (!empty($_config))
 146              $js .= "CKEDITOR.replace('".$name."', ".$this->jsEncode($_config).");";
 147          else
 148              $js .= "CKEDITOR.replace('".$name."');";
 149  
 150          $out .= $this->script($js);
 151  
 152          if (!$this->returnOutput) {
 153              print $out;
 154              $out = "";
 155          }
 156  
 157          return $out;
 158      }
 159  
 160      /**
 161       * Replaces a &lt;textarea&gt; with a %CKEditor instance.
 162       *
 163       * @param $id (string) The id or name of textarea element.
 164       * @param $config (array) The specific configurations to apply to this editor instance (optional).
 165       * @param $events (array) Event listeners for this editor instance (optional).
 166       *
 167       * Example 1: adding %CKEditor to &lt;textarea name="article"&gt;&lt;/textarea&gt; element:
 168       * @code
 169       * $CKEditor = new CKEditor();
 170       * $CKEditor->replace("article");
 171       * @endcode
 172       */
 173  	public function replace($id, $config = array(), $events = array())
 174      {
 175          $out = "";
 176          if (!$this->initialized) {
 177              $out .= $this->init();
 178          }
 179  
 180          $_config = $this->configSettings($config, $events);
 181  
 182          $js = $this->returnGlobalEvents();
 183          if (!empty($_config)) {
 184              $js .= "CKEDITOR.replace('".$id."', ".$this->jsEncode($_config).");";
 185          }
 186          else {
 187              $js .= "CKEDITOR.replace('".$id."');";
 188          }
 189          $out .= $this->script($js);
 190  
 191          if (!$this->returnOutput) {
 192              print $out;
 193              $out = "";
 194          }
 195  
 196          return $out;
 197      }
 198  
 199      /**
 200       * Replace all &lt;textarea&gt; elements available in the document with editor instances.
 201       *
 202       * @param $className (string) If set, replace all textareas with class className in the page.
 203       *
 204       * Example 1: replace all &lt;textarea&gt; elements in the page.
 205       * @code
 206       * $CKEditor = new CKEditor();
 207       * $CKEditor->replaceAll();
 208       * @endcode
 209       *
 210       * Example 2: replace all &lt;textarea class="myClassName"&gt; elements in the page.
 211       * @code
 212       * $CKEditor = new CKEditor();
 213       * $CKEditor->replaceAll( 'myClassName' );
 214       * @endcode
 215       */
 216  	public function replaceAll($className = null)
 217      {
 218          $out = "";
 219          if (!$this->initialized) {
 220              $out .= $this->init();
 221          }
 222  
 223          $_config = $this->configSettings();
 224  
 225          $js = $this->returnGlobalEvents();
 226          if (empty($_config)) {
 227              if (empty($className)) {
 228                  $js .= "CKEDITOR.replaceAll();";
 229              }
 230              else {
 231                  $js .= "CKEDITOR.replaceAll('".$className."');";
 232              }
 233          }
 234          else {
 235              $classDetection = "";
 236              $js .= "CKEDITOR.replaceAll( function(textarea, config) {\n";
 237              if (!empty($className)) {
 238                  $js .= "    var classRegex = new RegExp('(?:^| )' + '". $className ."' + '(?:$| )');\n";
 239                  $js .= "    if (!classRegex.test(textarea.className))\n";
 240                  $js .= "        return false;\n";
 241              }
 242              $js .= "    CKEDITOR.tools.extend(config, ". $this->jsEncode($_config) .", true);";
 243              $js .= "} );";
 244  
 245          }
 246  
 247          $out .= $this->script($js);
 248  
 249          if (!$this->returnOutput) {
 250              print $out;
 251              $out = "";
 252          }
 253  
 254          return $out;
 255      }
 256  
 257      /**
 258       * Adds event listener.
 259       * Events are fired by %CKEditor in various situations.
 260       *
 261       * @param $event (string) Event name.
 262       * @param $javascriptCode (string) Javascript anonymous function or function name.
 263       *
 264       * Example usage:
 265       * @code
 266       * $CKEditor->addEventHandler('instanceReady', 'function (ev) {
 267       *     alert("Loaded: " + ev.editor.name);
 268       * }');
 269       * @endcode
 270       */
 271  	public function addEventHandler($event, $javascriptCode)
 272      {
 273          if (!isset($this->events[$event])) {
 274              $this->events[$event] = array();
 275          }
 276          // Avoid duplicates.
 277          if (!in_array($javascriptCode, $this->events[$event])) {
 278              $this->events[$event][] = $javascriptCode;
 279          }
 280      }
 281  
 282      /**
 283       * Clear registered event handlers.
 284       * Note: this function will have no effect on already created editor instances.
 285       *
 286       * @param $event (string) Event name, if not set all event handlers will be removed (optional).
 287       */
 288  	public function clearEventHandlers($event = null)
 289      {
 290          if (!empty($event)) {
 291              $this->events[$event] = array();
 292          }
 293          else {
 294              $this->events = array();
 295          }
 296      }
 297  
 298      /**
 299       * Adds global event listener.
 300       *
 301       * @param $event (string) Event name.
 302       * @param $javascriptCode (string) Javascript anonymous function or function name.
 303       *
 304       * Example usage:
 305       * @code
 306       * $CKEditor->addGlobalEventHandler('dialogDefinition', 'function (ev) {
 307       *     alert("Loading dialog: " + ev.data.name);
 308       * }');
 309       * @endcode
 310       */
 311  	public function addGlobalEventHandler($event, $javascriptCode)
 312      {
 313          if (!isset($this->globalEvents[$event])) {
 314              $this->globalEvents[$event] = array();
 315          }
 316          // Avoid duplicates.
 317          if (!in_array($javascriptCode, $this->globalEvents[$event])) {
 318              $this->globalEvents[$event][] = $javascriptCode;
 319          }
 320      }
 321  
 322      /**
 323       * Clear registered global event handlers.
 324       * Note: this function will have no effect if the event handler has been already printed/returned.
 325       *
 326       * @param $event (string) Event name, if not set all event handlers will be removed (optional).
 327       */
 328  	public function clearGlobalEventHandlers($event = null)
 329      {
 330          if (!empty($event)) {
 331              $this->globalEvents[$event] = array();
 332          }
 333          else {
 334              $this->globalEvents = array();
 335          }
 336      }
 337  
 338      /**
 339       * Prints javascript code.
 340       *
 341       * @param string $js
 342       */
 343  	private function script($js)
 344      {
 345          $out = "<script type=\"text/javascript\">";
 346          $out .= "//<![CDATA[\n";
 347          $out .= $js;
 348          $out .= "\n//]]>";
 349          $out .= "</script>\n";
 350  
 351          return $out;
 352      }
 353  
 354      /**
 355       * Returns the configuration array (global and instance specific settings are merged into one array).
 356       *
 357       * @param $config (array) The specific configurations to apply to editor instance.
 358       * @param $events (array) Event listeners for editor instance.
 359       */
 360  	private function configSettings($config = array(), $events = array())
 361      {
 362          $_config = $this->config;
 363          $_events = $this->events;
 364  
 365          if (is_array($config) && !empty($config)) {
 366              $_config = array_merge($_config, $config);
 367          }
 368  
 369          if (is_array($events) && !empty($events)) {
 370              foreach ($events as $eventName => $code) {
 371                  if (!isset($_events[$eventName])) {
 372                      $_events[$eventName] = array();
 373                  }
 374                  if (!in_array($code, $_events[$eventName])) {
 375                      $_events[$eventName][] = $code;
 376                  }
 377              }
 378          }
 379  
 380          if (!empty($_events)) {
 381              foreach($_events as $eventName => $handlers) {
 382                  if (empty($handlers)) {
 383                      continue;
 384                  }
 385                  else if (count($handlers) == 1) {
 386                      $_config['on'][$eventName] = '@@'.$handlers[0];
 387                  }
 388                  else {
 389                      $_config['on'][$eventName] = '@@function (ev){';
 390                      foreach ($handlers as $handler => $code) {
 391                          $_config['on'][$eventName] .= '('.$code.')(ev);';
 392                      }
 393                      $_config['on'][$eventName] .= '}';
 394                  }
 395              }
 396          }
 397  
 398          return $_config;
 399      }
 400  
 401      /**
 402       * Return global event handlers.
 403       */
 404  	private function returnGlobalEvents()
 405      {
 406          static $returnedEvents;
 407          $out = "";
 408  
 409          if (!isset($returnedEvents)) {
 410              $returnedEvents = array();
 411          }
 412  
 413          if (!empty($this->globalEvents)) {
 414              foreach ($this->globalEvents as $eventName => $handlers) {
 415                  foreach ($handlers as $handler => $code) {
 416                      if (!isset($returnedEvents[$eventName])) {
 417                          $returnedEvents[$eventName] = array();
 418                      }
 419                      // Return only new events
 420                      if (!in_array($code, $returnedEvents[$eventName])) {
 421                          $out .= ($code ? "\n" : "") . "CKEDITOR.on('". $eventName ."', $code);";
 422                          $returnedEvents[$eventName][] = $code;
 423                      }
 424                  }
 425              }
 426          }
 427  
 428          return $out;
 429      }
 430  
 431      /**
 432       * Initializes CKEditor (executed only once).
 433       */
 434  	private function init()
 435      {
 436          static $initComplete;
 437          $out = "";
 438  
 439          if (!empty($initComplete)) {
 440              return "";
 441          }
 442  
 443          if ($this->initialized) {
 444              $initComplete = true;
 445              return "";
 446          }
 447  
 448          $args = "";
 449          $ckeditorPath = $this->ckeditorPath();
 450  
 451          if (!empty($this->timestamp) && $this->timestamp != "%"."TIMESTAMP%") {
 452              $args = '?t=' . $this->timestamp;
 453          }
 454  
 455          // Skip relative paths...
 456          if (strpos($ckeditorPath, '..') !== 0) {
 457              $out .= $this->script("window.CKEDITOR_BASEPATH='". $ckeditorPath ."';");
 458          }
 459  
 460          $out .= "<script type=\"text/javascript\" src=\"" . $ckeditorPath . 'ckeditor.js' . $args . "\"></script>\n";
 461  
 462          $extraCode = "";
 463          if ($this->timestamp != self::timestamp) {
 464              $extraCode .= ($extraCode ? "\n" : "") . "CKEDITOR.timestamp = '". $this->timestamp ."';";
 465          }
 466          if ($extraCode) {
 467              $out .= $this->script($extraCode);
 468          }
 469  
 470          $initComplete = $this->initialized = true;
 471  
 472          return $out;
 473      }
 474  
 475      /**
 476       * Return path to ckeditor.js.
 477       */
 478  	private function ckeditorPath()
 479      {
 480          if (!empty($this->basePath)) {
 481              return $this->basePath;
 482          }
 483  
 484          /**
 485           * The absolute pathname of the currently executing script.
 486           * Note: If a script is executed with the CLI, as a relative path, such as file.php or ../file.php,
 487           * $_SERVER['SCRIPT_FILENAME'] will contain the relative path specified by the user.
 488           */
 489          if (isset($_SERVER['SCRIPT_FILENAME'])) {
 490              $realPath = dirname($_SERVER['SCRIPT_FILENAME']);
 491          }
 492          else {
 493              /**
 494               * realpath — Returns canonicalized absolute pathname
 495               */
 496              $realPath = realpath( './' ) ;
 497          }
 498  
 499          /**
 500           * The filename of the currently executing script, relative to the document root.
 501           * For instance, $_SERVER['PHP_SELF'] in a script at the address http://example.com/test.php/foo.bar
 502           * would be /test.php/foo.bar.
 503           */
 504          $selfPath = dirname($_SERVER['PHP_SELF']);
 505          $file = str_replace("\\", "/", __FILE__);
 506  
 507          if (!$selfPath || !$realPath || !$file) {
 508              return "/ckeditor/";
 509          }
 510  
 511          $documentRoot = substr($realPath, 0, strlen($realPath) - strlen($selfPath));
 512          $fileUrl = substr($file, strlen($documentRoot));
 513          $ckeditorUrl = str_replace("ckeditor_php5.php", "", $fileUrl);
 514  
 515          return $ckeditorUrl;
 516      }
 517  
 518      /**
 519       * This little function provides a basic JSON support.
 520       * http://php.net/manual/en/function.json-encode.php
 521       *
 522       * @param mixed $val
 523       * @return string
 524       */
 525  	private function jsEncode($val)
 526      {
 527          if (is_null($val)) {
 528              return 'null';
 529          }
 530          if ($val === false) {
 531              return 'false';
 532          }
 533          if ($val === true) {
 534              return 'true';
 535          }
 536          if (is_scalar($val))
 537          {
 538              if (is_float($val))
 539              {
 540                  // Always use "." for floats.
 541                  $val = str_replace(",", ".", strval($val));
 542              }
 543  
 544              // Use @@ to not use quotes when outputting string value
 545              if (strpos($val, '@@') === 0) {
 546                  return substr($val, 2);
 547              }
 548              else {
 549                  // All scalars are converted to strings to avoid indeterminism.
 550                  // PHP's "1" and 1 are equal for all PHP operators, but
 551                  // JS's "1" and 1 are not. So if we pass "1" or 1 from the PHP backend,
 552                  // we should get the same result in the JS frontend (string).
 553                  // Character replacements for JSON.
 554                  static $jsonReplaces = array(array("\\", "/", "\n", "\t", "\r", "\b", "\f", '"'),
 555                  array('\\\\', '\\/', '\\n', '\\t', '\\r', '\\b', '\\f', '\"'));
 556  
 557                  $val = str_replace($jsonReplaces[0], $jsonReplaces[1], $val);
 558  
 559                  return '"' . $val . '"';
 560              }
 561          }
 562          $isList = true;
 563          for ($i = 0, reset($val); $i < count($val); $i++, next($val))
 564          {
 565              if (key($val) !== $i)
 566              {
 567                  $isList = false;
 568                  break;
 569              }
 570          }
 571          $result = array();
 572          if ($isList)
 573          {
 574              foreach ($val as $v) $result[] = $this->jsEncode($v);
 575              return '[ ' . join(', ', $result) . ' ]';
 576          }
 577          else
 578          {
 579              foreach ($val as $k => $v) $result[] = $this->jsEncode($k).': '.$this->jsEncode($v);
 580              return '{ ' . join(', ', $result) . ' }';
 581          }
 582      }
 583  }


Generated: Tue Nov 16 22:51:00 2010 Cross-referenced by PHPXref 0.7