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 require_once(DOKU_INC.'inc/media.php'); 211 212 media_filelist($_POST['ns']); 213} 214 215/** 216 * Return sub index for index view 217 * 218 * @author Andreas Gohr <andi@splitbrain.org> 219 */ 220function ajax_index(){ 221 global $conf; 222 require_once(DOKU_INC.'inc/search.php'); 223 require_once(DOKU_INC.'inc/html.php'); 224 225 // wanted namespace 226 $ns = cleanID($_POST['idx']); 227 $dir = utf8_encodeFN(str_replace(':','/',$ns)); 228 229 $lvl = count(explode(':',$ns)); 230 231 $data = array(); 232 search($data,$conf['datadir'],'search_index',array('ns' => $ns),$dir); 233 foreach($data as $item){ 234 $item['level'] = $lvl+1; 235 echo html_li_index($item); 236 echo '<div class="li">'; 237 echo html_list_index($item); 238 echo '</div>'; 239 echo '</li>'; 240 } 241} 242 243/** 244 * List matching namespaces and pages for the link wizard 245 */ 246function ajax_linkwiz(){ 247 global $conf; 248 global $lang; 249 require_once(DOKU_INC.'inc/html.php'); 250 251 $q = ltrim($_POST['q'],':'); 252 $id = noNS($q); 253 $ns = getNS($q); 254 255 $ns = cleanID($ns); 256 $id = cleanID($id); 257 258 $nsd = utf8_encodeFN(str_replace(':','/',$ns)); 259 $idd = utf8_encodeFN(str_replace(':','/',$id)); 260 261 $data = array(); 262 if($q && !$ns){ 263 264 // use index to lookup matching pages 265 require_once(DOKU_INC.'inc/fulltext.php'); 266 require_once(DOKU_INC.'inc/parserutils.php'); 267 $pages = array(); 268 $pages = ft_pageLookup($id,false); 269 270 // result contains matches in pages and namespaces 271 // we now extract the matching namespaces to show 272 // them seperately 273 $dirs = array(); 274 $count = count($pages); 275 for($i=0; $i<$count; $i++){ 276 if(strpos(noNS($pages[$i]),$id) === false){ 277 // match was in the namespace 278 $dirs[getNS($pages[$i])] = 1; // assoc array avoids dupes 279 }else{ 280 // it is a matching page, add it to the result 281 $data[] = array( 282 'id' => $pages[$i], 283 'title' => p_get_first_heading($pages[$i],false), 284 'type' => 'f', 285 ); 286 } 287 unset($pages[$i]); 288 } 289 foreach($dirs as $dir => $junk){ 290 $data[] = array( 291 'id' => $dir, 292 'type' => 'd', 293 ); 294 } 295 296 }else{ 297 298 require_once(DOKU_INC.'inc/search.php'); 299 $opts = array( 300 'depth' => 1, 301 'listfiles' => true, 302 'listdirs' => true, 303 'pagesonly' => true, 304 'firsthead' => true, 305 ); 306 if($id) $opts['filematch'] = '^.*\/'.$id; 307 if($id) $opts['dirmatch'] = '^.*\/'.$id; 308 search($data,$conf['datadir'],'search_universal',$opts,$nsd); 309 310 // add back to upper 311 if($ns){ 312 array_unshift($data,array( 313 'id' => getNS($ns), 314 'type' => 'u', 315 )); 316 } 317 } 318 319 // fixme sort results in a useful way ? 320 321 if(!count($data)){ 322 echo $lang['nothingfound']; 323 exit; 324 } 325 326 // output the found data 327 $even = 1; 328 foreach($data as $item){ 329 $even *= -1; //zebra 330 331 if(($item['type'] == 'd' || $item['type'] == 'u') && $item['id']) $item['id'] .= ':'; 332 $link = wl($item['id']); 333 334 echo '<div class="'.(($even > 0)?'even':'odd').' type_'.$item['type'].'">'; 335 336 337 if($item['type'] == 'u'){ 338 $name = 'back to upper'; 339 }else{ 340 $name = htmlspecialchars($item['id']); 341 } 342 343 echo '<a href="'.$link.'" title="'.htmlspecialchars($item['id']).'" class="wikilink1">'.$name.'</a>'; 344 345 if($item['title']){ 346 echo '<span>'.htmlspecialchars($item['title']).'</span>'; 347 } 348 echo '</div>'; 349 } 350 351} 352 353//Setup VIM: ex: et ts=2 enc=utf-8 : 354