* @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html */ // must be run within Dokuwiki if(!defined('DOKU_INC')) die(); class action_plugin_xtern extends DokuWiki_Action_Plugin { private $accumulator = null; private $current; function __construct() { $this->accumulator = metaFN('xtern:accumulator','.ser'); } public function register(Doku_Event_Handler $controller) { $controller->register_hook('AJAX_CALL_UNKNOWN', 'BEFORE', $this, 'handle_ajax_call_unknown'); $controller->register_hook('DOKUWIKI_STARTED', 'BEFORE', $this, 'curl_check'); $controller->register_hook('IO_WIKIPAGE_READ', 'AFTER', $this, 'handle_wiki_read'); $controller->register_hook('TPL_CONTENT_DISPLAY', 'BEFORE', $this, 'handle_wiki_content'); $controller->register_hook('COMMON_WIKIPAGE_SAVE', 'BEFORE', $this, 'handle_page_save'); } /** * @param Doku_Event $event event object by reference * @param mixed $param [the parameters passed as fifth argument to register_hook() when this * handler was registered] * @return void */ public function curl_check(Doku_Event $event, $param) { global $USERINFO,$JSINFO,$ID; $admin = false; if(isset($USERINFO)) { $groups = $USERINFO['grps']; if(in_array('admin', $groups)) $admin = true; } if($admin && !function_exists("curl_init")) { msg($this->getLang('nocurl'),2); return; } $this->accumulator = metaFN('xtern:accumulator','.ser'); if($this->getConf('noicons')) { $JSINFO['xtern_disable'] = '1'; } if($this->getConf('alt_div')) { $JSINFO['xtern_selector'] = "#" .$this->getConf('alt_div') . " a"; } else if($this->getConf('alt_class')) { $JSINFO['xtern_selector'] = '.' . $this->getConf('alt_class') . " a"; } $skip = $this->getConf('skip_pages'); if($skip) { $skip = preg_replace("/\s+/","",$skip) ; $skip = str_replace(',','|',$skip) ; $regex = "#^($skip)$#"; if(preg_match($regex,$ID)) { $JSINFO['xtern_skip'] = 1; } } } public function handle_ajax_call_unknown(Doku_Event $event, $param) { if ($event->data !== 'extern_url') { return; } global $lang,$INPUT; $event->stopPropagation(); $event->preventDefault(); $url = $INPUT->str('url'); if(!function_exists("curl_init")) { echo "NOCURL"; return; } $url = urldecode($url); $ch = curl_init($url); if($this->getConf('ca_required')) { curl_setopt($ch, CURLOPT_CAINFO, __DIR__ . "/ca/cacert.pem"); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 1); } curl_setopt($ch,CURLOPT_RETURNTRANSFER,1); curl_setopt($ch,CURLOPT_FOLLOWLOCATION,1); curl_setopt($ch, CURLOPT_MAXREDIRS, 5); curl_setopt($ch,CURLOPT_TIMEOUT,10); curl_setopt($ch, CURLOPT_NOBODY, 1); //just fetch headers $output = curl_exec($ch); $curl_errno = curl_errno($ch); if($curl_errno) { if($curl_errno == "28") { $status = "408"; } else if($curl_errno == "60") { $status = "495"; } else $status = $curl_errno; } else $status = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); echo "$status"; return 1; } function handle_wiki_read(Doku_Event $event, $param) { global $INPUT, $ACT; if($event->data[3]) { //by-pass revision return; } $act = act_clean($ACT); if($act != 'edit') return; if(!file_exists($this->accumulator)) return; $id = $INPUT->str('id'); $id = str_replace(array('/','\\'), ':', $id); $ar = unserialize(file_get_contents($this->accumulator)); $srch = array('__\s*BROKEN-LINK:','LINK-BROKEN\s*__') ; $event->result = preg_replace("#$srch#", "",$event->result); $event->result = str_replace($srch,"",$event->result); if(!empty($ar[$id])) { foreach($ar[$id] as $url) { $this->update_wiki_page($event->result, $url) ; } } //__BROKEN-LINK: __ BROKEN-LINK:[ $event->result = preg_replace('/__\s*BROKEN-LINK:__\s*BROKEN-LINK:/ms', '__ BROKEN-LINK:', $event->result); $event->result = preg_replace('/\s*LINK-BROKEN\s*__\s*LINK-BROKEN\s*__/ms', 'LINK-BROKEN__', $event->result); $event->result = preg_replace('/_*\s*BROKEN-LINK:_*\s*BROKEN-LINK:/ms', '__BROKEN-LINK: ', $event->result); $event->result = preg_replace('/LINK-BROKEN__LINK-BROKEN__/ms', 'LINK-BROKEN__', $event->result); $event->result = preg_replace('/BROKEN-LINK:\s+/ms', 'BROKEN-LINK: ', $event->result); $event->result = preg_replace('/__BROKEN-LINK: \s*_*\s* BROKEN-LINK:/ms','__ BROKEN-LINK:',$event->result); } function update_wiki_page(&$result, $url) { msg(($url) , 2); $this->current = $url; // $result = preg_replace_callback("|(?current) !== false && strpos($matches[0], '-LINK:' . $piece) === false) { if ($matches[1] == '[[') { $link = preg_quote($this->current); $matches[0] = preg_replace("#\[\[($link.*?)\]\]#ms", "__ BROKEN-LINK:[[$1]] LINK-BROKEN __", $matches[0]); } else { $matches[0] = str_replace($piece, "__ BROKEN-LINK:" . $piece . " LINK-BROKEN __", $matches[0]); } } } } return $matches[0]; } , $result); } function handle_wiki_content(Doku_Event $event, $param) { global $ACT; if($ACT == 'preview') { return; } else if($this->getConf('conceal')) { $event->data = preg_replace('#\\s*BROKEN\-LINK\:(.*?)LINK\-BROKEN\s*#',"$3",$event->data); return; } } function handle_page_save(Doku_Event $event, $param) { global $INPUT; $url = $INPUT->str('xtern_url'); if(!isset($url) || empty($url)) return; if($event->data['contentChanged']) return; if(strpos($event->data['newContent'], 'BROKEN-LINK:') !== false) { $event->data['contentChanged'] = true; } } function write_debug($data) { return; $debug_handle=fopen(DOKU_INC.'xtern.txt', 'wb'); if(!$debug_handle) return; fwrite($debug_handle, $data); fclose($debug_handle); } }