[ Index ]

PHP Cross Reference of DokuWiki

title

Body

[close]

/inc/ -> Ajax.php (source)

   1  <?php
   2  
   3  namespace dokuwiki;
   4  
   5  /**
   6   * Manage all builtin AJAX calls
   7   *
   8   * @todo The calls should be refactored out to their own proper classes
   9   * @package dokuwiki
  10   */
  11  class Ajax {
  12  
  13      /**
  14       * Execute the given call
  15       *
  16       * @param string $call name of the ajax call
  17       */
  18      public function __construct($call) {
  19          $callfn = 'call_' . $call;
  20          if(method_exists($this, $callfn)) {
  21              $this->$callfn();
  22          } else {
  23              $evt = new \Doku_Event('AJAX_CALL_UNKNOWN', $call);
  24              if($evt->advise_before()) {
  25                  print "AJAX call '" . hsc($call) . "' unknown!\n";
  26              } else {
  27                  $evt->advise_after();
  28                  unset($evt);
  29              }
  30          }
  31      }
  32  
  33      /**
  34       * Searches for matching pagenames
  35       *
  36       * @author Andreas Gohr <andi@splitbrain.org>
  37       */
  38      protected function call_qsearch() {
  39          global $lang;
  40          global $INPUT;
  41  
  42          $maxnumbersuggestions = 50;
  43  
  44          $query = $INPUT->post->str('q');
  45          if(empty($query)) $query = $INPUT->get->str('q');
  46          if(empty($query)) return;
  47  
  48          $query = urldecode($query);
  49  
  50          $data = ft_pageLookup($query, true, useHeading('navigation'));
  51  
  52          if(!count($data)) return;
  53  
  54          print '<strong>' . $lang['quickhits'] . '</strong>';
  55          print '<ul>';
  56          $counter = 0;
  57          foreach($data as $id => $title) {
  58              if(useHeading('navigation')) {
  59                  $name = $title;
  60              } else {
  61                  $ns = getNS($id);
  62                  if($ns) {
  63                      $name = noNS($id) . ' (' . $ns . ')';
  64                  } else {
  65                      $name = $id;
  66                  }
  67              }
  68              echo '<li>' . html_wikilink(':' . $id, $name) . '</li>';
  69  
  70              $counter++;
  71              if($counter > $maxnumbersuggestions) {
  72                  echo '<li>...</li>';
  73                  break;
  74              }
  75          }
  76          print '</ul>';
  77      }
  78  
  79      /**
  80       * Support OpenSearch suggestions
  81       *
  82       * @link   http://www.opensearch.org/Specifications/OpenSearch/Extensions/Suggestions/1.0
  83       * @author Mike Frysinger <vapier@gentoo.org>
  84       */
  85      protected function call_suggestions() {
  86          global $INPUT;
  87  
  88          $query = cleanID($INPUT->post->str('q'));
  89          if(empty($query)) $query = cleanID($INPUT->get->str('q'));
  90          if(empty($query)) return;
  91  
  92          $data = ft_pageLookup($query);
  93          if(!count($data)) return;
  94          $data = array_keys($data);
  95  
  96          // limit results to 15 hits
  97          $data = array_slice($data, 0, 15);
  98          $data = array_map('trim', $data);
  99          $data = array_map('noNS', $data);
 100          $data = array_unique($data);
 101          sort($data);
 102  
 103          /* now construct a json */
 104          $suggestions = array(
 105              $query,  // the original query
 106              $data,   // some suggestions
 107              array(), // no description
 108              array()  // no urls
 109          );
 110          $json = new \JSON();
 111  
 112          header('Content-Type: application/x-suggestions+json');
 113          print $json->encode($suggestions);
 114      }
 115  
 116      /**
 117       * Refresh a page lock and save draft
 118       *
 119       * Andreas Gohr <andi@splitbrain.org>
 120       */
 121      protected function call_lock() {
 122          global $ID;
 123          global $INFO;
 124          global $INPUT;
 125  
 126          $ID = cleanID($INPUT->post->str('id'));
 127          if(empty($ID)) return;
 128  
 129          $INFO = pageinfo();
 130  
 131          $response = [
 132              'errors' => [],
 133              'lock' => '0',
 134              'draft' => '',
 135          ];
 136          if(!$INFO['writable']) {
 137              $response['errors'][] = 'Permission to write this page has been denied.';
 138              echo json_encode($response);
 139              return;
 140          }
 141  
 142          if(!checklock($ID)) {
 143              lock($ID);
 144              $response['lock'] = '1';
 145          }
 146  
 147          $draft = new Draft($ID, $INFO['client']);
 148          if ($draft->saveDraft()) {
 149              $response['draft'] = $draft->getDraftMessage();
 150          } else {
 151              $response['errors'] = array_merge($response['errors'], $draft->getErrors());
 152          }
 153          echo json_encode($response);
 154      }
 155  
 156      /**
 157       * Delete a draft
 158       *
 159       * @author Andreas Gohr <andi@splitbrain.org>
 160       */
 161      protected function call_draftdel() {
 162          global $INPUT;
 163          $id = cleanID($INPUT->str('id'));
 164          if(empty($id)) return;
 165  
 166          $client = $_SERVER['REMOTE_USER'];
 167          if(!$client) $client = clientIP(true);
 168  
 169          $cname = getCacheName($client . $id, '.draft');
 170          @unlink($cname);
 171      }
 172  
 173      /**
 174       * Return subnamespaces for the Mediamanager
 175       *
 176       * @author Andreas Gohr <andi@splitbrain.org>
 177       */
 178      protected function call_medians() {
 179          global $conf;
 180          global $INPUT;
 181  
 182          // wanted namespace
 183          $ns = cleanID($INPUT->post->str('ns'));
 184          $dir = utf8_encodeFN(str_replace(':', '/', $ns));
 185  
 186          $lvl = count(explode(':', $ns));
 187  
 188          $data = array();
 189          search($data, $conf['mediadir'], 'search_index', array('nofiles' => true), $dir);
 190          foreach(array_keys($data) as $item) {
 191              $data[$item]['level'] = $lvl + 1;
 192          }
 193          echo html_buildlist($data, 'idx', 'media_nstree_item', 'media_nstree_li');
 194      }
 195  
 196      /**
 197       * Return list of files for the Mediamanager
 198       *
 199       * @author Andreas Gohr <andi@splitbrain.org>
 200       */
 201      protected function call_medialist() {
 202          global $NS;
 203          global $INPUT;
 204  
 205          $NS = cleanID($INPUT->post->str('ns'));
 206          $sort = $INPUT->post->bool('recent') ? 'date' : 'natural';
 207          if($INPUT->post->str('do') == 'media') {
 208              tpl_mediaFileList();
 209          } else {
 210              tpl_mediaContent(true, $sort);
 211          }
 212      }
 213  
 214      /**
 215       * Return the content of the right column
 216       * (image details) for the Mediamanager
 217       *
 218       * @author Kate Arzamastseva <pshns@ukr.net>
 219       */
 220      protected function call_mediadetails() {
 221          global $IMG, $JUMPTO, $REV, $fullscreen, $INPUT;
 222          $fullscreen = true;
 223          require_once (DOKU_INC . 'lib/exe/mediamanager.php');
 224  
 225          $image = '';
 226          if($INPUT->has('image')) $image = cleanID($INPUT->str('image'));
 227          if(isset($IMG)) $image = $IMG;
 228          if(isset($JUMPTO)) $image = $JUMPTO;
 229          $rev = false;
 230          if(isset($REV) && !$JUMPTO) $rev = $REV;
 231  
 232          html_msgarea();
 233          tpl_mediaFileDetails($image, $rev);
 234      }
 235  
 236      /**
 237       * Returns image diff representation for mediamanager
 238       *
 239       * @author Kate Arzamastseva <pshns@ukr.net>
 240       */
 241      protected function call_mediadiff() {
 242          global $NS;
 243          global $INPUT;
 244  
 245          $image = '';
 246          if($INPUT->has('image')) $image = cleanID($INPUT->str('image'));
 247          $NS = getNS($image);
 248          $auth = auth_quickaclcheck("$NS:*");
 249          media_diff($image, $NS, $auth, true);
 250      }
 251  
 252      /**
 253       * Manages file uploads
 254       *
 255       * @author Kate Arzamastseva <pshns@ukr.net>
 256       */
 257      protected function call_mediaupload() {
 258          global $NS, $MSG, $INPUT;
 259  
 260          $id = '';
 261          if($_FILES['qqfile']['tmp_name']) {
 262              $id = $INPUT->post->str('mediaid', $_FILES['qqfile']['name']);
 263          } elseif($INPUT->get->has('qqfile')) {
 264              $id = $INPUT->get->str('qqfile');
 265          }
 266  
 267          $id = cleanID($id);
 268  
 269          $NS = $INPUT->str('ns');
 270          $ns = $NS . ':' . getNS($id);
 271  
 272          $AUTH = auth_quickaclcheck("$ns:*");
 273          if($AUTH >= AUTH_UPLOAD) {
 274              io_createNamespace("$ns:xxx", 'media');
 275          }
 276  
 277          if($_FILES['qqfile']['error']) unset($_FILES['qqfile']);
 278  
 279          $res = false;
 280          if($_FILES['qqfile']['tmp_name']) $res = media_upload($NS, $AUTH, $_FILES['qqfile']);
 281          if($INPUT->get->has('qqfile')) $res = media_upload_xhr($NS, $AUTH);
 282  
 283          if($res) {
 284              $result = array(
 285                  'success' => true,
 286                  'link' => media_managerURL(array('ns' => $ns, 'image' => $NS . ':' . $id), '&'),
 287                  'id' => $NS . ':' . $id,
 288                  'ns' => $NS
 289              );
 290          } else {
 291              $error = '';
 292              if(isset($MSG)) {
 293                  foreach($MSG as $msg) {
 294                      $error .= $msg['msg'];
 295                  }
 296              }
 297              $result = array(
 298                  'error' => $error,
 299                  'ns' => $NS
 300              );
 301          }
 302          $json = new \JSON;
 303          header('Content-Type: application/json');
 304          echo $json->encode($result);
 305      }
 306  
 307      /**
 308       * Return sub index for index view
 309       *
 310       * @author Andreas Gohr <andi@splitbrain.org>
 311       */
 312      protected function call_index() {
 313          global $conf;
 314          global $INPUT;
 315  
 316          // wanted namespace
 317          $ns = cleanID($INPUT->post->str('idx'));
 318          $dir = utf8_encodeFN(str_replace(':', '/', $ns));
 319  
 320          $lvl = count(explode(':', $ns));
 321  
 322          $data = array();
 323          search($data, $conf['datadir'], 'search_index', array('ns' => $ns), $dir);
 324          foreach(array_keys($data) as $item) {
 325              $data[$item]['level'] = $lvl + 1;
 326          }
 327          echo html_buildlist($data, 'idx', 'html_list_index', 'html_li_index');
 328      }
 329  
 330      /**
 331       * List matching namespaces and pages for the link wizard
 332       *
 333       * @author Andreas Gohr <gohr@cosmocode.de>
 334       */
 335      protected function call_linkwiz() {
 336          global $conf;
 337          global $lang;
 338          global $INPUT;
 339  
 340          $q = ltrim(trim($INPUT->post->str('q')), ':');
 341          $id = noNS($q);
 342          $ns = getNS($q);
 343  
 344          $ns = cleanID($ns);
 345          $id = cleanID($id);
 346  
 347          $nsd = utf8_encodeFN(str_replace(':', '/', $ns));
 348  
 349          $data = array();
 350          if($q && !$ns) {
 351  
 352              // use index to lookup matching pages
 353              $pages = ft_pageLookup($id, true);
 354  
 355              // result contains matches in pages and namespaces
 356              // we now extract the matching namespaces to show
 357              // them seperately
 358              $dirs = array();
 359  
 360              foreach($pages as $pid => $title) {
 361                  if(strpos(noNS($pid), $id) === false) {
 362                      // match was in the namespace
 363                      $dirs[getNS($pid)] = 1; // assoc array avoids dupes
 364                  } else {
 365                      // it is a matching page, add it to the result
 366                      $data[] = array(
 367                          'id' => $pid,
 368                          'title' => $title,
 369                          'type' => 'f',
 370                      );
 371                  }
 372                  unset($pages[$pid]);
 373              }
 374              foreach($dirs as $dir => $junk) {
 375                  $data[] = array(
 376                      'id' => $dir,
 377                      'type' => 'd',
 378                  );
 379              }
 380  
 381          } else {
 382  
 383              $opts = array(
 384                  'depth' => 1,
 385                  'listfiles' => true,
 386                  'listdirs' => true,
 387                  'pagesonly' => true,
 388                  'firsthead' => true,
 389                  'sneakyacl' => $conf['sneaky_index'],
 390              );
 391              if($id) $opts['filematch'] = '^.*\/' . $id;
 392              if($id) $opts['dirmatch'] = '^.*\/' . $id;
 393              search($data, $conf['datadir'], 'search_universal', $opts, $nsd);
 394  
 395              // add back to upper
 396              if($ns) {
 397                  array_unshift(
 398                      $data, array(
 399                               'id' => getNS($ns),
 400                               'type' => 'u',
 401                           )
 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 = hsc($item['id']);
 427              }
 428  
 429              echo '<a href="' . $link . '" title="' . hsc($item['id']) . '" class="wikilink1">' . $name . '</a>';
 430  
 431              if(!blank($item['title'])) {
 432                  echo '<span>' . hsc($item['title']) . '</span>';
 433              }
 434              echo '</div>';
 435          }
 436  
 437      }
 438  
 439  }