Xataface CKeditor Module 0.3
CKeditor Widget for Xataface
lib/ckeditor/ckeditor_php5.php
Go to the documentation of this file.
00001 <?php
00002 /*
00003 * Copyright (c) 2003-2010, CKSource - Frederico Knabben. All rights reserved.
00004 * For licensing, see LICENSE.html or http://ckeditor.com/license
00005 */
00006 
00018 class CKEditor
00019 {
00023         const version = '3.4.1';
00027         const timestamp = 'A8LE4JO';
00028 
00038         public $basePath;
00050         public $config = array();
00056         public $initialized = false;
00069         public $returnOutput = false;
00076         public $textareaAttributes = array( "rows" => 8, "cols" => 60 );
00081         public $timestamp = "A8LE4JO";
00085         private $events = array();
00089         private $globalEvents = array();
00090 
00096         function __construct($basePath = null) {
00097                 if (!empty($basePath)) {
00098                         $this->basePath = $basePath;
00099                 }
00100         }
00101 
00131         public function editor($name, $value = "", $config = array(), $events = array())
00132         {
00133                 $attr = "";
00134                 foreach ($this->textareaAttributes as $key => $val) {
00135                         $attr.= " " . $key . '="' . str_replace('"', '&quot;', $val) . '"';
00136                 }
00137                 $out = "<textarea name=\"" . $name . "\"" . $attr . ">" . htmlspecialchars($value) . "</textarea>\n";
00138                 if (!$this->initialized) {
00139                         $out .= $this->init();
00140                 }
00141 
00142                 $_config = $this->configSettings($config, $events);
00143 
00144                 $js = $this->returnGlobalEvents();
00145                 if (!empty($_config))
00146                         $js .= "CKEDITOR.replace('".$name."', ".$this->jsEncode($_config).");";
00147                 else
00148                         $js .= "CKEDITOR.replace('".$name."');";
00149 
00150                 $out .= $this->script($js);
00151 
00152                 if (!$this->returnOutput) {
00153                         print $out;
00154                         $out = "";
00155                 }
00156 
00157                 return $out;
00158         }
00159 
00173         public function replace($id, $config = array(), $events = array())
00174         {
00175                 $out = "";
00176                 if (!$this->initialized) {
00177                         $out .= $this->init();
00178                 }
00179 
00180                 $_config = $this->configSettings($config, $events);
00181 
00182                 $js = $this->returnGlobalEvents();
00183                 if (!empty($_config)) {
00184                         $js .= "CKEDITOR.replace('".$id."', ".$this->jsEncode($_config).");";
00185                 }
00186                 else {
00187                         $js .= "CKEDITOR.replace('".$id."');";
00188                 }
00189                 $out .= $this->script($js);
00190 
00191                 if (!$this->returnOutput) {
00192                         print $out;
00193                         $out = "";
00194                 }
00195 
00196                 return $out;
00197         }
00198 
00216         public function replaceAll($className = null)
00217         {
00218                 $out = "";
00219                 if (!$this->initialized) {
00220                         $out .= $this->init();
00221                 }
00222 
00223                 $_config = $this->configSettings();
00224 
00225                 $js = $this->returnGlobalEvents();
00226                 if (empty($_config)) {
00227                         if (empty($className)) {
00228                                 $js .= "CKEDITOR.replaceAll();";
00229                         }
00230                         else {
00231                                 $js .= "CKEDITOR.replaceAll('".$className."');";
00232                         }
00233                 }
00234                 else {
00235                         $classDetection = "";
00236                         $js .= "CKEDITOR.replaceAll( function(textarea, config) {\n";
00237                         if (!empty($className)) {
00238                                 $js .= "        var classRegex = new RegExp('(?:^| )' + '". $className ."' + '(?:$| )');\n";
00239                                 $js .= "        if (!classRegex.test(textarea.className))\n";
00240                                 $js .= "                return false;\n";
00241                         }
00242                         $js .= "        CKEDITOR.tools.extend(config, ". $this->jsEncode($_config) .", true);";
00243                         $js .= "} );";
00244 
00245                 }
00246 
00247                 $out .= $this->script($js);
00248 
00249                 if (!$this->returnOutput) {
00250                         print $out;
00251                         $out = "";
00252                 }
00253 
00254                 return $out;
00255         }
00256 
00271         public function addEventHandler($event, $javascriptCode)
00272         {
00273                 if (!isset($this->events[$event])) {
00274                         $this->events[$event] = array();
00275                 }
00276                 // Avoid duplicates.
00277                 if (!in_array($javascriptCode, $this->events[$event])) {
00278                         $this->events[$event][] = $javascriptCode;
00279                 }
00280         }
00281 
00288         public function clearEventHandlers($event = null)
00289         {
00290                 if (!empty($event)) {
00291                         $this->events[$event] = array();
00292                 }
00293                 else {
00294                         $this->events = array();
00295                 }
00296         }
00297 
00311         public function addGlobalEventHandler($event, $javascriptCode)
00312         {
00313                 if (!isset($this->globalEvents[$event])) {
00314                         $this->globalEvents[$event] = array();
00315                 }
00316                 // Avoid duplicates.
00317                 if (!in_array($javascriptCode, $this->globalEvents[$event])) {
00318                         $this->globalEvents[$event][] = $javascriptCode;
00319                 }
00320         }
00321 
00328         public function clearGlobalEventHandlers($event = null)
00329         {
00330                 if (!empty($event)) {
00331                         $this->globalEvents[$event] = array();
00332                 }
00333                 else {
00334                         $this->globalEvents = array();
00335                 }
00336         }
00337 
00343         private function script($js)
00344         {
00345                 $out = "<script type=\"text/javascript\">";
00346                 $out .= "//<![CDATA[\n";
00347                 $out .= $js;
00348                 $out .= "\n//]]>";
00349                 $out .= "</script>\n";
00350 
00351                 return $out;
00352         }
00353 
00360         private function configSettings($config = array(), $events = array())
00361         {
00362                 $_config = $this->config;
00363                 $_events = $this->events;
00364 
00365                 if (is_array($config) && !empty($config)) {
00366                         $_config = array_merge($_config, $config);
00367                 }
00368 
00369                 if (is_array($events) && !empty($events)) {
00370                         foreach ($events as $eventName => $code) {
00371                                 if (!isset($_events[$eventName])) {
00372                                         $_events[$eventName] = array();
00373                                 }
00374                                 if (!in_array($code, $_events[$eventName])) {
00375                                         $_events[$eventName][] = $code;
00376                                 }
00377                         }
00378                 }
00379 
00380                 if (!empty($_events)) {
00381                         foreach($_events as $eventName => $handlers) {
00382                                 if (empty($handlers)) {
00383                                         continue;
00384                                 }
00385                                 else if (count($handlers) == 1) {
00386                                         $_config['on'][$eventName] = '@@'.$handlers[0];
00387                                 }
00388                                 else {
00389                                         $_config['on'][$eventName] = '@@function (ev){';
00390                                         foreach ($handlers as $handler => $code) {
00391                                                 $_config['on'][$eventName] .= '('.$code.')(ev);';
00392                                         }
00393                                         $_config['on'][$eventName] .= '}';
00394                                 }
00395                         }
00396                 }
00397 
00398                 return $_config;
00399         }
00400 
00404         private function returnGlobalEvents()
00405         {
00406                 static $returnedEvents;
00407                 $out = "";
00408 
00409                 if (!isset($returnedEvents)) {
00410                         $returnedEvents = array();
00411                 }
00412 
00413                 if (!empty($this->globalEvents)) {
00414                         foreach ($this->globalEvents as $eventName => $handlers) {
00415                                 foreach ($handlers as $handler => $code) {
00416                                         if (!isset($returnedEvents[$eventName])) {
00417                                                 $returnedEvents[$eventName] = array();
00418                                         }
00419                                         // Return only new events
00420                                         if (!in_array($code, $returnedEvents[$eventName])) {
00421                                                 $out .= ($code ? "\n" : "") . "CKEDITOR.on('". $eventName ."', $code);";
00422                                                 $returnedEvents[$eventName][] = $code;
00423                                         }
00424                                 }
00425                         }
00426                 }
00427 
00428                 return $out;
00429         }
00430 
00434         private function init()
00435         {
00436                 static $initComplete;
00437                 $out = "";
00438 
00439                 if (!empty($initComplete)) {
00440                         return "";
00441                 }
00442 
00443                 if ($this->initialized) {
00444                         $initComplete = true;
00445                         return "";
00446                 }
00447 
00448                 $args = "";
00449                 $ckeditorPath = $this->ckeditorPath();
00450 
00451                 if (!empty($this->timestamp) && $this->timestamp != "%"."TIMESTAMP%") {
00452                         $args = '?t=' . $this->timestamp;
00453                 }
00454 
00455                 // Skip relative paths...
00456                 if (strpos($ckeditorPath, '..') !== 0) {
00457                         $out .= $this->script("window.CKEDITOR_BASEPATH='". $ckeditorPath ."';");
00458                 }
00459 
00460                 $out .= "<script type=\"text/javascript\" src=\"" . $ckeditorPath . 'ckeditor.js' . $args . "\"></script>\n";
00461 
00462                 $extraCode = "";
00463                 if ($this->timestamp != self::timestamp) {
00464                         $extraCode .= ($extraCode ? "\n" : "") . "CKEDITOR.timestamp = '". $this->timestamp ."';";
00465                 }
00466                 if ($extraCode) {
00467                         $out .= $this->script($extraCode);
00468                 }
00469 
00470                 $initComplete = $this->initialized = true;
00471 
00472                 return $out;
00473         }
00474 
00478         private function ckeditorPath()
00479         {
00480                 if (!empty($this->basePath)) {
00481                         return $this->basePath;
00482                 }
00483 
00489                 if (isset($_SERVER['SCRIPT_FILENAME'])) {
00490                         $realPath = dirname($_SERVER['SCRIPT_FILENAME']);
00491                 }
00492                 else {
00496                         $realPath = realpath( './' ) ;
00497                 }
00498 
00504                 $selfPath = dirname($_SERVER['PHP_SELF']);
00505                 $file = str_replace("\\", "/", __FILE__);
00506 
00507                 if (!$selfPath || !$realPath || !$file) {
00508                         return "/ckeditor/";
00509                 }
00510 
00511                 $documentRoot = substr($realPath, 0, strlen($realPath) - strlen($selfPath));
00512                 $fileUrl = substr($file, strlen($documentRoot));
00513                 $ckeditorUrl = str_replace("ckeditor_php5.php", "", $fileUrl);
00514 
00515                 return $ckeditorUrl;
00516         }
00517 
00525         private function jsEncode($val)
00526         {
00527                 if (is_null($val)) {
00528                         return 'null';
00529                 }
00530                 if ($val === false) {
00531                         return 'false';
00532                 }
00533                 if ($val === true) {
00534                         return 'true';
00535                 }
00536                 if (is_scalar($val))
00537                 {
00538                         if (is_float($val))
00539                         {
00540                                 // Always use "." for floats.
00541                                 $val = str_replace(",", ".", strval($val));
00542                         }
00543 
00544                         // Use @@ to not use quotes when outputting string value
00545                         if (strpos($val, '@@') === 0) {
00546                                 return substr($val, 2);
00547                         }
00548                         else {
00549                                 // All scalars are converted to strings to avoid indeterminism.
00550                                 // PHP's "1" and 1 are equal for all PHP operators, but
00551                                 // JS's "1" and 1 are not. So if we pass "1" or 1 from the PHP backend,
00552                                 // we should get the same result in the JS frontend (string).
00553                                 // Character replacements for JSON.
00554                                 static $jsonReplaces = array(array("\\", "/", "\n", "\t", "\r", "\b", "\f", '"'),
00555                                 array('\\\\', '\\/', '\\n', '\\t', '\\r', '\\b', '\\f', '\"'));
00556 
00557                                 $val = str_replace($jsonReplaces[0], $jsonReplaces[1], $val);
00558 
00559                                 return '"' . $val . '"';
00560                         }
00561                 }
00562                 $isList = true;
00563                 for ($i = 0, reset($val); $i < count($val); $i++, next($val))
00564                 {
00565                         if (key($val) !== $i)
00566                         {
00567                                 $isList = false;
00568                                 break;
00569                         }
00570                 }
00571                 $result = array();
00572                 if ($isList)
00573                 {
00574                         foreach ($val as $v) $result[] = $this->jsEncode($v);
00575                         return '[ ' . join(', ', $result) . ' ]';
00576                 }
00577                 else
00578                 {
00579                         foreach ($val as $k => $v) $result[] = $this->jsEncode($k).': '.$this->jsEncode($v);
00580                         return '{ ' . join(', ', $result) . ' }';
00581                 }
00582         }
00583 }
 All Data Structures Files Functions Variables