*/ class action_plugin_fckg_edit extends DokuWiki_Action_Plugin { //store the namespaces for sorting var $fck_location = "fckeditor"; var $helper = false; var $fckg_bak_file = ""; var $debug = false; var $test = false; var $page_from_template; var $draft_found = false; var $draft_text; /** * Constructor */ function action_plugin_fckg_edit() { $this->setupLocale(); $this->helper = plugin_load('helper', 'fckg'); } function register(Doku_Event_Handler $controller) { if(method_exists($this->helper, 'is_outOfScope') && $this->helper->is_outOfScope()) return; global $FCKG_show_preview; $FCKG_show_preview = true; if(isset($_REQUEST['mode']) && $_REQUEST['mode'] == 'dwiki') { $FCKG_show_preview = true; return; } elseif(isset($_COOKIE['FCKG_USE'])) { preg_match('/_\w+_/', $_COOKIE['FCKG_USE'], $matches); if($matches[0] == '_false_') { $FCKG_show_preview = true; return; } } $Fck_NmSp = "!!NONSET!!"; if(isset($_COOKIE['FCK_NmSp'])) { $Fck_NmSp = $_COOKIE['FCK_NmSp']; } $dwedit_ns = @$this->getConf('dwedit_ns'); if(isset($dwedit_ns) && $dwedit_ns) { $ns_choices = explode(',',$dwedit_ns); foreach($ns_choices as $ns) { $ns = trim($ns); if(preg_match("/$ns/",$_REQUEST['id']) || preg_match("/$ns/",$Fck_NmSp)) { $FCKG_show_preview = true; return; } } } $controller->register_hook('COMMON_PAGE_FROMTEMPLATE', 'AFTER', $this, 'pagefromtemplate', array()); $controller->register_hook('COMMON_PAGETPL_LOAD', 'AFTER', $this, 'pagefromtemplate', array()); $controller->register_hook('TPL_ACT_RENDER', 'BEFORE', $this, 'fckg_edit'); $controller->register_hook('TPL_METAHEADER_OUTPUT', 'BEFORE', $this, 'fckg_edit_meta'); } /** * function pagefromtemplate * Capture template text output by Template Event handler instead of pageTemplate() * @author Myron Turner * */ function pagefromtemplate(&$event) { if($event->data['tpl']) { $this->page_from_template = $event->data['tpl']; } } /** * fckg_edit_meta * * load fck js * @author Pierre Spring * @param mixed $event * @access public * @return void */ function fckg_edit_meta(&$event) { global $ACT; // we only change the edit behaviour if ($ACT != 'edit'){ return; } global $ID; global $REV; global $INFO; $event->data['script'][] = array( 'type'=>'text/javascript', 'charset'=>'utf-8', '_data'=>'', 'src'=>DOKU_BASE.'lib/plugins/fckg/' .$this->fck_location. '/fckeditor.js' ); $event->data['script'][] = array( 'type'=>'text/javascript', 'charset'=>'utf-8', '_data'=>'', 'src'=>DOKU_BASE.'lib/plugins/fckg/scripts/vki_kb.js' ); $ua = strtolower ($_SERVER['HTTP_USER_AGENT']); if(strpos($ua, 'msie') !== false) { echo "\n" . '' ."\n"; } return; } /** * function fckg_edit * @author Pierre Spring * edit screen using fck * * @param & $event * @access public * @return void */ function fckg_edit(&$event) { global $INFO; // we only change the edit behaviour if ($event->data != 'edit') { return; } // load xml and acl if (!$this->_preprocess()){ return; } // print out the edit screen $this->_print(); // prevent Dokuwiki normal processing of $ACT (it would clean the variable and destroy our 'index' value. $event->preventDefault(); // index command belongs to us, there is no need to hold up Dokuwiki letting other plugins see if its for them $event->stopPropagation(); } /** * function _preprocess * @author Myron Turner */ function _preprocess() { global $ID; global $REV; global $DATE; global $RANGE; global $PRE; global $SUF; global $INFO; global $SUM; global $lang; global $conf; global $fckg_lang; //set summary default if(!$SUM){ if($REV){ $SUM = $lang['restored']; }elseif(!$INFO['exists']){ $SUM = $lang['created']; } } if($INFO['exists']){ if($RANGE){ list($PRE,$text,$SUF) = rawWikiSlices($RANGE,$ID,$REV); }else{ $text = rawWiki($ID,$REV); } }else{ //try to load a pagetemplate $text = pageTemplate($ID); //Check for text from template event handler if(!$text && $this->page_from_template) $text = $this->page_from_template; } $text = str_replace("{{rss>http://", "{ { rss>Feed:", $text); if($this->getConf('smiley_hack')) { $new_addr = $_SERVER['SERVER_NAME'] . DOKU_BASE; $text=preg_replace("#(?<=http://)(.*?)(?=lib/plugins/fckg/fckeditor/editor/images/smiley/msn)#s", $new_addr,$text); } $text = preg_replace_callback('/\[\[\w+>.*?\]\]/ms', create_function( '$matches', 'return str_replace("/", "__IWIKI_FSLASH__" ,$matches[0]);' ), $text); global $useComplexTables; if($this->getConf('complex_tables') || strrpos($text, '~~COMPLEX_TABLES~~') !== false) { $useComplexTables=true; } else { $useComplexTables=false; } if(strpos($text, '%%') !== false) { $text= preg_replace_callback( "/<(nowiki|code|file)>(.*?)<\/(nowiki|code|file)/ms", function ($matches) { $matches[0] = str_replace('%%', 'DBLPERCENT',$matches[0]); return $matches[0]; }, $text ); $text = preg_replace_callback( "/(?)%%(.*?)%%/ms", function($matches) { return '' . $matches[1] . ''; }, $text ); $text = str_replace('DBLPERCENT','%%',$text); } /* convert html tags to entities in indented code blocks*/ $text= preg_replace_callback( '/(\n )((?![\*\-]).*?)(\n)(?!\s)/ms', create_function( '$matches', '$matches[0] = preg_replace("/(\[\[\w+)>/ms","$1__IWIKI__",$matches[0]); $matches[0] = preg_replace("/<(?!\s)/ms", "<", $matches[0]); $matches[0] = preg_replace("/(?/ms", ">", $matches[0]); $matches[0] = preg_replace("/__IWIKI__/ms", ">", $matches[0]); return $matches[0]; ' ), $text ); $pos = strpos($text, '<'); if($pos !== false) { $text = preg_replace_callback( '/()(.*?)(<\/nowiki>)/ms', create_function( '$matches', '$needles = array("[","]", "/", ".", "*", "_","\'","<",">","%", "{", "}", "\\\"); $replacements = array("[","]","/", ".", "*", "_", "'", "<",">","%", "{","}", "\"); $matches[2] = str_replace($needles, $replacements, $matches[2]); return $matches[1] . $matches[2] . $matches[3];' ), $text ); $text = preg_replace_callback( '/<(code|file)(.*?)(>)(.*?)(<\/\1>)/ms', create_function( '$matches', 'if(preg_match("/\w+/",$matches[2])) { $matches[4] = str_replace("CHEVRONescC", ">>",$matches[4]); $matches[4] = str_replace("CHEVRONescO", "<<",$matches[4]); $matches[4] = preg_replace("/<(?!\s)/ms", "__GESHI_OPEN__", $matches[4]); } else { if( preg_match("/MULTI/",$matches[0])) { $open = "< "; $close = " >"; } else { $open = "<"; $close = ">"; } $matches[4] = preg_replace("/<(?!\s)/ms", $open, $matches[4]); $matches[4] = preg_replace("/(?/ms", $close, $matches[4]); } $matches[4] = str_replace("\"", "__GESHI_QUOT__", $matches[4]); return "<" . $matches[1] . $matches[2] . $matches[3] . $matches[4] . $matches[5];' ), $text ); /* \n_fckg_NPBBR_\n: the final \n prevents this from iterfering with next in line markups -- in particular tables which require a new line and margin left this may leave an empty paragraph in the xhtml, which is removed below */ $text = preg_replace('/<\/(code|file)>(\s*)(?=[^\w])(\s*)/m',"\n_fckg_NPBBR_\n$2",$text ); $text = preg_replace_callback( '/(\|\s*)(|)(.*?)(<\/code>|<\/file>)\n_fckg_NPBBR_(?=.*?\|)/ms', create_function( '$matches', '$matches[2] = preg_replace("//ms", "TPRE_CODE", $matches[2]); $matches[2] = preg_replace("//ms", "TPRE_FILE", $matches[2]); $matches[4] = "TPRE_CLOSE"; $matches[3] = preg_replace("/^\n+/", "TC_NL",$matches[3]); $matches[3] = preg_replace("/\n/ms", "TC_NL",$matches[3]); return $matches[1] . $matches[2] . trim($matches[3]) . $matches[4];' ), $text ); $text = preg_replace('/TPRE_CLOSE\s+/ms',"TPRE_CLOSE",$text); $text = preg_replace('/<(?!code|file|plugin|del|sup|sub|\/\/|\s|\/del|\/code|\/file|\/plugin|\/sup|\/sub)/ms',"//)/ms', create_function( '$matches', 'return str_replace("//","", $matches[0]);' ), $text ); $text = str_replace('',' ', $text); } if($this->getConf('duplicate_notes')) { $text = preg_replace_callback('/\(\(/ms', create_function( '$matches', 'static $count = 0; $count++; $ins = "FNoteINSert" . $count; return "(($ins";' ), $text ); } $text = preg_replace('/^\>/ms',"_dwQUOT_",$text); // dw quotes $text = str_replace('>>','CHEVRONescC',$text); $text = str_replace('<<','CHEVRONescO',$text); $text = preg_replace('/(={3,}.*?)(\{\{.*?\}\})(.*?={3,})/',"$1$3\n$2",$text); $email_regex = '/\/\/\<\/\/(.*?@.*?)>/'; $text = preg_replace($email_regex,"<$1>",$text); $text = preg_replace('/{{(.*)\.swf(\s*)}}/ms',"SWF$1.swf$2FWS",$text); $this->xhtml = $this->_render_xhtml($text); $this->xhtml = str_replace("__IWIKI_FSLASH__", "⁄", $this->xhtml); if($this->getConf('duplicate_notes')) { $this->xhtml = preg_replace("/FNoteINSert\d+/ms", "",$this->xhtml); } $this->xhtml = str_replace("__GESHI_QUOT__", '"', $this->xhtml); $this->xhtml = str_replace("__GESHI_OPEN__", "< ", $this->xhtml); $this->xhtml = str_replace('CHEVRONescC', '>>',$this->xhtml); $this->xhtml = str_replace('CHEVRONescO', '<<',$this->xhtml); $this->xhtml = preg_replace('/_dwQUOT_/ms','>',$this->xhtml); // dw quotes if($pos !== false) { $this->xhtml = preg_replace_callback( '/(TPRE_CODE|TPRE_FILE)(.*?)(TPRE_CLOSE)/ms', create_function( '$matches', '$matches[1] = preg_replace("/TPRE_CODE/","
\n", $matches[1]);  
                    $matches[1] = preg_replace("/TPRE_FILE/","
\n", $matches[1]);  
                    $matches[2] = preg_replace("/TC_NL/ms", "\n", $matches[2]);  
                    $matches[3] = "
"; return $matches[1] . $matches[2] . $matches[3];' ), $this->xhtml ); } $this->xhtml = preg_replace_callback( '/()(.*?)(<\/pre>)/ms', create_function( '$matches', '$matches[4] = preg_replace("/(\||\^)[ ]+(\||\^)/ms","$1   $2" , $matches[4]); return $matches[1] . $matches[2] . $matches[3] . $matches[4] . $matches[5];' ), $this->xhtml ); $cname = getCacheName($INFO['client'].$ID,'.draft.fckl'); if(file_exists($cname)) { $cdata = unserialize(io_readFile($cname,false)); $cdata['text'] = urldecode($cdata['text']); preg_match_all("/<\/(.*?)\>/", $cdata['text'],$matches); /* exclude drafts saved from preview mode */ if (!in_array('code', $matches[1]) && !in_array('file', $matches[1]) && !in_array('nowiki', $matches[1])) { $this->draft_text = $cdata['text']; $this->draft_found = true; msg($fckg_lang['draft_msg']) ; } unlink($cname); } return true; } /** * function dw_edit_displayed * @author Myron Turner * determines whether or not to show or hide the 'DW Edit' button */ function dw_edit_displayed() { global $INFO; $dw_edit_display = @$this->getConf('dw_edit_display'); if(!isset($dw_edit_display))return ""; //version 0. if($dw_edit_display != 'all') { $admin_exclusion = false; if($dw_edit_display == 'admin' && ($INFO['isadmin'] || $INFO['ismanager']) ) { $admin_exclusion = true; } if($dw_edit_display == 'none' || $admin_exclusion === false) { return ' style = "display:none"; '; } return ""; } return ""; } /** * function _print * @author Myron Turner */ function _print() { global $INFO; global $lang; global $fckg_lang; global $ID; global $REV; global $DATE; global $PRE; global $SUF; global $SUM; $wr = $INFO['writable']; if($wr){ if ($REV) print p_locale_xhtml('editrev'); $ro=false; }else{ // check pseudo action 'source' if(!actionOK('source')){ msg('Command disabled: source',-1); return false; } print p_locale_xhtml('read'); $ro='readonly="readonly"'; } if(!$DATE) $DATE = $INFO['lastmod']; $guest_toolbar = $this->getConf('guest_toolbar'); $guest_media = $this->getConf('guest_media'); if(!isset($INFO['userinfo']) && !$guest_toolbar) { echo $this->helper->registerOnLoad( ' fck = new FCKeditor("wiki__text", "100%", "600"); fck.BasePath = "'.DOKU_BASE.'lib/plugins/fckg/'.$this->fck_location.'/"; fck.ToolbarSet = "DokuwikiNoGuest"; fck.ReplaceTextarea();' ); } else if(!isset($INFO['userinfo']) && !$guest_media) { echo $this->helper->registerOnLoad( ' fck = new FCKeditor("wiki__text", "100%", "600"); fck.BasePath = "'.DOKU_BASE.'lib/plugins/fckg/'.$this->fck_location.'/"; fck.ToolbarSet = "DokuwikiGuest"; fck.ReplaceTextarea();' ); } else { echo $this->helper->registerOnLoad( ' fck = new FCKeditor("wiki__text", "100%", "600"); fck.BasePath = "'.DOKU_BASE.'lib/plugins/fckg/'.$this->fck_location.'/"; fck.ToolbarSet = "Dokuwiki"; fck.ReplaceTextarea();' ); } ?>
dw_edit_displayed(); ?>
onmousedown="parse_wikitext('edbtn__save');" /> name="do[delete]" value="" title="" style = "font-size: 100%;" onmouseup="draft_delete();" onclick = "return confirm('');" /> style = "font-size: 100%;" onclick ="setDWEditCookie(2, this);parse_wikitext('edbtn__save');this.form.submit();" type="submit" name="do[save]" value="" title="" /> test ? 'inline' : 'none'; $backup_btn = isset($fckg_lang['dw_btn_backup'])? $fckg_lang['dw_btn_backup'] : $fckg_lang['dw_btn_refresh']; $backup_title = isset($fckg_lang['title_dw_backup'])? $fckg_lang['title_dw_backup'] : $fckg_lang['title_dw_refresh']; $using_scayt = ($this->getConf('scayt')) == 'on'; ?> draft_found) { ?>    
debug) { ?>
      [ close ]   
/> title=" " />
*/ function _render_xhtml($text){ $mode = 'fckg'; global $Smilies; $smiley_as_text = @$this->getConf('smiley_as_text'); if($smiley_as_text) { $Smilies = array('8-)'=>'aSMILEY_1', '8-O'=>'aSMILEY_2', ':-('=>'aSMILEY_3', ':-)'=>'aSMILEY_4', '=)' => 'aSMILEY_5', ':-/' => 'aSMILEY_6', ':-\\' => 'aSMILEY_7', ':-?' => 'aSMILEY_8', ':-D'=>'aSMILEY_9', ':-P'=>'bSMILEY_10', ':-O'=>'bSMILEY_11', ':-X'=>'bSMILEY_12', ':-|'=>'bSMILEY_13', ';-)'=>'bSMILEY_14', '^_^'=>'bSMILEY_15', ':?:'=>'bSMILEY_16', ':!:'=>'bSMILEY_17', 'LOL'=>'bSMILEY_18', 'FIXME'=>'bSMILEY_19', 'DELETEME'=>'bSMILEY_20'); $s_values = array_values($Smilies); $s_values_regex = implode('|', $s_values); $s_keys = array_keys($Smilies); $s_keys = array_map ( create_function( '$k', 'return "(" . preg_quote($k,"/") . ")";' ) , $s_keys ); $s_keys_regex = implode('|', $s_keys); global $haveDokuSmilies; $haveDokuSmilies = false; $text = preg_replace_callback( '/(' . $s_keys_regex . ')/ms', create_function( '$matches', 'global $Smilies; global $haveDokuSmilies; $haveDokuSmilies = true; return $Smilies[$matches[1]];' ), $text ); } // try default renderer first: $file = DOKU_INC."inc/parser/$mode.php"; if(@file_exists($file)){ require_once $file; $rclass = "Doku_Renderer_$mode"; if ( !class_exists($rclass) ) { trigger_error("Unable to resolve render class $rclass",E_USER_WARNING); msg("Renderer for $mode not valid",-1); return null; } $Renderer = new $rclass(); } else{ // Maybe a plugin is available? $Renderer = plugin_load('renderer',$mode); if(is_null($Renderer)){ msg("No renderer for $mode found",-1); return null; } } // prevents utf8 conversions of quotation marks $text = str_replace('"',"_fckg_QUOT_",$text); $text = preg_replace_callback('/()(.*?)(<\/code>)/ms', create_function( '$matches', '$quot = str_replace("_fckg_QUOT_",\'"\',$matches[2]); $quot = str_replace("\\\\ ","_fckg_NL",$quot); return $matches[1] . $quot . $matches[3];' ), $text); global $fckgLPluginPatterns; $fckgLPluginPatterns = array(); $instructions = p_get_instructions("=== header ==="); // loads DOKU_PLUGINS array --M.T. Dec 22 2009 $installed_plugins = $this->get_plugins(); $regexes = $installed_plugins['plugins']; $text = preg_replace_callback('/('. $regexes .')/', create_function( '$matches', 'global $fckgLPluginPatterns; $retv = preg_replace("/([\{\}\@\:&~\?\!<>])/", "$1 ", $matches[0]); $fckgLPluginPatterns[] = array($retv, $matches[0]); return $retv;' ), $text); global $fckLImmutables; $fckglImmutables=array(); foreach($installed_plugins['xcl'] as $xcl) { $text = preg_replace_callback('/'. $xcl . '/', create_function( '$matches', 'global $fckLImmutables; if(preg_match("#//" . str_replace("//" ;' ), $text); } global $multi_block; if(preg_match('/(?=MULTI_PLUGIN_OPEN)(.*?)(?<=MULTI_PLUGIN_CLOSE)/ms', $text, $matches)) { //file_put_contents('multi_text-2.txt',$matches[1]); $multi_block = $matches[1]; } $instructions = p_get_instructions($text); if(is_null($instructions)) return ''; $Renderer->notoc(); $Renderer->smileys = getSmileys(); $Renderer->entities = getEntities(); $Renderer->acronyms = array(); $Renderer->interwiki = getInterwiki(); // Loop through the instructions foreach ( $instructions as $instruction ) { // Execute the callback against the Renderer call_user_func_array(array(&$Renderer, $instruction[0]),$instruction[1]); } //set info array $info = $Renderer->info; // Post process and return the output $data = array($mode,& $Renderer->doc); trigger_event('RENDERER_CONTENT_POSTPROCESS',$data); $xhtml = $Renderer->doc; $pos = strpos($xhtml, 'MULTI_PLUGIN_OPEN'); if($pos !== false) { $xhtml = preg_replace('/MULTI_PLUGIN_OPEN.*?MULTI_PLUGIN_CLOSE/ms', $multi_block, $xhtml); $xhtml = preg_replace_callback( '|MULTI_PLUGIN_OPEN.*?MULTI_PLUGIN_CLOSE|ms', create_function( '$matches', '$matches[0] = str_replace("//",$matches[0]);' ), $xhtml ); $xhtml = preg_replace('/~\s*~\s*MULTI_PLUGIN_OPEN~\s*~/', "~ ~ MULTI_PLUGIN_OPEN~ ~\n\n\n\n", $xhtml); $xhtml = preg_replace('/~\s*~\s*MULTI_PLUGIN_CLOSE~\s*~/', "\n\n\n\n~ ~ MULTI_PLUGIN_CLOSE~ ~\n", $xhtml); } // remove empty paragraph: see _fckg_NPBBR_ comment above $xhtml = preg_replace('/

\s+_fckg_NPBBR_\s+<\/p>/ms',"\n",$xhtml); $xhtml = str_replace('_fckg_NPBBR_', " ", $xhtml); $xhtml = str_replace('_fckg_QUOT_', '"', $xhtml); $xhtml = str_replace('_fckg_NL', "\n", $xhtml); $xhtml = str_replace('

', "\n\n

 

", $xhtml); // inserts p before an initial codeblock to enable text entry above block $xhtml = preg_replace('/^
 

\s+<\/(em|b|u|i)>/ms',"",$xhtml); if($smiley_as_text) { if($haveDokuSmilies) { $s_values = array_values($Smilies); $s_values_regex = (implode('|', $s_values)); $xhtml = preg_replace_callback( '/(' . $s_values_regex . ')/ms', create_function( '$matches', 'global $Smilies; return array_search($matches[1],$Smilies); ' ), $xhtml ); } } $ua = strtolower ($_SERVER['HTTP_USER_AGENT']); if(strpos($ua,'chrome') !== false) { $xhtml = preg_replace_callback( '/(?<=)/sm', create_function( '$matches', '$ret_str = " " . trim($matches[3]) . " " . trim($matches[2]) . " " . trim($matches[1]) ; return $ret_str;' ), $xhtml ); } return $xhtml; } function write_debug($what) { return; $handle = fopen("edit_php.txt", "a"); if(is_array($what)) $what = print_r($what,true); fwrite($handle,"$what\n"); fclose($handle); } /** * @author Myron Turner * Converts FCK extended syntax to native DokuWiki syntax */ function fck_convert_text(&$event) { } function big_file() { } /** * get regular expressions for installed plugins * @author Myron Turner * return string of regexes suitable for PCRE matching */ function get_plugins() { global $DOKU_PLUGINS; $list = plugin_list('syntax'); $data = $DOKU_PLUGINS['syntax'][$list[0]]->Lexer->_regexes['base']->_labels; $patterns = $DOKU_PLUGINS['syntax'][$list[0]]->Lexer->_regexes['base']->_patterns; $labels = array(); $regex = '~~NOCACHE~~|~~NOTOC~~'; //$regex .= "|\{\{rss>http:\/\/.*?\}\}"; $exclusions = $this->getConf('xcl_plugins'); $exclusions = trim($exclusions, " ,"); $exclusions = explode (',', $exclusions); $exclusions[] = 'fckg_font'; $list = array_diff($list,$exclusions); foreach($list as $plugin) { if(preg_match('/fckg_dwplugin/',$plugin)) continue; $plugin = 'plugin_' . $plugin; $indices = array_keys($data, $plugin); if(empty($indices)) { $plugin = '_' . $plugin; $indices = array_keys($data, $plugin); } if(!empty($indices)) { foreach($indices as $index) { $labels[] = "$index: " . $patterns[$index]; $pattern = $patterns[$index]; $pattern = preg_replace('/^\(\^/',"(",$pattern); $regex .= "|$pattern"; } } } $regex = ltrim($regex, '|'); $regex_xcl = array(); foreach($exclusions as $plugin) { if(preg_match('/fckg_dwplugin/',$plugin)) continue; $plugin = 'plugin_' . $plugin; $indices = array_keys($data, $plugin); if(empty($indices)) { $plugin = '_' . $plugin; $indices = array_keys($data, $plugin); } if(!empty($indices)) { foreach($indices as $index) { $pos = strpos($patterns[$index],'<'); if($pos !== false) { $pattern = str_replace('<', '\/\/<\/\/', $patterns[$index]); $pattern = str_replace('?=',"",$pattern); $regex_xcl[] = $pattern; } } } } return array('plugins'=> $regex, 'xcl'=> $regex_xcl); //return $regex; } } //end of action class ?>