You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

1350 lines
53 KiB

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