[ 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' . ucfirst($call);
  20          if(method_exists($this, $callfn)) {
  21              $this->$callfn();
  22          } else {
  23              $evt = new Extension\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 callQsearch() {
  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 callSuggestions() {
  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  
 111          header('Content-Type: application/x-suggestions+json');
 112          print json_encode($suggestions);
 113      }
 114  
 115      /**
 116       * Refresh a page lock and save draft
 117       *
 118       * Andreas Gohr <andi@splitbrain.org>
 119       */
 120      protected function callLock() {
 121          global $ID;
 122          global $INFO;
 123          global $INPUT;
 124  
 125          $ID = cleanID($INPUT->post->str('id'));
 126          if(empty($ID)) return;
 127  
 128          $INFO = pageinfo();
 129  
 130          $response = [
 131              'errors' => [],
 132              'lock' => '0',
 133              'draft' => '',
 134          ];
 135          if(!$INFO['writable']) {
 136              $response['errors'][] = 'Permission to write this page has been denied.';
 137              echo json_encode($response);
 138              return;
 139          }
 140  
 141          if(!checklock($ID)) {
 142              lock($ID);
 143              $response['lock'] = '1';
 144          }
 145  
 146          $draft = new Draft($ID, $INFO['client']);
 147          if ($draft->saveDraft()) {
 148              $response['draft'] = $draft->getDraftMessage();
 149          } else {
 150              $response['errors'] = array_merge($response['errors'], $draft->getErrors());
 151          }
 152          echo json_encode($response);
 153      }
 154  
 155      /**
 156       * Delete a draft
 157       *
 158       * @author Andreas Gohr <andi@splitbrain.org>
 159       */
 160      protected function callDraftdel() {
 161          global $INPUT;
 162          $id = cleanID($INPUT->str('id'));
 163          if(empty($id)) return;
 164  
 165          $client = $_SERVER['REMOTE_USER'];
 166          if(!$client) $client = clientIP(true);
 167  
 168          $cname = getCacheName($client . $id, '.draft');
 169          @unlink($cname);
 170      }
 171  
 172      /**
 173       * Return subnamespaces for the Mediamanager
 174       *
 175       * @author Andreas Gohr <andi@splitbrain.org>
 176       */
 177      protected function callMedians() {
 178          global $conf;
 179          global $INPUT;
 180  
 181          // wanted namespace
 182          $ns = cleanID($INPUT->post->str('ns'));
 183          $dir = utf8_encodeFN(str_replace(':', '/', $ns));
 184  
 185          $lvl = count(explode(':', $ns));
 186  
 187          $data = array();
 188          search($data, $conf['mediadir'], 'search_index', array('nofiles' => true), $dir);
 189          foreach(array_keys($data) as $item) {
 190              $data[$item]['level'] = $lvl + 1;
 191          }
 192          echo html_buildlist($data, 'idx', 'media_nstree_item', 'media_nstree_li');
 193      }
 194  
 195      /**
 196       * Return list of files for the Mediamanager
 197       *
 198       * @author Andreas Gohr <andi@splitbrain.org>
 199       */
 200      protected function callMedialist() {
 201          global $NS;
 202          global $INPUT;
 203  
 204          $NS = cleanID($INPUT->post->str('ns'));
 205          $sort = $INPUT->post->bool('recent') ? 'date' : 'natural';
 206          if($INPUT->post->str('do') == 'media') {
 207              tpl_mediaFileList();
 208          } else {
 209              tpl_mediaContent(true, $sort);
 210          }
 211      }
 212  
 213      /**
 214       * Return the content of the right column
 215       * (image details) for the Mediamanager
 216       *
 217       * @author Kate Arzamastseva <pshns@ukr.net>
 218       */
 219      protected function callMediadetails() {
 220          global $IMG, $JUMPTO, $REV, $fullscreen, $INPUT;
 221          $fullscreen = true;
 222          require_once (DOKU_INC . 'lib/exe/mediamanager.php');
 223  
 224          $image = '';
 225          if($INPUT->has('image')) $image = cleanID($INPUT->str('image'));
 226          if(isset($IMG)) $image = $IMG;
 227          if(isset($JUMPTO)) $image = $JUMPTO;
 228          $rev = false;
 229          if(isset($REV) && !$JUMPTO) $rev = $REV;
 230  
 231          html_msgarea();
 232          tpl_mediaFileDetails($image, $rev);
 233      }
 234  
 235      /**
 236       * Returns image diff representation for mediamanager
 237       *
 238       * @author Kate Arzamastseva <pshns@ukr.net>
 239       */
 240      protected function callMediadiff() {
 241          global $NS;
 242          global $INPUT;
 243  
 244          $image = '';
 245          if($INPUT->has('image')) $image = cleanID($INPUT->str('image'));
 246          $NS = getNS($image);
 247          $auth = auth_quickaclcheck("$NS:*");
 248          media_diff($image, $NS, $auth, true);
 249      }
 250  
 251      /**
 252       * Manages file uploads
 253       *
 254       * @author Kate Arzamastseva <pshns@ukr.net>
 255       */
 256      protected function callMediaupload() {
 257          global $NS, $MSG, $INPUT;
 258  
 259          $id = '';
 260          if($_FILES['qqfile']['tmp_name']) {
 261              $id = $INPUT->post->str('mediaid', $_FILES['qqfile']['name']);
 262          } elseif($INPUT->get->has('qqfile')) {
 263              $id = $INPUT->get->str('qqfile');
 264          }
 265  
 266          $id = cleanID($id);
 267  
 268          $NS = $INPUT->str('ns');
 269          $ns = $NS . ':' . getNS($id);
 270  
 271          $AUTH = auth_quickaclcheck("$ns:*");
 272          if($AUTH >= AUTH_UPLOAD) {
 273              io_createNamespace("$ns:xxx", 'media');
 274          }
 275  
 276          if($_FILES['qqfile']['error']) unset($_FILES['qqfile']);
 277  
 278          $res = false;
 279          if($_FILES['qqfile']['tmp_name']) $res = media_upload($NS, $AUTH, $_FILES['qqfile']);
 280          if($INPUT->get->has('qqfile')) $res = media_upload_xhr($NS, $AUTH);
 281  
 282          if($res) {
 283              $result = array(
 284                  'success' => true,
 285                  'link' => media_managerURL(array('ns' => $ns, 'image' => $NS . ':' . $id), '&'),
 286                  'id' => $NS . ':' . $id,
 287                  'ns' => $NS
 288              );
 289          } else {
 290              $error = '';
 291              if(isset($MSG)) {
 292                  foreach($MSG as $msg) {
 293                      $error .= $msg['msg'];
 294                  }
 295              }
 296              $result = array(
 297                  'error' => $error,
 298                  'ns' => $NS
 299              );
 300          }
 301  
 302          header('Content-Type: application/json');
 303          echo json_encode($result);
 304      }
 305  
 306      /**
 307       * Return sub index for index view
 308       *
 309       * @author Andreas Gohr <andi@splitbrain.org>
 310       */
 311      protected function callIndex() {
 312          global $conf;
 313          global $INPUT;
 314  
 315          // wanted namespace
 316          $ns = cleanID($INPUT->post->str('idx'));
 317          $dir = utf8_encodeFN(str_replace(':', '/', $ns));
 318  
 319          $lvl = count(explode(':', $ns));
 320  
 321          $data = array();
 322          search($data, $conf['datadir'], 'search_index', array('ns' => $ns), $dir);
 323          foreach(array_keys($data) as $item) {
 324              $data[$item]['level'] = $lvl + 1;
 325          }
 326          echo html_buildlist($data, 'idx', 'html_list_index', 'html_li_index');
 327      }
 328  
 329      /**
 330       * List matching namespaces and pages for the link wizard
 331       *
 332       * @author Andreas Gohr <gohr@cosmocode.de>
 333       */
 334      protected function callLinkwiz() {
 335          global $conf;
 336          global $lang;
 337          global $INPUT;
 338  
 339          $q = ltrim(trim($INPUT->post->str('q')), ':');
 340          $id = noNS($q);
 341          $ns = getNS($q);
 342  
 343          $ns = cleanID($ns);
 344          $id = cleanID($id);
 345  
 346          $nsd = utf8_encodeFN(str_replace(':', '/', $ns));
 347  
 348          $data = array();
 349          if($q && !$ns) {
 350  
 351              // use index to lookup matching pages
 352              $pages = ft_pageLookup($id, true);
 353  
 354              // result contains matches in pages and namespaces
 355              // we now extract the matching namespaces to show
 356              // them seperately
 357              $dirs = array();
 358  
 359              foreach($pages as $pid => $title) {
 360                  if(strpos(noNS($pid), $id) === false) {
 361                      // match was in the namespace
 362                      $dirs[getNS($pid)] = 1; // assoc array avoids dupes
 363                  } else {
 364                      // it is a matching page, add it to the result
 365                      $data[] = array(
 366                          'id' => $pid,
 367                          'title' => $title,
 368                          'type' => 'f',
 369                      );
 370                  }
 371                  unset($pages[$pid]);
 372              }
 373              foreach($dirs as $dir => $junk) {
 374                  $data[] = array(
 375                      'id' => $dir,
 376                      'type' => 'd',
 377                  );
 378              }
 379  
 380          } else {
 381  
 382              $opts = array(
 383                  'depth' => 1,
 384                  'listfiles' => true,
 385                  'listdirs' => true,
 386                  'pagesonly' => true,
 387                  'firsthead' => true,
 388                  'sneakyacl' => $conf['sneaky_index'],
 389              );
 390              if($id) $opts['filematch'] = '^.*\/' . $id;
 391              if($id) $opts['dirmatch'] = '^.*\/' . $id;
 392              search($data, $conf['datadir'], 'search_universal', $opts, $nsd);
 393  
 394              // add back to upper
 395              if($ns) {
 396                  array_unshift(
 397                      $data, array(
 398                               'id' => getNS($ns),
 399                               'type' => 'u',
 400                           )
 401                  );
 402              }
 403          }
 404  
 405          // fixme sort results in a useful way ?
 406  
 407          if(!count($data)) {
 408              echo $lang['nothingfound'];
 409              exit;
 410          }
 411  
 412          // output the found data
 413          $even = 1;
 414          foreach($data as $item) {
 415              $even *= -1; //zebra
 416  
 417              if(($item['type'] == 'd' || $item['type'] == 'u') && $item['id'] !== '') $item['id'] .= ':';
 418              $link = wl($item['id']);
 419  
 420              echo '<div class="' . (($even > 0) ? 'even' : 'odd') . ' type_' . $item['type'] . '">';
 421  
 422              if($item['type'] == 'u') {
 423                  $name = $lang['upperns'];
 424              } else {
 425                  $name = hsc($item['id']);
 426              }
 427  
 428              echo '<a href="' . $link . '" title="' . hsc($item['id']) . '" class="wikilink1">' . $name . '</a>';
 429  
 430              if(!blank($item['title'])) {
 431                  echo '<span>' . hsc($item['title']) . '</span>';
 432              }
 433              echo '</div>';
 434          }
 435  
 436      }
 437  
 438  }