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