splitbrain /
dokuwiki
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
| 1 | <?php |
||
| 2 | /** |
||
| 3 | * DokuWiki AJAX call handler |
||
| 4 | * |
||
| 5 | * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) |
||
| 6 | * @author Andreas Gohr <[email protected]> |
||
| 7 | */ |
||
| 8 | |||
| 9 | if(!defined('DOKU_INC')) define('DOKU_INC',dirname(__FILE__).'/../../'); |
||
| 10 | require_once(DOKU_INC.'inc/init.php'); |
||
| 11 | //close session |
||
| 12 | session_write_close(); |
||
| 13 | |||
| 14 | header('Content-Type: text/html; charset=utf-8'); |
||
| 15 | |||
| 16 | //call the requested function |
||
| 17 | if($INPUT->post->has('call')){ |
||
| 18 | $call = $INPUT->post->str('call'); |
||
| 19 | }else if($INPUT->get->has('call')){ |
||
| 20 | $call = $INPUT->get->str('call'); |
||
| 21 | }else{ |
||
| 22 | exit; |
||
| 23 | } |
||
| 24 | $callfn = 'ajax_'.$call; |
||
| 25 | |||
| 26 | if(function_exists($callfn)){ |
||
| 27 | $callfn(); |
||
| 28 | }else{ |
||
| 29 | $evt = new Doku_Event('AJAX_CALL_UNKNOWN', $call); |
||
| 30 | if ($evt->advise_before()) { |
||
| 31 | print "AJAX call '".htmlspecialchars($call)."' unknown!\n"; |
||
| 32 | exit; |
||
| 33 | } |
||
| 34 | $evt->advise_after(); |
||
| 35 | unset($evt); |
||
| 36 | } |
||
| 37 | |||
| 38 | /** |
||
| 39 | * Searches for matching pagenames |
||
| 40 | * |
||
| 41 | * @author Andreas Gohr <[email protected]> |
||
| 42 | */ |
||
| 43 | function ajax_qsearch(){ |
||
| 44 | global $lang; |
||
| 45 | global $INPUT; |
||
| 46 | |||
| 47 | $maxnumbersuggestions = 50; |
||
| 48 | |||
| 49 | $query = $INPUT->post->str('q'); |
||
| 50 | if(empty($query)) $query = $INPUT->get->str('q'); |
||
| 51 | if(empty($query)) return; |
||
| 52 | |||
| 53 | $query = urldecode($query); |
||
| 54 | |||
| 55 | $data = ft_pageLookup($query, true, useHeading('navigation')); |
||
| 56 | |||
| 57 | if(!count($data)) return; |
||
| 58 | |||
| 59 | print '<strong>'.$lang['quickhits'].'</strong>'; |
||
| 60 | print '<ul>'; |
||
| 61 | $counter = 0; |
||
| 62 | foreach($data as $id => $title){ |
||
| 63 | if (useHeading('navigation')) { |
||
| 64 | $name = $title; |
||
| 65 | } else { |
||
| 66 | $ns = getNS($id); |
||
| 67 | if($ns){ |
||
| 68 | $name = noNS($id).' ('.$ns.')'; |
||
| 69 | }else{ |
||
| 70 | $name = $id; |
||
| 71 | } |
||
| 72 | } |
||
| 73 | echo '<li>' . html_wikilink(':'.$id,$name) . '</li>'; |
||
| 74 | |||
| 75 | $counter ++; |
||
| 76 | if($counter > $maxnumbersuggestions) { |
||
| 77 | echo '<li>...</li>'; |
||
| 78 | break; |
||
| 79 | } |
||
| 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 <[email protected]> |
||
| 89 | */ |
||
| 90 | function ajax_suggestions() { |
||
| 91 | global $INPUT; |
||
| 92 | |||
| 93 | $query = cleanID($INPUT->post->str('q')); |
||
| 94 | if(empty($query)) $query = cleanID($INPUT->get->str('q')); |
||
| 95 | if(empty($query)) return; |
||
| 96 | |||
| 97 | $data = ft_pageLookup($query); |
||
| 98 | if(!count($data)) return; |
||
| 99 | $data = array_keys($data); |
||
| 100 | |||
| 101 | // limit results to 15 hits |
||
| 102 | $data = array_slice($data, 0, 15); |
||
| 103 | $data = array_map('trim',$data); |
||
| 104 | $data = array_map('noNS',$data); |
||
| 105 | $data = array_unique($data); |
||
| 106 | sort($data); |
||
| 107 | |||
| 108 | /* now construct a json */ |
||
| 109 | $suggestions = array( |
||
| 110 | $query, // the original query |
||
| 111 | $data, // some suggestions |
||
| 112 | array(), // no description |
||
| 113 | array() // no urls |
||
| 114 | ); |
||
| 115 | $json = new JSON(); |
||
| 116 | |||
| 117 | header('Content-Type: application/x-suggestions+json'); |
||
| 118 | print $json->encode($suggestions); |
||
| 119 | } |
||
| 120 | |||
| 121 | /** |
||
| 122 | * Refresh a page lock and save draft |
||
| 123 | * |
||
| 124 | * Andreas Gohr <[email protected]> |
||
| 125 | */ |
||
| 126 | function ajax_lock(){ |
||
| 127 | global $conf; |
||
| 128 | global $lang; |
||
| 129 | global $ID; |
||
| 130 | global $INFO; |
||
| 131 | global $INPUT; |
||
| 132 | |||
| 133 | $ID = cleanID($INPUT->post->str('id')); |
||
| 134 | if(empty($ID)) return; |
||
| 135 | |||
| 136 | $INFO = pageinfo(); |
||
| 137 | |||
| 138 | if (!$INFO['writable']) { |
||
| 139 | echo 'Permission denied'; |
||
| 140 | return; |
||
| 141 | } |
||
| 142 | |||
| 143 | if(!checklock($ID)){ |
||
| 144 | lock($ID); |
||
| 145 | echo 1; |
||
| 146 | } |
||
| 147 | |||
| 148 | if($conf['usedraft'] && $INPUT->post->str('wikitext')){ |
||
| 149 | $client = $_SERVER['REMOTE_USER']; |
||
| 150 | if(!$client) $client = clientIP(true); |
||
| 151 | |||
| 152 | $draft = array('id' => $ID, |
||
| 153 | 'prefix' => substr($INPUT->post->str('prefix'), 0, -1), |
||
| 154 | 'text' => $INPUT->post->str('wikitext'), |
||
| 155 | 'suffix' => $INPUT->post->str('suffix'), |
||
| 156 | 'date' => $INPUT->post->int('date'), |
||
| 157 | 'client' => $client, |
||
| 158 | ); |
||
| 159 | $cname = getCacheName($draft['client'].$ID,'.draft'); |
||
| 160 | if(io_saveFile($cname,serialize($draft))){ |
||
| 161 | echo $lang['draftdate'].' '.dformat(); |
||
| 162 | } |
||
| 163 | } |
||
| 164 | |||
| 165 | } |
||
| 166 | |||
| 167 | /** |
||
| 168 | * Delete a draft |
||
| 169 | * |
||
| 170 | * @author Andreas Gohr <[email protected]> |
||
| 171 | */ |
||
| 172 | function ajax_draftdel(){ |
||
| 173 | global $INPUT; |
||
| 174 | $id = cleanID($INPUT->str('id')); |
||
| 175 | if(empty($id)) return; |
||
| 176 | |||
| 177 | $client = $_SERVER['REMOTE_USER']; |
||
| 178 | if(!$client) $client = clientIP(true); |
||
| 179 | |||
| 180 | $cname = getCacheName($client.$id,'.draft'); |
||
| 181 | @unlink($cname); |
||
| 182 | } |
||
| 183 | |||
| 184 | /** |
||
| 185 | * Return subnamespaces for the Mediamanager |
||
| 186 | * |
||
| 187 | * @author Andreas Gohr <[email protected]> |
||
| 188 | */ |
||
| 189 | function ajax_medians(){ |
||
| 190 | global $conf; |
||
| 191 | global $INPUT; |
||
| 192 | |||
| 193 | // wanted namespace |
||
| 194 | $ns = cleanID($INPUT->post->str('ns')); |
||
| 195 | $dir = utf8_encodeFN(str_replace(':','/',$ns)); |
||
| 196 | |||
| 197 | $lvl = count(explode(':',$ns)); |
||
| 198 | |||
| 199 | $data = array(); |
||
| 200 | search($data,$conf['mediadir'],'search_index',array('nofiles' => true),$dir); |
||
| 201 | foreach(array_keys($data) as $item){ |
||
| 202 | $data[$item]['level'] = $lvl+1; |
||
| 203 | } |
||
| 204 | echo html_buildlist($data, 'idx', 'media_nstree_item', 'media_nstree_li'); |
||
| 205 | } |
||
| 206 | |||
| 207 | /** |
||
| 208 | * Return list of files for the Mediamanager |
||
| 209 | * |
||
| 210 | * @author Andreas Gohr <[email protected]> |
||
| 211 | */ |
||
| 212 | function ajax_medialist(){ |
||
| 213 | global $NS; |
||
| 214 | global $INPUT; |
||
| 215 | |||
| 216 | $NS = cleanID($INPUT->post->str('ns')); |
||
| 217 | $sort = $INPUT->post->bool('recent') ? 'date' : 'natural'; |
||
| 218 | if ($INPUT->post->str('do') == 'media') { |
||
| 219 | tpl_mediaFileList(); |
||
| 220 | } else { |
||
| 221 | tpl_mediaContent(true, $sort); |
||
| 222 | } |
||
| 223 | } |
||
| 224 | |||
| 225 | /** |
||
| 226 | * Return the content of the right column |
||
| 227 | * (image details) for the Mediamanager |
||
| 228 | * |
||
| 229 | * @author Kate Arzamastseva <[email protected]> |
||
| 230 | */ |
||
| 231 | function ajax_mediadetails(){ |
||
| 232 | global $IMG, $JUMPTO, $REV, $fullscreen, $INPUT; |
||
| 233 | $fullscreen = true; |
||
| 234 | require_once(DOKU_INC.'lib/exe/mediamanager.php'); |
||
| 235 | |||
| 236 | $image = ''; |
||
| 237 | if ($INPUT->has('image')) $image = cleanID($INPUT->str('image')); |
||
| 238 | if (isset($IMG)) $image = $IMG; |
||
| 239 | if (isset($JUMPTO)) $image = $JUMPTO; |
||
| 240 | $rev = false; |
||
| 241 | if (isset($REV) && !$JUMPTO) $rev = $REV; |
||
| 242 | |||
| 243 | html_msgarea(); |
||
| 244 | tpl_mediaFileDetails($image, $rev); |
||
| 245 | } |
||
| 246 | |||
| 247 | /** |
||
| 248 | * Returns image diff representation for mediamanager |
||
| 249 | * @author Kate Arzamastseva <[email protected]> |
||
| 250 | */ |
||
| 251 | function ajax_mediadiff(){ |
||
| 252 | global $NS; |
||
| 253 | global $INPUT; |
||
| 254 | |||
| 255 | $image = ''; |
||
| 256 | if ($INPUT->has('image')) $image = cleanID($INPUT->str('image')); |
||
| 257 | $NS = getNS($image); |
||
| 258 | $auth = auth_quickaclcheck("$NS:*"); |
||
| 259 | media_diff($image, $NS, $auth, true); |
||
|
0 ignored issues
–
show
|
|||
| 260 | } |
||
| 261 | |||
| 262 | function ajax_mediaupload(){ |
||
| 263 | global $NS, $MSG, $INPUT; |
||
| 264 | |||
| 265 | $id = ''; |
||
| 266 | if ($_FILES['qqfile']['tmp_name']) { |
||
| 267 | $id = $INPUT->post->str('mediaid', $_FILES['qqfile']['name']); |
||
| 268 | } elseif ($INPUT->get->has('qqfile')) { |
||
| 269 | $id = $INPUT->get->str('qqfile'); |
||
| 270 | } |
||
| 271 | |||
| 272 | $id = cleanID($id); |
||
| 273 | |||
| 274 | $NS = $INPUT->str('ns'); |
||
| 275 | $ns = $NS.':'.getNS($id); |
||
| 276 | |||
| 277 | $AUTH = auth_quickaclcheck("$ns:*"); |
||
| 278 | if($AUTH >= AUTH_UPLOAD) { io_createNamespace("$ns:xxx", 'media'); } |
||
| 279 | |||
| 280 | if ($_FILES['qqfile']['error']) unset($_FILES['qqfile']); |
||
| 281 | |||
| 282 | $res = false; |
||
| 283 | if ($_FILES['qqfile']['tmp_name']) $res = media_upload($NS, $AUTH, $_FILES['qqfile']); |
||
| 284 | if ($INPUT->get->has('qqfile')) $res = media_upload_xhr($NS, $AUTH); |
||
| 285 | |||
| 286 | if($res) { |
||
| 287 | $result = array( |
||
| 288 | 'success' => true, |
||
| 289 | 'link' => media_managerURL(array('ns' => $ns, 'image' => $NS . ':' . $id), '&'), |
||
| 290 | 'id' => $NS . ':' . $id, |
||
| 291 | 'ns' => $NS |
||
| 292 | ); |
||
| 293 | } else { |
||
| 294 | $error = ''; |
||
| 295 | if(isset($MSG)) { |
||
| 296 | foreach($MSG as $msg) { |
||
| 297 | $error .= $msg['msg']; |
||
| 298 | } |
||
| 299 | } |
||
| 300 | $result = array( |
||
| 301 | 'error' => $error, |
||
| 302 | 'ns' => $NS |
||
| 303 | ); |
||
| 304 | } |
||
| 305 | $json = new JSON; |
||
| 306 | echo htmlspecialchars($json->encode($result), ENT_NOQUOTES); |
||
| 307 | } |
||
| 308 | |||
| 309 | /** |
||
| 310 | * Return sub index for index view |
||
| 311 | * |
||
| 312 | * @author Andreas Gohr <[email protected]> |
||
| 313 | */ |
||
| 314 | function ajax_index(){ |
||
| 315 | global $conf; |
||
| 316 | global $INPUT; |
||
| 317 | |||
| 318 | // wanted namespace |
||
| 319 | $ns = cleanID($INPUT->post->str('idx')); |
||
| 320 | $dir = utf8_encodeFN(str_replace(':','/',$ns)); |
||
| 321 | |||
| 322 | $lvl = count(explode(':',$ns)); |
||
| 323 | |||
| 324 | $data = array(); |
||
| 325 | search($data,$conf['datadir'],'search_index',array('ns' => $ns),$dir); |
||
| 326 | foreach(array_keys($data) as $item){ |
||
| 327 | $data[$item]['level'] = $lvl+1; |
||
| 328 | } |
||
| 329 | echo html_buildlist($data, 'idx', 'html_list_index', 'html_li_index'); |
||
| 330 | } |
||
| 331 | |||
| 332 | /** |
||
| 333 | * List matching namespaces and pages for the link wizard |
||
| 334 | * |
||
| 335 | * @author Andreas Gohr <[email protected]> |
||
| 336 | */ |
||
| 337 | function ajax_linkwiz(){ |
||
| 338 | global $conf; |
||
| 339 | global $lang; |
||
| 340 | global $INPUT; |
||
| 341 | |||
| 342 | $q = ltrim(trim($INPUT->post->str('q')),':'); |
||
| 343 | $id = noNS($q); |
||
| 344 | $ns = getNS($q); |
||
| 345 | |||
| 346 | $ns = cleanID($ns); |
||
| 347 | $id = cleanID($id); |
||
| 348 | |||
| 349 | $nsd = utf8_encodeFN(str_replace(':','/',$ns)); |
||
| 350 | |||
| 351 | $data = array(); |
||
| 352 | if($q && !$ns){ |
||
| 353 | |||
| 354 | // use index to lookup matching pages |
||
| 355 | $pages = ft_pageLookup($id,true); |
||
| 356 | |||
| 357 | // result contains matches in pages and namespaces |
||
| 358 | // we now extract the matching namespaces to show |
||
| 359 | // them seperately |
||
| 360 | $dirs = array(); |
||
| 361 | |||
| 362 | foreach($pages as $pid => $title){ |
||
| 363 | if(strpos(noNS($pid),$id) === false){ |
||
| 364 | // match was in the namespace |
||
| 365 | $dirs[getNS($pid)] = 1; // assoc array avoids dupes |
||
| 366 | }else{ |
||
| 367 | // it is a matching page, add it to the result |
||
| 368 | $data[] = array( |
||
| 369 | 'id' => $pid, |
||
| 370 | 'title' => $title, |
||
| 371 | 'type' => 'f', |
||
| 372 | ); |
||
| 373 | } |
||
| 374 | unset($pages[$pid]); |
||
| 375 | } |
||
| 376 | foreach($dirs as $dir => $junk){ |
||
| 377 | $data[] = array( |
||
| 378 | 'id' => $dir, |
||
| 379 | 'type' => 'd', |
||
| 380 | ); |
||
| 381 | } |
||
| 382 | |||
| 383 | }else{ |
||
| 384 | |||
| 385 | $opts = array( |
||
| 386 | 'depth' => 1, |
||
| 387 | 'listfiles' => true, |
||
| 388 | 'listdirs' => true, |
||
| 389 | 'pagesonly' => true, |
||
| 390 | 'firsthead' => true, |
||
| 391 | 'sneakyacl' => $conf['sneaky_index'], |
||
| 392 | ); |
||
| 393 | if($id) $opts['filematch'] = '^.*\/'.$id; |
||
| 394 | if($id) $opts['dirmatch'] = '^.*\/'.$id; |
||
| 395 | search($data,$conf['datadir'],'search_universal',$opts,$nsd); |
||
| 396 | |||
| 397 | // add back to upper |
||
| 398 | if($ns){ |
||
| 399 | array_unshift($data,array( |
||
| 400 | 'id' => getNS($ns), |
||
| 401 | 'type' => 'u', |
||
| 402 | )); |
||
| 403 | } |
||
| 404 | } |
||
| 405 | |||
| 406 | // fixme sort results in a useful way ? |
||
| 407 | |||
| 408 | if(!count($data)){ |
||
| 409 | echo $lang['nothingfound']; |
||
| 410 | exit; |
||
| 411 | } |
||
| 412 | |||
| 413 | // output the found data |
||
| 414 | $even = 1; |
||
| 415 | foreach($data as $item){ |
||
| 416 | $even *= -1; //zebra |
||
| 417 | |||
| 418 | if(($item['type'] == 'd' || $item['type'] == 'u') && $item['id']) $item['id'] .= ':'; |
||
| 419 | $link = wl($item['id']); |
||
| 420 | |||
| 421 | echo '<div class="'.(($even > 0)?'even':'odd').' type_'.$item['type'].'">'; |
||
| 422 | |||
| 423 | if($item['type'] == 'u'){ |
||
| 424 | $name = $lang['upperns']; |
||
| 425 | }else{ |
||
| 426 | $name = htmlspecialchars($item['id']); |
||
| 427 | } |
||
| 428 | |||
| 429 | echo '<a href="'.$link.'" title="'.htmlspecialchars($item['id']).'" class="wikilink1">'.$name.'</a>'; |
||
| 430 | |||
| 431 | if($item['title']){ |
||
| 432 | echo '<span>'.htmlspecialchars($item['title']).'</span>'; |
||
| 433 | } |
||
| 434 | echo '</div>'; |
||
| 435 | } |
||
| 436 | |||
| 437 | } |
||
| 438 | |||
| 439 | //Setup VIM: ex: et ts=2 : |
||
| 440 |
This check looks for type mismatches where the missing type is
false. This is usually indicative of an error condtion.Consider the follow example
This function either returns a new
DateTimeobject or false, if there was an error. This is a typical pattern in PHP programming to show that an error has occurred without raising an exception. The calling code should check for this returnedfalsebefore passing on the value to another function or method that may not be able to handle afalse.