[ Index ]

PHP Cross Reference of DokuWiki

title

Body

[close]

/inc/ -> Ajax.php (source)

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