1<?php 2/** 3 * DokuWiki AJAX call handler 4 * 5 * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) 6 * @author Andreas Gohr <andi@splitbrain.org> 7 */ 8 9//fix for Opera XMLHttpRequests 10if(!count($_POST) && $HTTP_RAW_POST_DATA){ 11 parse_str($HTTP_RAW_POST_DATA, $_POST); 12} 13 14if(!defined('DOKU_INC')) define('DOKU_INC',dirname(__FILE__).'/../../'); 15require_once(DOKU_INC.'inc/init.php'); 16require_once(DOKU_INC.'inc/common.php'); 17require_once(DOKU_INC.'inc/pageutils.php'); 18require_once(DOKU_INC.'inc/auth.php'); 19//close sesseion 20session_write_close(); 21 22header('Content-Type: text/html; charset=utf-8'); 23 24 25//call the requested function 26if(isset($_POST['call'])) 27 $call = $_POST['call']; 28else if(isset($_GET['call'])) 29 $call = $_GET['call']; 30else 31 exit; 32 33$callfn = 'ajax_'.$call; 34 35if(function_exists($callfn)){ 36 $callfn(); 37}else{ 38 $evt = new Doku_Event('AJAX_CALL_UNKNOWN', $call); 39 if ($evt->advise_before()) { 40 print "AJAX call '".htmlspecialchars($call)."' unknown!\n"; 41 exit; 42 } 43 $evt->advise_after(); 44 unset($evt); 45} 46 47/** 48 * Searches for matching pagenames 49 * 50 * @author Andreas Gohr <andi@splitbrain.org> 51 */ 52function ajax_qsearch(){ 53 global $conf; 54 global $lang; 55 56 $query = cleanID($_POST['q']); 57 if(empty($query)) $query = cleanID($_GET['q']); 58 if(empty($query)) return; 59 60 require_once(DOKU_INC.'inc/html.php'); 61 require_once(DOKU_INC.'inc/fulltext.php'); 62 63 $data = array(); 64 $data = ft_pageLookup($query); 65 66 if(!count($data)) return; 67 68 print '<strong>'.$lang['quickhits'].'</strong>'; 69 print '<ul>'; 70 foreach($data as $id){ 71 print '<li>'; 72 $ns = getNS($id); 73 if($ns){ 74 $name = shorten(noNS($id), ' ('.$ns.')',30); 75 }else{ 76 $name = $id; 77 } 78 print html_wikilink(':'.$id,$name); 79 print '</li>'; 80 } 81 print '</ul>'; 82} 83 84/** 85 * Support OpenSearch suggestions 86 * 87 * @link http://www.opensearch.org/Specifications/OpenSearch/Extensions/Suggestions/1.0 88 * @author Mike Frysinger <vapier@gentoo.org> 89 */ 90function ajax_suggestions() { 91 global $conf; 92 global $lang; 93 94 $query = cleanID($_POST['q']); 95 if(empty($query)) $query = cleanID($_GET['q']); 96 if(empty($query)) return; 97 98 require_once(DOKU_INC.'inc/html.php'); 99 require_once(DOKU_INC.'inc/fulltext.php'); 100 require_once(DOKU_INC.'inc/JSON.php'); 101 102 $data = array(); 103 $data = ft_pageLookup($query); 104 if(!count($data)) return; 105 106 // limit results to 15 hits 107 $data = array_slice($data, 0, 15); 108 $data = array_map('trim',$data); 109 $data = array_map('noNS',$data); 110 $data = array_unique($data); 111 sort($data); 112 113 /* now construct a json */ 114 $suggestions = array( 115 $query, // the original query 116 $data, // some suggestions 117 array(), // no description 118 array() // no urls 119 ); 120 $json = new JSON(); 121 122 header('Content-Type: application/x-suggestions+json'); 123 print $json->encode($suggestions); 124} 125 126/** 127 * Refresh a page lock and save draft 128 * 129 * Andreas Gohr <andi@splitbrain.org> 130 */ 131function ajax_lock(){ 132 global $conf; 133 global $lang; 134 $id = cleanID($_POST['id']); 135 if(empty($id)) return; 136 137 if(!checklock($id)){ 138 lock($id); 139 echo 1; 140 } 141 142 if($conf['usedraft'] && $_POST['wikitext']){ 143 $client = $_SERVER['REMOTE_USER']; 144 if(!$client) $client = clientIP(true); 145 146 $draft = array('id' => $id, 147 'prefix' => $_POST['prefix'], 148 'text' => $_POST['wikitext'], 149 'suffix' => $_POST['suffix'], 150 'date' => $_POST['date'], 151 'client' => $client, 152 ); 153 $cname = getCacheName($draft['client'].$id,'.draft'); 154 if(io_saveFile($cname,serialize($draft))){ 155 echo $lang['draftdate'].' '.strftime($conf['dformat']); 156 } 157 } 158 159} 160 161/** 162 * Delete a draft 163 * 164 * @author Andreas Gohr <andi@splitbrain.org> 165 */ 166function ajax_draftdel(){ 167 $id = cleanID($_POST['id']); 168 if(empty($id)) return; 169 170 $client = $_SERVER['REMOTE_USER']; 171 if(!$client) $client = clientIP(true); 172 173 $cname = getCacheName($client.$id,'.draft'); 174 @unlink($cname); 175} 176 177/** 178 * Return subnamespaces for the Mediamanager 179 * 180 * @author Andreas Gohr <andi@splitbrain.org> 181 */ 182function ajax_medians(){ 183 global $conf; 184 require_once(DOKU_INC.'inc/search.php'); 185 require_once(DOKU_INC.'inc/media.php'); 186 187 // wanted namespace 188 $ns = cleanID($_POST['ns']); 189 $dir = utf8_encodeFN(str_replace(':','/',$ns)); 190 191 $lvl = count(explode(':',$ns)); 192 193 $data = array(); 194 search($data,$conf['mediadir'],'search_index',array('nofiles' => true),$dir); 195 foreach($data as $item){ 196 $item['level'] = $lvl+1; 197 echo media_nstree_li($item); 198 echo media_nstree_item($item); 199 echo '</li>'; 200 } 201} 202 203/** 204 * Return list of files for the Mediamanager 205 * 206 * @author Andreas Gohr <andi@splitbrain.org> 207 */ 208function ajax_medialist(){ 209 global $conf; 210 global $NS; 211 require_once(DOKU_INC.'inc/media.php'); 212 require_once(DOKU_INC.'inc/template.php'); 213 214 $NS = $_POST['ns']; 215 tpl_mediaContent(true); 216} 217 218/** 219 * Return list of search result for the Mediamanager 220 * 221 * @author Tobias Sarnowski <sarnowski@cosmocode.de> 222 */ 223function ajax_mediasearchlist(){ 224 global $conf; 225 require_once(DOKU_INC.'inc/media.php'); 226 227 media_searchlist($_POST['ns']); 228} 229 230/** 231 * Return sub index for index view 232 * 233 * @author Andreas Gohr <andi@splitbrain.org> 234 */ 235function ajax_index(){ 236 global $conf; 237 require_once(DOKU_INC.'inc/search.php'); 238 require_once(DOKU_INC.'inc/html.php'); 239 240 // wanted namespace 241 $ns = cleanID($_POST['idx']); 242 $dir = utf8_encodeFN(str_replace(':','/',$ns)); 243 244 $lvl = count(explode(':',$ns)); 245 246 $data = array(); 247 search($data,$conf['datadir'],'search_index',array('ns' => $ns),$dir); 248 foreach($data as $item){ 249 $item['level'] = $lvl+1; 250 echo html_li_index($item); 251 echo '<div class="li">'; 252 echo html_list_index($item); 253 echo '</div>'; 254 echo '</li>'; 255 } 256} 257 258/** 259 * List matching namespaces and pages for the link wizard 260 * 261 * @author Andreas Gohr <gohr@cosmocode.de> 262 */ 263function ajax_linkwiz(){ 264 global $conf; 265 global $lang; 266 require_once(DOKU_INC.'inc/html.php'); 267 268 $q = ltrim($_POST['q'],':'); 269 $id = noNS($q); 270 $ns = getNS($q); 271 272 $ns = cleanID($ns); 273 $id = cleanID($id); 274 275 $nsd = utf8_encodeFN(str_replace(':','/',$ns)); 276 $idd = utf8_encodeFN(str_replace(':','/',$id)); 277 278 $data = array(); 279 if($q && !$ns){ 280 281 // use index to lookup matching pages 282 require_once(DOKU_INC.'inc/fulltext.php'); 283 require_once(DOKU_INC.'inc/parserutils.php'); 284 $pages = array(); 285 $pages = ft_pageLookup($id,false); 286 287 // result contains matches in pages and namespaces 288 // we now extract the matching namespaces to show 289 // them seperately 290 $dirs = array(); 291 $count = count($pages); 292 for($i=0; $i<$count; $i++){ 293 if(strpos(noNS($pages[$i]),$id) === false){ 294 // match was in the namespace 295 $dirs[getNS($pages[$i])] = 1; // assoc array avoids dupes 296 }else{ 297 // it is a matching page, add it to the result 298 $data[] = array( 299 'id' => $pages[$i], 300 'title' => p_get_first_heading($pages[$i],false), 301 'type' => 'f', 302 ); 303 } 304 unset($pages[$i]); 305 } 306 foreach($dirs as $dir => $junk){ 307 $data[] = array( 308 'id' => $dir, 309 'type' => 'd', 310 ); 311 } 312 313 }else{ 314 315 require_once(DOKU_INC.'inc/search.php'); 316 $opts = array( 317 'depth' => 1, 318 'listfiles' => true, 319 'listdirs' => true, 320 'pagesonly' => true, 321 'firsthead' => true, 322 ); 323 if($id) $opts['filematch'] = '^.*\/'.$id; 324 if($id) $opts['dirmatch'] = '^.*\/'.$id; 325 search($data,$conf['datadir'],'search_universal',$opts,$nsd); 326 327 // add back to upper 328 if($ns){ 329 array_unshift($data,array( 330 'id' => getNS($ns), 331 'type' => 'u', 332 )); 333 } 334 } 335 336 // fixme sort results in a useful way ? 337 338 if(!count($data)){ 339 echo $lang['nothingfound']; 340 exit; 341 } 342 343 // output the found data 344 $even = 1; 345 foreach($data as $item){ 346 $even *= -1; //zebra 347 348 if(($item['type'] == 'd' || $item['type'] == 'u') && $item['id']) $item['id'] .= ':'; 349 $link = wl($item['id']); 350 351 echo '<div class="'.(($even > 0)?'even':'odd').' type_'.$item['type'].'">'; 352 353 354 if($item['type'] == 'u'){ 355 $name = $lang['upperns']; 356 }else{ 357 $name = htmlspecialchars($item['id']); 358 } 359 360 echo '<a href="'.$link.'" title="'.htmlspecialchars($item['id']).'" class="wikilink1">'.$name.'</a>'; 361 362 if($item['title']){ 363 echo '<span>'.htmlspecialchars($item['title']).'</span>'; 364 } 365 echo '</div>'; 366 } 367 368} 369 370//Setup VIM: ex: et ts=2 enc=utf-8 : 371