1<?php
2if(!defined('DOKU_INC')) define('DOKU_INC',realpath(dirname(__FILE__).'/../../../').'/');
3if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/');
4require_once(DOKU_PLUGIN.'action.php');
5use dokuwiki\Extension\Event;
6
7/**
8 * @license    GNU GPLv2 version 2 or later (http://www.gnu.org/licenses/gpl.html)
9 *
10 * class       plugin_ckgedit_edit
11 * @author     Myron Turner <turnermm02@shaw.ca>
12 */
13
14class action_plugin_ckgedit_edit extends DokuWiki_Action_Plugin {
15
16    var $fck_location = "ckeditor";
17    var $helper = false;
18    var $ckgedit_bak_file = "";
19    var $debug = false;
20    var $test = false;
21    var $page_from_template;
22    var $draft_found = false;
23    var $draft_text;
24    var $draft_started;
25    var $captcha;
26    /**
27     * Constructor
28     */
29    function __construct()
30    {
31        $this->setupLocale();
32        $this->helper = plugin_load('helper', 'ckgedit');
33        if(!plugin_isdisabled('captcha')) {
34            $this->captcha = plugin_load('helper', 'captcha');
35        }
36        else  $this->captcha  = false;
37
38    }
39
40
41    function register(Doku_Event_Handler $controller)
42    {
43       $version = explode('.', phpversion());
44       define('PHP_VERSION_NUM', $version[0] * 10+ $version[1]);
45
46         if($this->helper->is_outOfScope()) return;
47
48        global $FCKG_show_preview;
49        $FCKG_show_preview = true;
50
51        if(isset($_REQUEST['mode']) && $_REQUEST['mode'] == 'dwiki') {
52          $FCKG_show_preview = true;
53          return;
54        }
55        elseif(isset($_COOKIE['FCKG_USE'])) {
56             preg_match('/_\w+_/',  $_COOKIE['FCKG_USE'], $matches);
57             if($matches[0] == '_false_') {
58                  $FCKG_show_preview = true;
59                   return;
60             }
61        }
62        $Fck_NmSp = "!!NONSET!!";
63        if(isset($_COOKIE['FCK_NmSp'])) {
64          $Fck_NmSp = $_COOKIE['FCK_NmSp'];
65        }
66        $dwedit_ns = @$this->getConf('dwedit_ns');
67        if(isset($dwedit_ns) && $dwedit_ns) {
68            $ns_choices = explode(',',$dwedit_ns);
69            foreach($ns_choices as $ns) {
70              $ns = trim($ns);
71              if(preg_match("/$ns/",$_REQUEST['id']) || preg_match("/$ns/",$Fck_NmSp)) {
72                      $FCKG_show_preview = true;
73                       return;
74             }
75            }
76        }
77        $controller->register_hook('COMMON_PAGE_FROMTEMPLATE', 'AFTER', $this, 'pagefromtemplate', array());
78        $controller->register_hook('COMMON_PAGETPL_LOAD', 'AFTER', $this, 'pagefromtemplate', array());
79
80        $controller->register_hook('TPL_ACT_RENDER', 'BEFORE', $this, 'ckgedit_edit');
81        $controller->register_hook('TPL_METAHEADER_OUTPUT', 'BEFORE', $this, 'ckgedit_edit_meta');
82    }
83
84   /**
85    * function pagefromtemplate
86    * Capture template text output by Template Event handler instead of pageTemplate()
87	* @author  Myron Turner <turnermm02@shaw.ca>
88    *
89    */
90    function pagefromtemplate(Doku_Event $event) {
91      if($event->data['tpl']) {
92         $this->page_from_template = $event->data['tpl'];
93      }
94    }
95
96    /**
97     * ckgedit_edit_meta
98     *
99     * load fck js
100     * @author Pierre Spring <pierre.spring@liip.ch>
101    * @author Myron Turner <turnermm03@shaw.ca>
102     * @param mixed $event
103     * @access public
104     * @return void
105     */
106    function ckgedit_edit_meta(Doku_Event $event)
107    {
108        global $ACT;
109        // we only change the edit behaviour
110        if ($ACT != 'edit'){
111            return;
112        }
113        global $ID;
114        global $REV;
115        global $INFO;
116        global $conf;
117            $event->data['script'][] =
118                array(
119                    'type'=>'text/javascript',
120                    'charset'=>'utf-8',
121                    '_data'=>'',
122                     'src'=>DOKU_BASE.'lib/plugins/ckgedit/' .$this->fck_location. '/ckeditor.js'
123                )+([ 'defer' => 'defer']);
124
125      if(isset($conf['fnencode']) && $conf['fnencode'] == 'safe') {
126            $event->data['script'][] =
127                array(
128                    'type'=>'text/javascript',
129                    'charset'=>'utf-8',
130                    '_data'=>'',
131                     'src'=>'lib/plugins/ckgedit/scripts/safeFN_cmpr.js'
132                ) + ([ 'defer' => 'defer']);
133      }
134      $ua = strtolower ($_SERVER['HTTP_USER_AGENT']);
135      if(strpos($ua, 'msie') !== false) {
136          echo "\n" . '<meta http-equiv="X-UA-Compatible" content="IE=EmulateIE8" />' ."\n";
137      }
138
139        if($this->test) {
140         $nval = substr(md5(time()), -20);
141         $parse_url = DOKU_URL . 'lib/plugins/ckgedit/scripts/parse_wiki.js.unc';
142        }
143        else $parse_url = DOKU_BASE . 'lib/plugins/ckgedit/scripts/parse_wiki-cmpr.js';
144        $event->data['script'][] =
145            array(
146                'type'=>'text/javascript',
147                'charset'=>'utf-8',
148                '_data'=>'',
149                 'src'=> $parse_url
150            ) + ([ 'defer' => 'defer']);
151
152        return;
153    }
154
155    /**
156     * function    ckgedit_edit
157     * @author     Pierre Spring <pierre.spring@liip.ch>
158     * edit screen using fck
159     *
160     * @param & $event
161     * @access public
162     * @return void
163     */
164    function ckgedit_edit(Doku_Event $event)
165    {
166
167        global $INFO;
168
169        // we only change the edit behaviour
170        if ($event->data != 'edit') {
171            return;
172        }
173        // load xml and acl
174        if (!$this->_preprocess()){
175            return;
176        }
177        // print out the edit screen
178        $this->_print();
179        // prevent Dokuwiki normal processing of $ACT (it would clean the variable and destroy our 'index' value.
180        $event->preventDefault();
181        // index command belongs to us, there is no need to hold up Dokuwiki letting other plugins see if its for them
182        $event->stopPropagation();
183    }
184
185   /**
186    * function _preprocess
187	* @author  Myron Turner <turnermm02@shaw.ca>
188    */
189    function _preprocess($draft_text = "")
190    {
191        global $ID;
192        global $REV;
193        global $DATE;
194        global $RANGE;
195        global $PRE;
196        global $SUF;
197        global $INFO;
198        global $SUM;
199        global $lang;
200        global $conf;
201        global $ckgedit_lang;
202        //set summary default
203        if(!$SUM){
204            if($REV){
205                $SUM = $lang['restored'];
206            }elseif(!$INFO['exists']){
207                $SUM = $lang['created'];
208            }
209        }
210            if(!$draft_text) {
211            if($INFO['exists']){
212                if($RANGE){
213                    list($PRE,$text,$SUF) = rawWikiSlices($RANGE,$ID,$REV);
214                }else{
215                    $text = rawWiki($ID,$REV);
216                }
217            }else{
218                //try to load a pagetemplate
219                 $text = pageTemplate($ID);
220                //Check for text from template event handler
221                 if(!$text && $this->page_from_template) $text = $this->page_from_template;
222            }
223            }
224            else $text = $draft_text;
225
226     $text = str_replace('&notags',  '&amp;amp;notags',$text);
227     $text = preg_replace_callback(
228    '/(~~NOCACHE~~|~~NOTOC~~|\{\{rss>http(s?):\/\/.*?\}\})/ms',
229     create_function(
230               '$matches',
231               '$matches[0] = preg_replace("#{{rss>http(s?):\/\/#", "{ { rss>$1Feed:",  $matches[0]);
232               $matches[0] = str_replace("~", "~ ",  $matches[0]);
233               return $matches[0];'
234               ),$text);
235
236    if($this->getConf('smiley_hack')) {
237        $new_addr = $_SERVER['SERVER_NAME'] . DOKU_BASE;
238        $text=preg_replace("#(?<=http://)(.*?)(?=lib/plugins/ckgedit/ckeditor/plugins/smiley/images)#s", $new_addr,$text);
239     }
240 /*interwiki frasl refactoring*/
241
242/*
243    $text = preg_replace_callback('/\[\[\w+>.*?\]\]/ms',
244    create_function(
245        '$matches',
246        'return str_replace("/", "__IWIKI_FSLASH__" ,$matches[0]);'
247    ), $text);
248    */
249
250      global $useComplexTables;
251      if($this->getConf('complex_tables') || strrpos($text, '~~COMPLEX_TABLES~~') !== false) {
252          $useComplexTables=true;
253      }
254      else {
255         $useComplexTables=false;
256      }
257
258      if(strpos($text, '%%') !== false || strpos($text, '\\\\') !== false || strpos($text, '|') !== false ) {
259      $text = preg_replace('/%%\s*<nowiki>\s*%%/ms', 'PERCNWPERC',$text);
260      $text = preg_replace('/%%\s*<(code|file)>\s*%%/ms', 'PERC' . "$1" . 'PERC',$text);
261        $text = preg_replace_callback(
262            "/<(nowiki|code|file)>(.*?)<\/(nowiki|code|file)/ms",
263            function ($matches) {
264                $matches[0] = str_replace('%%', 'DBLPERCENT',$matches[0]);
265                $matches[0] =  str_replace('\\ ', 'DBLBACKSPLASH',$matches[0]);
266                 $matches[0] =  str_replace('|', 'NWPIPECHARACTER',$matches[0]);
267                return $matches[0];
268            },
269           $text
270        );
271
272        $text = preg_replace_callback(
273            "/(?<!nowiki>)%%(.*?)%%/ms",
274            function($matches) {
275            return '<nowiki>' . $matches[1] . '</nowiki>';
276            },
277            $text
278        );
279
280        $text =  str_replace('DBLPERCENT','%%',$text);
281      }
282
283       $pos = strpos($text, '<');
284
285       if($pos !== false) {
286
287/* skipentity support */
288        $text = preg_replace_callback(
289            '/``(.*?)``/ms',
290            function($matches) {
291                $needles =  array('[',']', '/',  '.', '*', '_','\'','<','>','%', '{', '}', '\\' , '(' );
292                $replacements = array('&#91;','&#93;','&#47;', '&#46;', '&#42;', '&#95;', '&#39;', '&#60;','&#62;','&#37;', '&#123;','&#125;', '&#92;','&#40;');
293                $matches[1] = str_replace($needles, $replacements, $matches[1]);
294               return '&grave;&grave;' .$matches[1] .'&grave;&grave;' ;
295            },
296            $text
297        );
298
299
300           $text = preg_replace_callback(
301            '/(<nowiki>)(.*?)(<\/nowiki>)/ms',
302            create_function(
303                '$matches',
304                 '$needles =  array("[","]", "/",  ".", "*", "_","\'","<",">","%", "{", "}", "\\\","(");
305                  $replacements = array("&#91;","&#93;","&#47;", "&#46;", "&#42;", "&#95;", "&#39;", "&#60;","&#62;","&#37;", "&#123;","&#125;", "&#92;","&#40;");
306                  $matches[2] = str_replace($needles, $replacements, $matches[2]);
307                  return  $matches[1] . $matches[2] . $matches[3];'
308            ),
309            $text
310          );
311
312           $text = preg_replace_callback(
313            '/<(code|file)(.*?)(>)(.*?)(<\/\1>)/ms',
314            create_function(
315                '$matches',
316                 ' //file_put_contents("geshi.txt", print_r($matches,true));
317                 if(preg_match("/(^\s*geshi:\s*(\w+)(\s+\w+\.\w+)*\s*)$/m",$matches[0],$gmatch)){
318                      $gmatch[0] = preg_replace("/\s*geshi:\s+/","",$gmatch[0]);
319                      $matches[1] .= " " . trim($gmatch[0]);
320                      //file_put_contents("gmatch.txt", print_r($gmatch,true));
321                      $c=1;
322                      $matches[4] = str_replace($gmatch[1],"",$matches[4],$c);
323                  }
324                 if(preg_match("/\w+/",$matches[2])) {
325                   $matches[4] = str_replace("CHEVRONescC", ">>",$matches[4]);
326                   $matches[4] = str_replace("CHEVRONescO", "<<",$matches[4]);
327                   $matches[4] = preg_replace("/<(?!\s)/ms", "__GESHI_OPEN__", $matches[4]);
328                  }
329                  else {
330                  if( preg_match("/MULTI/",$matches[0])) {
331                     $open = "< ";
332                     $close = " >";
333                  }
334                  else {
335                     $open = "&lt;";
336                     $close = "&gt;";
337                  }
338                  $matches[4] = preg_replace("/<(?!\s)/ms", $open, $matches[4]);
339                  $matches[4] = preg_replace("/(?<!\s)>/ms", $close, $matches[4]);
340                  }
341                  $matches[4] = str_replace("\"", "__GESHI_QUOT__", $matches[4]);
342                  $matches[4] = preg_replace("/\\\\\\(\n|\s)/ms","CODE_BLOCK_EOL_MASK$1",$matches[4]);
343                  return "<" . $matches[1] . $matches[2] . $matches[3] . $matches[4] . $matches[5];'
344            ),
345            $text
346          );
347
348          $text = preg_replace_callback(
349             '/~~START_HTML_BLOCK~~.*?CLOSE_HTML_BLOCK/ms',
350                 create_function(
351                '$matches',
352                '$matches[0] = str_replace("_ckgedit_NPBBR_","",$matches[0]);
353                 return $matches[0];'
354        ),$text);
355
356          $text = preg_replace_callback(
357            '/(\|\s*)(<code>|<file>)(.*?)(<\/code>|<\/file>)\n_ckgedit_NPBBR_(?=.*?\|)/ms',
358            create_function(
359                '$matches',
360                 '$matches[2] = preg_replace("/<code>/ms", "TPRE_CODE", $matches[2]);
361                  $matches[2] = preg_replace("/<file>/ms", "TPRE_FILE", $matches[2]);
362                  $matches[4] = "TPRE_CLOSE";
363                  $matches[3] = preg_replace("/^\n+/", "TC_NL",$matches[3]);
364                  $matches[3] = preg_replace("/\n/ms", "TC_NL",$matches[3]);
365                  return $matches[1] . $matches[2] .  trim($matches[3]) .   $matches[4];'
366            ),
367            $text
368          );
369         $text = preg_replace('/TPRE_CLOSE\s+/ms',"TPRE_CLOSE",$text);
370         $text = preg_replace('/<(?!code|file|nowiki|del|sup|sub|\/\/|\s|\/del|\/code|\/nowiki|\/file|\/sup|\/sub)/ms',"&lt;",$text);
371         $text = str_replace(array('<nowiki>','</nowiki>'),array('NWIKISTART<nowiki>','NWIKICLOSE</nowiki>'),$text);
372         $text = str_replace('%%&lt;', '&#37;&#37;&#60;', $text);
373       }
374
375	   if($this->getConf('duplicate_notes')) {
376			$text = preg_replace_callback('/\(\((.*?)\)\)/ms',
377				  create_function(
378				   '$matches',
379				   'static $count = 0;
380				   $count++;
381				   $ins = "FNoteINSert" . $count;
382                   $needles =  array("[","]", "/",  ".", "*", "_","\'","<",">","%", "{", "}", "\\\","(");
383                   $replacements = array("&#91;","&#93;","&#47;", "&#46;", "&#42;", "&#95;", "&#39;", "&#60;","&#62;","&#37;", "&#123;","&#125;", "&#92;","&#40;");
384                   $matches[1] = str_replace($needles, $replacements, $matches[1]);
385              	   return "(($ins" . $matches[1] . "))" ;'
386				 ), $text
387			);
388		}
389       $text = preg_replace('/^\>/ms',"_QUOT_",$text);  // dw quotes
390       $text = str_replace('>>','CHEVRONescC',$text);
391       $text = str_replace('<<','CHEVRONescO',$text);
392       $text = preg_replace('/(={3,}.*?)(\{\{.*?\}\})(.*?={3,})/',"$1$3\n$2",$text);
393       $email_regex = '/\/\/\<\/\/(.*?@.*?)>/';
394       $text = preg_replace($email_regex,"<$1>",$text);
395
396       $text = preg_replace('/{{(.*)\.swf(\s*)}}/ms',"__SWF__$1.swf$2__FWS__",$text);
397       $text = preg_replace('/PERCNWPERC/ms', '%%&lt; nowiki &gt;%%',$text);
398       //$text = preg_replace('/%%\s*<(code|file)>\s*%%/ms', 'PERC' . "$1" . 'PERC',$text);
399       $text = preg_replace('/PERCcodePERC/ms','%%&lt;code&gt;%%', $text);
400       $text = preg_replace('/PERCfilePERC/ms','%%&lt;file&gt;%%', $text);
401       $divalign = false;
402       if($this->helper->has_plugin('divalign2')
403		   ||$this->helper->has_plugin('divalign2_center')) {
404           $divalign = true;
405           $text = preg_replace_callback('/\n([;#]{3})/',
406
407                              function ($matches) {
408                               return "divalNLine" . str_replace('#','CGEHASH',$matches[1]);
409                              },   $text
410            );
411       }
412      $text = preg_replace_callback(
413               '|(<code\s+\w+)(\s+\[enable_line_numbers.*?\])\s*>(.*?<\/code>)|ms',
414            function($matches) {
415                $retstr = $matches[1] . ">\n/*" .   $matches[2] . "*/\n" . $matches[3];
416               return $retstr;
417            }, $text
418        );
419
420       $this->xhtml = $this->_render_xhtml($text);
421
422 /*interwiki frasl refactoring*/
423  //   $this->xhtml = str_replace("__IWIKI_FSLASH__", "&frasl;", $this->xhtml);
424	   if($this->getConf('duplicate_notes')) {
425			$this->xhtml = preg_replace("/FNoteINSert\d+/ms", "",$this->xhtml);
426	   }
427      if($divalign) {
428            $this->xhtml = str_replace("CGEHASH", "#", $this->xhtml);
429      }
430       $this->xhtml = str_replace("__GESHI_QUOT__", '&#34;', $this->xhtml);
431       $this->xhtml = str_replace("__GESHI_OPEN__", "&#60; ", $this->xhtml);
432       $this->xhtml = str_replace('CHEVRONescC', '>>',$this->xhtml);
433       $this->xhtml = str_replace('CHEVRONescO', '<<',$this->xhtml);
434       $this->xhtml = preg_replace('/_QUOT_/ms','>',$this->xhtml);  // dw quotes
435       $this->xhtml = preg_replace_callback(
436         "/^(>+)(.*?)$/ms",
437         function($matches) {
438             $matches[2] = str_ireplace('<br/>',"",$matches[2]);
439                return $matches[1] . $matches[2] . "<br />";
440         },
441        $this->xhtml
442       );
443
444       if($pos !== false) {
445       $this->xhtml = preg_replace_callback(
446                '/(TPRE_CODE|TPRE_FILE)(.*?)(TPRE_CLOSE)/ms',
447                create_function(
448                   '$matches',
449                   '$matches[1] = preg_replace("/TPRE_CODE/","<pre class=\'code\'>\n", $matches[1]);
450                    $matches[1] = preg_replace("/TPRE_FILE/","<pre class=\'file\'>\n", $matches[1]);
451                    $matches[2] = preg_replace("/TC_NL/ms", "\n", $matches[2]);
452                    $matches[3] = "</pre>";
453                    return $matches[1] . $matches[2] . $matches[3];'
454                ),
455                $this->xhtml
456              );
457
458       }
459        $this->xhtml = preg_replace_callback(
460    '/~~START_HTML_BLOCK~~[\n\s]*(.*?)CLOSE_HTML_BLOCK/ms',
461        create_function(
462            '$matches',
463            '$matches[1] = str_replace("&amp;","&",$matches[1]);
464         $matches[1] =  html_entity_decode($matches[1],ENT_QUOTES, "UTF-8");
465             $matches[1] = preg_replace("/<\/?code.*?>/", "",$matches[1]);
466         $matches[1] = preg_replace("/^\s*<\/p>/","",$matches[1]);
467         $tmp = explode("\n", $matches[1]);
468         for($n=0; $n<7; $n++) {
469               if( (preg_match("/(<p>\s*)*(&nbsp;|\s+)<\/p>/",$tmp[$n])) || (preg_match("/^\s+$/",$tmp[$n]))) {
470                unset($tmp[$n]);
471             }
472          }
473         return "~~START_HTML_BLOCK~~" . implode("\n",$tmp) . "CLOSE_HTML_BLOCK"; '
474        ),$this->xhtml);
475
476        $this->xhtml = preg_replace_callback(
477            '/(<pre)(.*?)(>)(.*?)(<\/pre>)/ms',
478            create_function(
479                '$matches',
480                  '$matches[4] = preg_replace("/(\||\^)[ ]+(\||\^)/ms","$1 &nbsp; $2" , $matches[4]);
481                  return  $matches[1] . $matches[2] . $matches[3] . $matches[4] . $matches[5];'
482            ),
483            $this->xhtml
484          );
485
486          $this->xhtml = preg_replace_callback(
487            '/~~MULTI_PLUGIN_OPEN~~(.*?)~~MULTI_PLUGIN_CLOSE~~/ms',
488            create_function(
489                '$matches',
490                'return str_replace("&lt;", "< ",$matches[0]);'
491            ),
492            $this->xhtml
493          );
494		  //insures breaks are retained for single spacing
495      $this->xhtml = preg_replace('/<p>\s*<br\/>\s*<\/p>/ms', '<br/>', $this->xhtml);
496
497      if($this->draft_started) return $this->xhtml;
498       $cname = getCacheName($INFO['client'].$ID,'.draft.fckl');
499
500       $this->draft_started = false;
501        if(file_exists($cname)  && !$this->draft_started) {
502
503           $this->draft_started = true;
504
505          $cdata =  unserialize(io_readFile($cname,false));
506          $prefix =  isset($cdata['prefix']) ? urldecode($cdata['prefix']) : "" ;
507          if($prefix) $prefix = $this-> _preprocess($prefix);
508          $text = urldecode($cdata['text']);
509          $suffix = isset($cdata['suffix']) ? urldecode($cdata['suffix']) : "" ;
510
511          if($suffix) $suffix = $this-> _preprocess($suffix);
512
513          preg_match_all("/<\/(.*?)\>/", $cdata['text'],$matches);
514          /* exclude drafts saved from preview mode */
515          if (!in_array('code', $matches[1]) && !in_array('file', $matches[1]) && !in_array('nowiki', $matches[1])) {
516             //$this->draft_text = $cdata['text'];
517             $this->draft_text = $prefix . $text . $suffix;
518              $this->draft_found = true;
519              msg($this->getLang('draft_msg')) ;
520          }
521          unlink($cname);
522       }
523       if($draft_started) return $this->xhtml;
524        return true;
525    }
526
527
528   /**
529      Check for for alternate style sheet
530    */
531    function alt_style_sheet() {
532       $stylesheet = DOKU_PLUGIN . 'ckgedit/ckeditor/css/_style.css';
533       if(file_exists($stylesheet)) {
534           global $conf;
535           $tpl_name = $conf['template'];
536           if($fh = fopen($stylesheet,"r")) {
537               $line_num = 0;
538               while (!feof($fh) &&  $line_num < 4) {
539                    $line = fgets($fh,1024);            //msg($line);
540                    if(strpos($line,$tpl_name)!==false) {
541                         return DOKU_BASE . '/lib/plugins/ckgedit/ckeditor/css/_style.css' ;
542                        break;
543                     }
544                    $line_num ++;
545               }
546           }
547       }
548      return "";
549    }
550
551
552   /**
553    * function _print
554    * @author  Myron Turner
555    */
556    function _print()
557    {
558        global $INFO;
559        global $lang;
560        global $ckgedit_lang;
561        global $ID;
562        global $REV;
563        global $DATE;
564        global $PRE;
565        global $SUF;
566        global $SUM;
567        $wr = $INFO['writable'];
568        if($wr){
569           if ($REV) print p_locale_xhtml('editrev');
570           $ro=false;
571        }else{
572            // check pseudo action 'source'
573            if(!actionOK('source')){
574                msg('Command disabled: source',-1);
575                return false;
576            }
577            print p_locale_xhtml('read');
578            $ro='readonly="readonly"';
579        }
580
581        if(!$DATE) $DATE = $INFO['lastmod'];
582        $guest_toolbar = $this->getConf('guest_toolbar');
583        $guest_media  = $this->getConf('guest_media');
584        if(!isset($INFO['userinfo']) && !$guest_toolbar) {
585            $toolbar = "DokuwikiNoGuest";
586        }
587       else if(!isset($INFO['userinfo']) && !$guest_media) {
588	        $toolbar = "DokuwikiGuest";
589	   }
590        else $toolbar = 'Dokuwiki';
591
592$height = isset($_COOKIE['ckgEdht']) && $_COOKIE['ckgEdht'] ? $_COOKIE['ckgEdht']: 250;
593if(!is_numeric($height)) $height = 250;
594$fbsz_increment = isset($_COOKIE['fbsz']) && $_COOKIE['fbsz'] ? $_COOKIE['fbsz'] : false;
595$fbrowser_width = 1070;
596$fbrowser_height = 660;
597if($fbsz_increment) {
598    $fbrowser_width  = $fbrowser_width + ($fbrowser_width*($fbsz_increment/100));
599    $fbrowser_height  =$fbrowser_height + ($fbrowser_height*($fbsz_increment/100));
600}
601
602$doku_base=  rtrim(DOKU_BASE,'/');
603$ns = getNS($_COOKIE['FCK_NmSp']);
604
605//get user file browser if allowed
606if ($this->getConf('allow_ckg_filebrowser') == 'all') {
607    $fb = $this->getUserFb();
608} else {
609    //use only allowed file browser
610    $fb = $this->getConf('allow_ckg_filebrowser');
611}
612
613//setup options
614if ($fb == 'dokuwiki') {
615    $fbOptions = "filebrowserImageBrowseUrl: \"$doku_base/lib/exe/mediamanager.php?ns=$ns&edid=wiki__text&onselect=ckg_edit_mediaman_insert&ckg_media=img\",
616    filebrowserBrowseUrl: \"$doku_base/lib/exe/mediamanager.php?ns=$ns&edid=wiki__text&onselect=ckg_edit_mediaman_insertlink&ckg_media=link\"";
617} else {
618    $fbOptions = "filebrowserImageBrowseUrl :  \"$doku_base/lib/plugins/ckgedit/fckeditor/editor/filemanager/browser/default/browser.html?Type=Image&Connector=$doku_base/lib/plugins/ckgedit/fckeditor/editor/filemanager/connectors/php/connector.php\",
619    filebrowserBrowseUrl: \"$doku_base/lib/plugins/ckgedit/fckeditor/editor/filemanager/browser/default/browser.html?Type=File&Connector=$doku_base/lib/plugins/ckgedit/fckeditor/editor/filemanager/connectors/php/connector.php\"";
620}
621if($this->getConf('style_sheet')) {
622$contents_css = $this->alt_style_sheet();
623}
624//msg($contents_css);
625$ckeditor_replace =<<<CKEDITOR_REPLACE
626
627		   ckgeditCKInstance = CKEDITOR.replace('wiki__text',
628		       {
629                  toolbar: '$toolbar' ,
630                  height: $height,
631                   filebrowserWindowWidth: $fbrowser_width,
632                   filebrowserWindowHeight:  $fbrowser_height,
633                  $fbOptions,
634                    on : {  'instanceReady' : function( evt ) {
635                         evt.editor.document.on( 'mousedown', function()
636                   {
637                              var browser_level = (window.top != window.self) ? window.self : window.top; browser_level.handlekeypress(evt);
638                             //  parent. handlekeypress(evt);
639                         } );
640                       }
641                     },
642                     on : {  'instanceReady' : function( evt ) {
643                         evt.editor.document.on( 'focus', function()
644                      {
645                               var browser_level = (window.top != window.self) ? window.self : window.top; browser_level.handlekeypress(evt);
646                              // parent. handlekeypress(evt);
647                         } );
648                      }
649                   },
650
651               }
652		   );
653           FCKeditor_OnComplete(ckgeditCKInstance);
654           if("$contents_css") {
655            CKEDITOR.config.contentsCss = "$contents_css";
656         }
657
658CKEDITOR_REPLACE;
659
660		 echo  $this->helper->registerOnLoad($ckeditor_replace);
661
662         global $skip_styling;
663
664?>
665<?php
666            global $INPUT;
667            if($this->page_from_template) {
668             $ckg_template = 'tpl';
669            }
670            else $ckg_template ="";
671
672             if($INPUT->has('hid')) {
673               $hid = $INPUT->str('hid');
674           }
675           else {
676               $hid = "";
677           }
678         /* accommodates include plugin's redirect to original page after editing included page */
679       $ckgedit_redirect =  $INPUT->str('redirect_id', "");
680
681 ?>
682   <form id="dw__editform" method="post" action="<?php echo script()?>"  accept-charset="<?php echo $lang['encoding']?>">
683    <div class="no">
684      <input type="hidden" name="id"   value="<?php echo $ID?>" />
685      <input type="hidden" name="rev"  value="<?php echo $REV?>" />
686      <input type="hidden" name="date" value="<?php echo $DATE?>" />
687      <input type="hidden" name="prefix" value="<?php echo formText($PRE)?>" />
688      <input type="hidden" name="suffix" value="<?php echo formText($SUF)?>" />
689      <input type="hidden" id="ckgedit_mode_type"  name="mode" value="" />
690      <input type="hidden" id="fck_preview_mode"  name="fck_preview_mode" value="nil" />
691      <input type="hidden" id="fck_wikitext"    name="fck_wikitext" value="__false__" />
692       <input type="hidden" id="styling"  name="styling" value="styles" />
693      <?php if(!empty($ckgedit_redirect)):?>
694     <input type="hidden" id="ckgedit_redirect"  name="ckgedit_redirect" value="<?php echo $ckgedit_redirect ?>" />
695      <?php endif ?>
696	  <?php if(!empty($hid)):?>
697       <input type="hidden" id="hid"  name="hid" value="<?php echo $hid; ?>" />
698	  <?php endif ?>
699      <input type="hidden" id="template"  name="template" value="<?php echo $ckg_template?>" />
700      <?php
701      if(function_exists('formSecurityToken')) {
702           formSecurityToken();
703      }
704      ?>
705    </div>
706<?php
707/*
708$this->xhtml=<<<ERRTXT
709[<a class="wikilink1 curid" data-curid="true" href="/dokuwiki/doku.php?id=*:*" title="*:*">go to top</a> | <a class="wikilink1" href="/dokuwiki/doku.php?id=*:start#system_configuration" title="*:start">back to Index</a> | <a class="wikilink1" href="/dokuwiki/doku.php?id=*:start" title="*:start">Wiki start page</a> ]
710ERRTXT;*/
711?>
712
713    <textarea name="wikitext" id="wiki__text" <?php echo $ro?> cols="80" rows="10" class="edit" tabindex="1"><?php echo "\n".$this->xhtml?></textarea>
714
715<?php
716
717$temp=array();
718
719if(class_exists('dokuwiki\Extension\Event')) {
720    Event::createAndTrigger('HTML_EDITFORM_INJECTION', $temp);
721}
722else {
723 trigger_event('HTML_EDITFORM_INJECTION', $temp);
724}
725$DW_EDIT_disabled = '';
726$guest_perm = auth_quickaclcheck($_REQUEST['id']);
727$guest_group = false;
728$guest_user = false;
729
730if(isset($INFO['userinfo'])&& isset($INFO['userinfo']['grps'])) {
731   $user_groups = $INFO['userinfo']['grps'];
732   if(is_array($user_groups) && $user_groups) {
733      foreach($user_groups as $group) {
734        if (strcasecmp('guest', $group) == 0) {
735          $guest_group = true;
736          break;
737        }
738     }
739   }
740  if($INFO['client'] == 'guest') $guest_user = true;
741}
742
743if(($guest_user || $guest_group) && $guest_perm <= 2) $DW_EDIT_disabled = 'disabled';
744global $USERINFO;
745$DW_EDIT_hide = $this->helper->dw_edit_displayed();
746$is_ckgeditChrome = false;
747 if(stripos($_SERVER['HTTP_USER_AGENT'],'Chrome') !== false) {
748      preg_match("/Chrome\/(\d+)/", $_SERVER['HTTP_USER_AGENT'],$cmatch);
749      if((int)$cmatch[1] <26)  $is_ckgeditChrome =true;
750}
751
752?>
753
754    <div id="wiki__editbar">
755      <div id="size__ctl" style="display: none"></div>
756      <?php if($wr){?>
757         <div class="editButtons">
758            <input type="checkbox" name="ckgedit" value="ckgedit" checked="checked" style="display: none"/>
759             <input class="button" type="button" id = "save_button"
760                   name="do[save]"
761                   value="<?php echo $lang['btn_save']?>"
762                   title="<?php echo $lang['btn_save']?> "
763                   <?php echo $DW_EDIT_disabled; ?>
764                  />
765
766            <input class="button" id="ebtn__delete" type="submit"
767                   <?php echo $DW_EDIT_disabled; ?>
768                   name="do[delete]" value="<?php echo $lang['btn_delete']?>"
769                   title="<?php echo $this->getLang('title_dw_delete') ?>"
770                   style = "font-size: 100%;"
771            />
772
773
774             <?php if(!$is_ckgeditChrome): ?>
775             <input class="button"  id = "ebtn__dwedit"
776                 <?php echo $DW_EDIT_disabled; ?>
777                 <?php echo $DW_EDIT_hide; ?>
778                 style = "font-size: 100%;"
779                 type="submit"
780                 name="do[save]"
781                 value="<?php echo $this->getLang('btn_dw_edit')?>"
782                 title="<?php echo $this->getLang('title_dw_edit')?>"
783                  />
784             <?php endif; ?>
785
786             <?php if($this->getConf('allow_ckg_filebrowser') == 'all'): ?>
787            <input class="button" id="ebtn__fbswitch"
788                   style="font-size: 100%;"
789                   type="submit"
790                   name="do[save]"
791                   value="<?php echo $this->get_switch_fb_value() ?>"
792                   title="<?php echo $this->get_switch_fb_title() ?>"
793                   />
794             <?php endif; ?>
795<?php
796global $INFO;
797
798  $disabled = 'Disabled';
799  $inline = $this->test ? 'inline' : 'none';
800  $chrome_dwedit_link =  '<a href="'.wl($INFO['id'],array('do'=>'show')).'" ' . 'onclick="draft_delete();setDWEditCookie(2);"class="action edit" rel="nofollow" title="DW Edit"><span>DW Edit</span></a>';
801  $backup_btn =$this->getLang('dw_btn_backup') ? $this->getLang('dw_btn_backup') : $this->getLang('dw_btn_refresh');
802  $backup_title = $this->getLang('title_dw_backup') ? $this->getLang('title_dw_backup') : $this->getLang('title_dw_refresh');
803  $using_scayt = ($this->getConf('scayt')) == 'on';
804
805?>
806            <input class="button" type="submit"
807                 name="do[draftdel]"
808                 id = "ebut_cancel"
809                 value="<?php echo $lang['btn_cancel']?>"
810                 style = "font-size: 100%;"
811                 title = "<?php echo $this->getLang('title_dw_cancel')?>"
812             />
813
814           <!-- aspell button removed, not supported -->
815
816            <input class="button" type="button" value = "Test"
817                   title="Test"
818                   style = 'display:<?php echo $inline ?>;'
819                   onmousedown="parse_wikitext('test');"
820                  />
821
822 <?php if($this->draft_found) { ?>
823             <input class="button"
824                 style = "background-color: yellow"
825                 id="ckgedit_draft_btn"
826                 type="button" value="<?php echo $this->getLang('btn_draft') ?>"
827                 title="<?php echo $this->getLang('title_draft') ?>"
828                  />
829 <?php } else { ?>
830
831
832             <input class="button" type="button"
833                   id = "backup_button"
834                   value="<?php echo $backup_btn ?>"
835                   title="<?php echo $backup_title ?>"
836
837                  />
838
839             <input class="button" type="button"
840                   id = "revert_to_prev_btn"
841                   value="<?php echo $this->getLang('dw_btn_revert')?>"
842                   title="<?php echo $this->getLang('title_dw_revert')?>"
843
844                  />
845     <?php if(!$skip_styling) : ?>
846              <input class="button" type="submit"
847                   name ="do[edit]"
848                   id = "no_styling_btn"
849                   style = "font-size: 100%;"
850                   value="<?php echo $this->getLang('dw_btn_styling')?>"
851                   title="<?php echo $this->getLang('title_styling')?>"
852                  />
853    <?php endif ?>
854             &nbsp;&nbsp;&nbsp;
855
856<?php
857if($is_ckgeditChrome) echo $chrome_dwedit_link;
858?>
859 <br />
860
861 <?php }  ?>
862
863 <?php if($this->debug) { ?>
864         <input class="button" type="button" value = "Debug"
865                   title="Debug"
866                   onclick="HTMLParser_debug();"
867                  />
868
869            <br />
870 <?php } ?>
871
872   <div id = "backup_msg" class="backup_msg" style=" display:none;">
873     <table><tr><td class = "backup_msg_td">
874      <div id="backup_msg_area" class="backup_msg_area"></div>
875     <td>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
876     <td align="right">
877      <a href="javascript:hide_backup_msg();void(0);" class="backup_msg_close">[ close ]</a>&nbsp;&nbsp;&nbsp;
878     </table>
879
880 </div>
881<?php
882
883if(!isset($_COOKIE['ckgEdPaste'])) {
884    $paste_value = 'on';
885}
886else {
887    $paste_value = (isset($_COOKIE['ckgEdPaste']) && $_COOKIE['ckgEdPaste'] == 'off' )  ? 'on' : 'off';
888}
889?>
890
891     <label class="nowrap" for="complex_tables" id="complex_tables_label">
892        <input type="checkbox" name="complex_tables" value="complex_tables"  id = "complex_tables"
893                     /><span id='complex_tables_label_text'> <?php echo $this->getLang('complex_tables');?></span></label>
894      &nbsp;&nbsp;<label class="nowrap" for="editor_height"><?php echo $this->getLang('editor_height');?></label>
895        <input type="text" size= "4" name="editor_height" title = "<?php echo $this->getLang('editor_height_title'); ?>" value="<?php echo $height?>"  id = "editor_height"  onchange="setEdHeight(this.value);" />  px
896    &nbsp;&nbsp;<label class="nowrap" for="ckg_img_paste" title ="<?php echo $this->getLang('ckg_img_paste_title'); ?>"> <?php echo $this->getLang('ckg_img_paste') . " ". $this->getLang($paste_value) ?></label>
897        &nbsp;<input type="checkbox" name="ckg_img_paste" title = "<?php echo $this->getLang('ckg_img_paste_title'); ?>"
898            id = "ckg_img_paste"  value = "<?php echo $paste_value?>" onchange="ckgd_setImgPaste(this.value);" />
899
900      <input style="display:none;" class="button" id="edbtn__save" type="submit" name="do[save]"
901                      value="<?php echo $lang['btn_save']?>"
902                      onmouseup="draft_delete();"
903                      <?php echo $DW_EDIT_disabled; ?>
904                      title="<?php echo $lang['btn_save']?> "  />
905
906            <!-- Not used by ckgedit but required to prevent null error when DW adds events -->
907            <input type="button" id='edbtn__preview' style="display: none"/>
908
909
910 <div id='saved_wiki_html' style = 'display:none;' ></div>
911 <div id='ckgedit_draft_html' style = 'display:none;' >
912 <?php echo $this->draft_text; ?>
913 </div>
914
915         </div>
916      <?php } ?>
917
918        <?php if($wr){ ?>
919            <div class="summary">
920                <label for="edit__summary" class="nowrap"><?php echo $lang['summary']?>:</label>
921                <input type="text" class="edit" name="summary" id="edit__summary" size="50" value="<?php echo formText($SUM)?>" tabindex="2" />
922                <label class="nowrap" for="minoredit"><input type="checkbox" id="minoredit" name="minor" value="1" tabindex="3" /> <span><?php echo $this->getLang('minor_changes') ?></span></label>
923            </div>
924        <?php }?>
925        <?php if($this->captcha && $this->captcha->isEnabled()) echo $this->captcha->getHTML(); ?>
926    </div>
927   </form>
928
929        <!-- draft messages from DW -->
930        <div id="draft__status"></div>
931  <script type="text/javascript">
932//<![CDATA[
933        <?php  echo 'var backup_empty = "' . $this->getLang('backup_empty') .'";'; ?>
934        /* aspell_window removed, not supported */
935        if(window.unsetDokuWikiLockTimer) window.unsetDokuWikiLockTimer();
936
937
938  function getComplexTables() {
939     return  document.getElementById('complex_tables').checked;
940  }
941
942    <?php  global $useComplexTables;  if($useComplexTables) { ?>
943        document.getElementById('complex_tables').click();
944    <?php } ?>
945    <?php  if($this->getConf('complex_tables')) { ?>
946         document.getElementById('complex_tables').disabled = true;
947         document.getElementById('complex_tables_label').style = "display:none";
948         document.getElementById('complex_tables_label_text').style = "display:none";
949    <?php } ?>
950
951<?php
952
953
954   if(preg_match("/MISIE|Trident/",$_SERVER['HTTP_USER_AGENT'])) {
955      echo "var isIE = true;";
956   }
957   else {
958     echo "var isIE = false;";
959   }
960
961   echo "var doku_base = '" . DOKU_BASE ."'";
962
963?>
964
965   var ckgedit_draft_btn = "<?php echo $this->getLang('btn_exit_draft') ?>";
966   var ckgedit_draft_btn_title = "<?php echo $this->getLang('title_exit_draft')?>";
967   function ckgedit_get_draft() {
968      var dom = GetE('ckgedit_draft_html');
969      var draft = dom.innerHTML;
970      var dw_text =  CKEDITOR.instances.wiki__text.getData();
971
972      CKEDITOR.instances.wiki__text.setData(draft);
973      dom.innerHTML = dw_text;
974      var btn = GetE('ckgedit_draft_btn');
975      var tmp = btn.value;
976      btn.value = ckgedit_draft_btn;
977      ckgedit_draft_btn = tmp;
978      tmp = ckgedit_draft_btn_title;
979      btn.title = ckgedit_draft_btn_title;
980      ckgedit_draft_btn_title = tmp;
981   }
982
983
984   function safe_convert(value) {
985
986     if(oDokuWiki_FCKEditorInstance.dwiki_fnencode && oDokuWiki_FCKEditorInstance.dwiki_fnencode == 'safe') {
987      <?php
988       global $updateVersion;
989       if(!isset($updateVersion)) $updateVersion = 0;
990       echo "updateVersion=$updateVersion;";
991       $list = plugin_list('action');
992       $safe_converted = false;
993       if(in_array( 'safefnrecode' , $list)) {
994          $safe_converted = true;
995       }
996
997     ?>
998
999 		if(value.match(/%25/ && value.match(/%25[a-z0-9]/))) {
1000                          value = value.replace(/%25/g,"%");
1001                          <?php
1002                          if($updateVersion > 30 || $safe_converted) {
1003                            echo 'value = value.replace(/%5D/g,"]");';
1004                          }
1005                          ?>
1006
1007                          value =  dwikiUTF8_decodeFN(value,'safe');
1008                       }
1009        }
1010        return value;
1011
1012     }
1013
1014RegExp.escape = function(str)
1015{
1016    var specials = new RegExp("[.*+?|()\\[\\]{}\\\\]", "g"); // .*+?|()[]{}\
1017    return str.replace(specials, "\\$&");
1018}
1019var ckgedit_xcl_fonts =parseInt  ("<?php echo $this->getConf('font_options') ;?>");
1020var ckgedit_xcl_colors =parseInt("<?php echo $this->getConf('color_options') ;?>");
1021var ckgedit_xcl_styles = (ckgedit_xcl_fonts + ckgedit_xcl_colors ==2) ? true : false;
1022var HTMLParser_DEBUG = "";
1023var ckgedit_hasCaptcha = "<?php echo $this->captcha?1:0?>";
1024
1025<?php if($this->debug) { ?>
1026   function HTMLParser_debug() {
1027       HTMLParser_DEBUG = "";
1028       parse_wikitext("");
1029/*
1030      for(var i in oDokuWiki_FCKEditorInstance) {
1031         HTMLParser_DEBUG += i + ' = ' + oDokuWiki_FCKEditorInstance[i] + "\n";;
1032       }
1033*/
1034
1035       var w = window.open();
1036       w.document.write('<pre>' + HTMLParser_DEBUG + '</pre>');
1037       w.document.close();
1038  }
1039<?php } ?>
1040
1041<?php
1042       global $conf;
1043
1044       if(isset($conf['animal'])) {
1045         echo "var config_animal='" . $conf['animal'] . "';";
1046       }
1047   ?>
1048
1049 //]]>
1050
1051  </script>
1052
1053
1054
1055<?php
1056    }
1057
1058    /**
1059     * Renders a list of instruction to minimal xhtml
1060     *@author Myron Turner <turnermm02@shaw.ca>
1061     */
1062    function _render_xhtml($text){
1063        $mode = 'ckgedit';
1064
1065        global $skip_styling;
1066        $skip_styling =  $this->getConf('nofont_styling');
1067        if(!$skip_styling && $_POST['styling'] == 'no_styles') {
1068            $skip_styling = true;
1069        }
1070
1071        if(strpos($text,'~~NO_STYLING~~') !== false) {
1072            $skip_styling = true;
1073        }
1074 //    $text = preg_replace("/\\\\(\n|\s)/ms","CODE_BLOCK_EOL_MASK$1",$text);
1075     $text = preg_replace_callback('/\[\[(.*?>)(.*?)\]\]/ms',
1076              function ($matches) {
1077                 if(strpos($matches[0],"\n") !== false) return $matches[0];
1078                 if(preg_match("#<(\w+)>.*?<\/\\1>#",$matches[0])) return $matches[0];
1079                 list($name,$link_text) = explode('|',$matches[2]);
1080                 $retv = '[[' . $matches[1] . "oIWIKIo" . $name ."cIWIKIc";
1081                 if(!empty($link_text)) {
1082                     $retv .= "|$link_text";
1083                 }
1084                 return $retv . ']]';
1085              },
1086           $text);
1087
1088        // try default renderer first:
1089        $file = DOKU_INC."inc/parser/$mode.php";
1090
1091        if(@file_exists($file)){
1092
1093            require_once $file;
1094            $rclass = "Doku_Renderer_$mode";
1095
1096            if ( !class_exists($rclass) ) {
1097                trigger_error("Unable to resolve render class $rclass",E_USER_WARNING);
1098                msg("Renderer for $mode not valid",-1);
1099                return null;
1100            }
1101            $Renderer = new $rclass();
1102        }
1103        else{
1104            // Maybe a plugin is available?
1105            $Renderer = plugin_load('renderer',$mode);
1106            if(is_null($Renderer)){
1107                msg("No renderer for $mode found",-1);
1108                return null;
1109            }
1110        }
1111// aimed at wrap plugin which allows multiple newlines in a cell
1112$text = preg_replace_callback(
1113    '#(\|.*?)\|.?[\n\r]#ms',
1114        function ($matches) {
1115            $matches[0] = preg_replace("#\\\\\\\\\s*[\r\n]#ms", "  \\\\\\\\  ",$matches[0]);
1116            return ($matches[0]);
1117        },
1118    $text);
1119
1120        // prevents utf8 conversions of quotation marks
1121         $text = str_replace('"',"_ckgedit_QUOT_",$text);
1122
1123         $text = preg_replace_callback('/(<code.*?>)([^<]+)(<\/code>)/ms',
1124             create_function(
1125               '$matches',
1126               '$quot =  str_replace("_ckgedit_QUOT_",\'"\',$matches[2]);
1127                $quot = str_replace("\\\\ ","_ckgedit_NL",$quot);
1128                $quot .= "_ckgedit_NL";
1129                return $matches[1] . $quot . $matches[3];'
1130          ), $text);
1131
1132         $text = preg_replace_callback('/(<file.*?>)([^<]+)(<\/file>)/ms',
1133             create_function(
1134               '$matches',
1135               '$quot =  str_replace("_ckgedit_QUOT_",\'"\',$matches[2]);
1136                $quot = str_replace("\\\\ ","_ckgedit_NL",$quot);
1137                $quot .= "_ckgedit_NL";
1138                return $matches[1] . $quot . $matches[3];'
1139          ), $text);
1140
1141          $text = preg_replace_callback('/\|([\s\S]+)\|/ms',  // prevents  extra backslash  from hanging on a new line
1142            function ($matches) {
1143                if(!strpos($matches[1], "_ckgedit_NL")) return $matches[0];
1144                $matches[1]  =  str_replace("\\_ckgedit_NL","_ckgedit_NL",$matches[1]);
1145
1146                return '|' . $matches[1] . '|';
1147                return $matches[0];
1148            },
1149           $text
1150        );
1151
1152          $text = preg_replace_callback('/(<code>|<file>)([^<]+)(<\/code>|<\/file>)/ms',
1153             create_function(
1154               '$matches',
1155               '$matches[2] = str_replace("&lt;font","ckgeditFONTOpen",$matches[2]);
1156               $matches[2] = str_replace("font&gt;","ckgeditFONTClose",$matches[2]);
1157                return $matches[1] .$matches[2] . $matches[3]; '
1158          ), $text);
1159           $text = str_replace('CODE_BLOCK_EOL_MASK','\\', $text);
1160         ///  msg($text);
1161            $instructions = p_get_instructions("=== header ==="); // loads DOKU_PLUGINS array --M.T. Dec 22 2009
1162
1163        $instructions = p_get_instructions($text);
1164        if(is_null($instructions)) return '';
1165
1166        $Renderer->notoc();
1167        if(!$this->getConf('smiley_as_text')) {
1168        $Renderer->smileys = getSmileys();
1169        }
1170        $Renderer->entities = getEntities();
1171        $Renderer->acronyms = array();
1172        $Renderer->interwiki = getInterwiki();
1173
1174        // Loop through the instructions
1175        /*
1176           By-passing plugin processing was sugested and first implemented
1177           by Matti Lattu<matti.lattu@iki.fi>
1178           It is a significant contribution to the functionality of ckgEdit
1179        */
1180        foreach ( $instructions as $instruction ) {
1181             if ($instruction[0] == 'plugin') {
1182                $Renderer->doc .= $instruction[1][3];
1183          } else {
1184               // Execute the callback against the Renderer
1185               call_user_func_array(array(&$Renderer, $instruction[0]),$instruction[1]);
1186            }
1187        }
1188
1189        //set info array
1190        $info = $Renderer->info;
1191
1192        // Post process and return the output
1193        $data = array($mode,& $Renderer->doc);
1194        if(class_exists('dokuwiki\Extension\Event')) {
1195           Event::createAndTrigger('RENDERER_CONTENT_POSTPROCESS', $data);
1196        }
1197        else {
1198        trigger_event('RENDERER_CONTENT_POSTPROCESS',$data);
1199        }
1200
1201        $xhtml = $Renderer->doc;
1202	    $xhtml = str_replace(
1203		    array('NWIKISTART','NWIKICLOSE'),
1204		    array('&amp;lt;nowiki>','&amp;lt;/nowiki>'),$xhtml);
1205
1206        if(!$skip_styling) {  // create font styles from font plugin markup for html display
1207        $xhtml = preg_replace_callback(
1208            '|&amp;lt;font\s+(.*?)/([\w ,\-]+);;([\(\)),\w,\s\#]+);;([\(\)),\w,\s\#]+)&gt;(.*?)&amp;lt;/font&gt;|ms',
1209             function($matches) {
1210               $count = 0; $str='';
1211              if($matches[3] && $matches[3] != 'inherit') { $str .= '<span style = "color:' . $matches[3] .'">'; $count++;}
1212              if($matches[1] && $matches[1] != 'inherit') { $str .= '<span style = "font-size:' . $matches[1] .'">'; $count++; }
1213              if($matches[2] && $matches[2] != 'inherit') { $str .= '<span style = "font-family:' . $matches[2] .'">'; $count++; }
1214              if($matches[4] && $matches[4] != 'inherit') { $str .= '<span style = "background-color:' . $matches[4] .'">'; $count++; }
1215              $str .= $matches[5];
1216              for($i =0; $i<$count; $i++) {
1217                  $str .= '</span>';
1218              }
1219               return $str;
1220             }, $xhtml
1221        );
1222        }
1223
1224    /**
1225     * Alternative to  the one liner at 1179:  $xhtml = str_replace(array('oiwikio','ciwikic'),array('oIWIKIo','cIWIKIc'),$xhtml);
1226     *  if it turns out that there are users using  'oiwikio','ciwikic'
1227     $xhtml = preg_replace_callback(
1228        '|class=\"interwiki.*?href=\".*?:oiwikiotowerciwikic\".*?title=\".*?oiwikiotowerciwikic\"|ms',
1229        function($matches) {
1230           $matches[0] = str_replace(array('oiwikio','ciwikic'),array('oIWIKIo','cIWIKIc'),$matches[0]);
1231          return $matches[0];
1232       },$xhtml
1233       );
1234     */
1235     if(stripos($xhtml,'oIWIKIo') !== false) {
1236        $xhtml = str_replace(array('oiwikio','ciwikic'),array('oIWIKIo','cIWIKIc'),$xhtml);
1237            $xhtml = preg_replace_callback(
1238                '/<?(.*?)oIWIKIo(.*?)cIWIKIc/ms',
1239                 create_function(
1240                   '$matches',
1241                   ' if(preg_match("/^\w+$/",$matches[2]) && $matches[1] == "/")  return "/". $matches[2];
1242                     return $matches[0];'
1243              ),
1244              $xhtml
1245            );
1246            $xhtml = preg_replace_callback(
1247                '/>oIWIKIo(.*?)cIWIKIc(?=<\/a>)/ms',
1248                 create_function(
1249                   '$matches',
1250                   ' return ">". $matches[1] ;'
1251              ),
1252              $xhtml
1253            );
1254
1255           }
1256
1257        $pos = strpos($xhtml, 'MULTI_PLUGIN_OPEN');
1258        if($pos !== false) {
1259           $xhtml = preg_replace_callback(
1260            '|MULTI_PLUGIN_OPEN.*?MULTI_PLUGIN_CLOSE|ms',
1261            create_function(
1262                '$matches',
1263                  '$matches[0] = str_replace("//<//", "< ",$matches[0]);
1264                  $matches[0] = str_replace(array("oIWIKIo","cIWIKIc"),"",$matches[0]);
1265                  return preg_replace("/\n/ms","<br />",$matches[0]);'
1266            ),
1267            $xhtml
1268          );
1269
1270           $xhtml = preg_replace('/~\s*~\s*MULTI_PLUGIN_OPEN~\s*~/', "\n\n~~MULTI_PLUGIN_OPEN~~<span class='multi_p_open'>\n\n</span>\n\n", $xhtml);
1271           $xhtml = preg_replace('/~\s*~\s*MULTI_PLUGIN_CLOSE~\s*~/', "<span class='multi_p_close'>\n\n<br /></span>\n\n~~MULTI_PLUGIN_CLOSE~~\n\n", $xhtml);
1272
1273        }
1274
1275
1276         // remove empty paragraph: see _ckgedit_NPBBR_ comment above
1277        $xhtml = preg_replace('/<p>\s+_ckgedit_NPBBR_\s+<\/p>/ms',"\n",$xhtml);
1278        $xhtml = str_replace('_ckgedit_NPBBR_', "<span class='np_break'>&nbsp;</span>", $xhtml);
1279        $xhtml = str_replace('_ckgedit_QUOT_', '&quot;', $xhtml);
1280        $xhtml = str_replace('_ckgedit_NL', "\n", $xhtml);
1281        $xhtml = str_replace('</pre>', "\n\n</pre><p>&nbsp;</p>", $xhtml);
1282        // inserts p before an initial codeblock to enable text entry above block
1283        $xhtml = preg_replace('/^<pre/',"<p>&nbsp;</p><pre",$xhtml);
1284        //remove empty markup remaining after removing marked-up acronyms in lists
1285        $xhtml = preg_replace('/<(em|b|u|i)>\s+<\/(em|b|u|i)>/ms',"",$xhtml);
1286        $xhtml = preg_replace("/col\d+\s+(\w+align)/ms", "$1",$xhtml);  //remove col number for cell prpoerties dialog
1287        $xhtml = str_replace('ckgeditFONTOpen', '&amp;lt;font',$xhtml);  // protect font markup in code blocks
1288        $xhtml = str_replace('ckgeditFONTClose', 'font&amp;gt;',$xhtml);
1289        $xhtml = str_replace('DBLBACKSPLASH', '\\ ',$xhtml);
1290        $xhtml = str_replace('NWPIPECHARACTER', '|',$xhtml);
1291        $xhtml = str_replace('&amp;lt;blockquote&gt;','<blockquote>',$xhtml);
1292        $xhtml = str_replace('&amp;lt;/blockquote&gt;','</blockquote>',$xhtml);
1293
1294       $xhtml= preg_replace_callback(
1295            '/(<p>\s*)?<blockquote>(.*?)<\/blockquote>(\s*<\/p>)?/ms',
1296            function($matches) {
1297                $matches[0] = preg_replace("/(<p>)?\s*(<blockquote>)\s*(<\/p>)?/m","<p></p>$2",$matches[0]);
1298                $matches[0] = preg_replace("/(<p>)?\s*(<\/blockquote>)\s*(<\/p>)?/m","$2<p></p>",$matches[0]);
1299             //   $matches[0] = str_replace('<blockquote>',  '<blockquote class ="blockquote-plugin">', $matches[0]);
1300               return $matches[0];
1301            },    $xhtml
1302        );
1303
1304      $ua = strtolower ($_SERVER['HTTP_USER_AGENT']);
1305	  if(strpos($ua,'chrome') !== false) {
1306       $xhtml = preg_replace_callback(
1307             '/(?<=<a )(href=\".*?\")(\s+\w+=\".*?\")(.*?)(?=>)/sm',
1308			 create_function(
1309			 '$matches',
1310			 '$ret_str = " " . trim($matches[3]) . " " . trim($matches[2])  . " " . trim($matches[1]) ;
1311			  return $ret_str;'
1312			 ),
1313			 $xhtml
1314			 );
1315		}
1316
1317        return $xhtml;
1318    }
1319
1320  function write_debug($what,$line="") {
1321     return;
1322     $handle = fopen("ckgedit_php.txt", "a");
1323    // if(is_array($what)) $what = print_r($what,true);
1324     if($line) $what = "line $line\n" . $what;
1325     fwrite($handle,"$what\n");
1326     fclose($handle);
1327  }
1328
1329    function get_switch_fb_value() {
1330        if ($this->getUserFb() == 'dokuwiki') {
1331            $fbText = $this->getLang('btn_val_ckg_fb');
1332        } else {
1333            $fbText = $this->getLang('btn_val_dw_fb');
1334        }
1335        return $fbText;
1336    }
1337
1338    function get_switch_fb_title() {
1339        if ($this->getUserFb() == 'dokuwiki') {
1340            $fbText = $this->getLang('btn_title_ckg_fb');
1341        } else {
1342            $fbText = $this->getLang('btn_title_dw_fb');
1343        }
1344        return $fbText;
1345    }
1346
1347    function getUserFb() {
1348        //get user file browser
1349        if (!isset($_COOKIE['ckgFbOpt'])) {
1350            $_COOKIE['ckgFbOpt'] = $this->getConf('default_ckg_filebrowser');
1351        }
1352        return $_COOKIE['ckgFbOpt'];
1353    }
1354
1355} //end of action class
1356
1357?>
1358