Want more features on Pastebin? Sign Up, it's FREE!
Guest

Ckeditor

By: a guest on Aug 5th, 2012  |  syntax: PHP  |  size: 14.97 KB  |  views: 3,694  |  expires: Never
download  |  raw  |  embed  |  report abuse  |  print
Text below is selected. Please press Ctrl+C to copy to your clipboard. (⌘+C on Mac)
  1. <?php
  2. /*
  3. * Copyright (c) 2003-2011, 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.6.1';
  24.         /**
  25.          * A constant string unique for each release of %CKEditor.
  26.          */
  27.         const timestamp = 'B5GJ5GG';
  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 = "B5GJ5GG";
  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.          *
  521.          * @param mixed $val
  522.          * @return string
  523.          */
  524.         private function jsEncode($val)
  525.         {
  526.                 if (is_null($val)) {
  527.                         return 'null';
  528.                 }
  529.                 if (is_bool($val)) {
  530.                         return $val ? 'true' : 'false';
  531.                 }
  532.                 if (is_int($val)) {
  533.                         return $val;
  534.                 }
  535.                 if (is_float($val)) {
  536.                         return str_replace(',', '.', $val);
  537.                 }
  538.                 if (is_array($val) || is_object($val)) {
  539.                         if (is_array($val) && (array_keys($val) === range(0,count($val)-1))) {
  540.                                 return '[' . implode(',', array_map(array($this, 'jsEncode'), $val)) . ']';
  541.                         }
  542.                         $temp = array();
  543.                         foreach ($val as $k => $v){
  544.                                 $temp[] = $this->jsEncode("{$k}") . ':' . $this->jsEncode($v);
  545.                         }
  546.                         return '{' . implode(',', $temp) . '}';
  547.                 }
  548.                 // String otherwise
  549.                 if (strpos($val, '@@') === 0)
  550.                         return substr($val, 2);
  551.                 if (strtoupper(substr($val, 0, 9)) == 'CKEDITOR.')
  552.                         return $val;
  553.  
  554.                 return '"' . str_replace(array("\\", "/", "\n", "\t", "\r", "\x08", "\x0c", '"'), array('\\\\', '\\/', '\\n', '\\t', '\\r', '\\b', '\\f', '\"'), $val) . '"';
  555.         }
  556. }
clone this paste RAW Paste Data