1<?php 2/* 3 * This plugin finds phpbb links to a thread or Topic from a speceficboard 4 * and if there is no title set it adds the thread title 5 * 6 * @author Dominik Eckelmann <deckelmann@gmail.com> 7 */ 8 9if(!defined('DOKU_INC')) die(); 10if(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/'); 11if(!defined('DOKU_DATA')) define('DOKU_DATA',DOKU_INC.'data/'); 12 13 14require_once(DOKU_PLUGIN.'action.php'); 15 16class action_plugin_phpbblinks extends DokuWiki_Action_Plugin 17{ 18 19 var $con; 20 var $pre; 21 22 /** 23 * return some info 24 */ 25 function getInfo() 26 { 27 return confToHash(dirname(__FILE__).'/info.txt'); 28 } 29 30 function register(&$controller) 31 { 32 $controller->register_hook('ACTION_ACT_PREPROCESS', 'BEFORE', $this, 'replace', array()); 33 } 34 35 function replace(&$event, $param) 36 { 37 38 // if the action is not save or preview -> we are not interested 39 if (!is_array($event->data)) return false; 40 if ( !isset($event->data['preview']) && !isset($event->data['save'])) 41 { 42 return false; 43 } 44 45 // ignore admin interface 46 global $ACT; 47 if ($ACT == 'admin') 48 { 49 return false; 50 } 51 52 // if not enabled -> return 53 if (!$this->getConf('enable')) 54 { 55 return false; 56 } 57 58 // get the board url 59 $url = $this->_getUrl(); 60 61 // no url given and the plugin has nothing to do 62 if (!$url) 63 { 64 $this->admMsg('No BoardURL is set',-1); 65 return; 66 } 67 68 // no db connection 69 if (!$this->_connect()) 70 { 71 return false; 72 } 73 74 global $TEXT; 75 76 // we take the requested text and split it into pices 77 $text = $TEXT; 78 $textpice = preg_split('/[\s]/',$text); 79 80 // prepare some stuff 81 $urlc = strlen($url); 82 $urla = parse_url($url); 83 $search = array(); 84 $replace = array(); 85 86 // start to check every word 87 foreach ($textpice as $word) 88 { 89 // ignore empty lines 90 if (empty($word)) 91 { 92 continue; 93 } 94 95 // prepare some more stuff 96 $args = array(); 97 $enclose = false; 98 $org = $word; 99 100 // if the word is a link 101 if (substr($word,0,2) == '[[' && substr($word,-2) == ']]' ) 102 { 103 $enclose = true; 104 if (strpos($word,'|')) 105 { 106 // link has already a title - ignore 107 continue; 108 } 109 $word = substr($word,2,-2); 110 if (strlen($word) <= $urlc) 111 { 112 // word is to short to be a real interesting url 113 continue; 114 } 115 if (substr($word,0,$urlc) != $url) 116 { 117 // not the right url 118 continue; 119 } 120 // get url args 121 $pices = parse_url($word); 122 123 124 if (!$pices['query']) 125 { 126 continue; // no args are given 127 } 128 129 // get the args 130 parse_str($pices['query'],$args); 131 } else { 132 $wu = parse_url($word); 133 134 // compare links 135 $same = true; 136 foreach (array('scheme','host','port','user','pass','path') as $k) 137 { 138 if (!isset($urla[$k])) 139 { 140 if (isset($wu[$k])) 141 { 142 $same = false; 143 break; 144 } 145 continue; 146 } 147 if ($wu[$k] != $urla[$k]) 148 { 149 // links are not the same 150 $same = false; 151 break; 152 } 153 } 154 if (!$same) 155 { 156 157 continue; 158 } 159 160 // get the url args 161 parse_str($wu['query'],$args); 162 } 163 164 // args make smbting 165 166 if (isset($args['p'])) 167 { 168 // get post title 169 $p = $args['p']; 170 $txt = $this->_getTopicByPostId($p); 171 if (!$txt) continue; 172 $txt = $this->getConf('linktxt') . $txt; 173 $search[] = '/(\s)?'.str_replace('/','\\/',preg_quote($org)).'(\s)?/'; 174 $replace[] = "\\1[[$url?p=$p#$p|$txt]]\\2"; 175 } 176 elseif (isset($args['t'])) 177 { 178 // get thread title 179 $t = $args['t']; 180 $txt = $this->_getTopicByTopicId($t); 181 if (!$txt) continue; 182 $txt = $this->getConf('linktxt') . $txt; 183 $search[] = '/(\s)?'.str_replace('/','\\/',preg_quote($org)).'(\s)?/'; 184 $replace[] = "\\1[[$url?t=$t|$txt]]\\2"; 185 } 186 else continue; 187 } 188 ksort($search); 189 ksort($replace); 190 $TEXT = preg_replace($search,$replace,$TEXT); 191 192 $this->_disconnect(); 193 } 194 195 function _getUrl() { 196 $url = $this->getConf('boardurl'); 197 if (empty($url)) return false; 198 199 // add a final / 200 201 if (substr($url,-1) != '/') { 202 $url .= '/'; 203 } 204 205 // add the viewtopic file 206 $url .= 'viewtopic.php'; 207 return $url; 208 } 209 210 function _getTopicByTopicId($id) { 211 if (!$this->con) return ''; 212 $q = sprintf( 213 'SELECT topic_title FROM %1$stopics WHERE topic_id=%2$d 214 ',$this->pre,intval($id)); 215 $r = $this->_query($q); 216 if (!$r) return false; 217 $r = $r['topic_title']; 218 return $r; 219 } 220 function _getTopicByPostId($id) { 221 if (!$this->con) return ''; 222 $q = sprintf(' 223 SELECT 224 %1$stopics.topic_title 225 FROM 226 %1$sposts , %1$stopics 227 WHERE 228 %1$sposts.post_id=%2$d AND 229 %1$sposts .topic_id = %1$stopics.topic_id 230 ',$this->pre,intval($id)); 231 $r = $this->_query($q); 232 if (!$r) return false; 233 $r = $r['topic_title']; 234 return $r; 235 } 236 function _connect() { 237 $host = ''; 238 $user = ''; 239 $pass = ''; 240 $dbu = ''; 241 $pre = ''; 242 if ($this->getConf('integration')) 243 { 244 global $conf; 245 global $table_prefix; 246 $host = $conf['auth']['mysql']['server']; 247 $user = $conf['auth']['mysql']['user']; 248 $pass = $conf['auth']['mysql']['password']; 249 $dbu = $conf['auth']['mysql']['database']; 250 $pre = $table_prefix; 251 } 252 else 253 { 254 $host = $this->getConf('host'); 255 $user = $this->getConf('user'); 256 $pass = $this->getConf('pass'); 257 $dbu = $this->getConf('db'); 258 $pre = $this->getConf('pre'); 259 } 260 $this->pre = $pre; 261 $con = @mysql_connect( $host , $user , $pass) or $err = @mysql_error(); 262 if (!$con) 263 { 264 $this->admMsg('Database connection failed '.$err,-1); 265 return false; 266 } 267 $this->con = $con; 268 $db = @mysql_select_db($dbu,$this->con); 269 if ($db) 270 { 271 return true; 272 } 273 $this->admMsg('Database selection failed '.@mysql_error($this->con),-1); 274 return false; 275 } 276 function _disconnect() { 277 mysql_close($this->con); 278 } 279 function _query($q) { 280 $r = @mysql_query($q,$this->con); 281 if (!$r) 282 { 283 $this->admMsg('Database Error '.@mysql_error($this->con),-1); 284 return array(); 285 } 286 $r = mysql_fetch_assoc($r); 287 return $r; 288 } 289 function _esc($s) { 290 return mysql_real_escape_string($s,$this->con); 291 } 292 293 function admMsg($msg,$type=0) 294 { 295 global $INFO; 296 if (!$INFO['isadmin'] && !$INFO['ismanager']) 297 { 298 return; 299 } 300 msg("PHPBBLinks: $msg",$type); 301 } 302} 303 304 305 306?> 307