116a367d4SAndreas Gohr<?php 216a367d4SAndreas Gohr 316a367d4SAndreas Gohrnamespace dokuwiki; 416a367d4SAndreas Gohr 524870174SAndreas Gohruse dokuwiki\Extension\Event; 624870174SAndreas Gohruse dokuwiki\Ui\MediaDiff; 724870174SAndreas Gohruse dokuwiki\Ui\Index; 89c8632b4SSatoshi Saharause dokuwiki\Ui; 92d85e841SAndreas Gohruse dokuwiki\Utf8\Sort; 109c8632b4SSatoshi Sahara 1116a367d4SAndreas Gohr/** 1216a367d4SAndreas Gohr * Manage all builtin AJAX calls 1316a367d4SAndreas Gohr * 1416a367d4SAndreas Gohr * @todo The calls should be refactored out to their own proper classes 1516a367d4SAndreas Gohr * @package dokuwiki 1616a367d4SAndreas Gohr */ 178c7c53b0SAndreas Gohrclass Ajax 188c7c53b0SAndreas Gohr{ 1916a367d4SAndreas Gohr /** 2016a367d4SAndreas Gohr * Execute the given call 2116a367d4SAndreas Gohr * 2216a367d4SAndreas Gohr * @param string $call name of the ajax call 2316a367d4SAndreas Gohr */ 24d868eb89SAndreas Gohr public function __construct($call) 25d868eb89SAndreas Gohr { 262ed72d06SAndreas Gohr $callfn = 'call' . ucfirst($call); 2716a367d4SAndreas Gohr if (method_exists($this, $callfn)) { 2816a367d4SAndreas Gohr $this->$callfn(); 2916a367d4SAndreas Gohr } else { 3024870174SAndreas Gohr $evt = new Event('AJAX_CALL_UNKNOWN', $call); 3116a367d4SAndreas Gohr if ($evt->advise_before()) { 32*26dfc232SAndreas Gohr echo "AJAX call '" . hsc($call) . "' unknown!\n"; 3316a367d4SAndreas Gohr } else { 3416a367d4SAndreas Gohr $evt->advise_after(); 3516a367d4SAndreas Gohr unset($evt); 3616a367d4SAndreas Gohr } 3716a367d4SAndreas Gohr } 3816a367d4SAndreas Gohr } 3916a367d4SAndreas Gohr 4016a367d4SAndreas Gohr /** 4116a367d4SAndreas Gohr * Searches for matching pagenames 4216a367d4SAndreas Gohr * 4316a367d4SAndreas Gohr * @author Andreas Gohr <andi@splitbrain.org> 4416a367d4SAndreas Gohr */ 45d868eb89SAndreas Gohr protected function callQsearch() 46d868eb89SAndreas Gohr { 4716a367d4SAndreas Gohr global $lang; 4816a367d4SAndreas Gohr global $INPUT; 4916a367d4SAndreas Gohr 5016a367d4SAndreas Gohr $maxnumbersuggestions = 50; 5116a367d4SAndreas Gohr 5216a367d4SAndreas Gohr $query = $INPUT->post->str('q'); 5316a367d4SAndreas Gohr if (empty($query)) $query = $INPUT->get->str('q'); 5416a367d4SAndreas Gohr if (empty($query)) return; 5516a367d4SAndreas Gohr 5616a367d4SAndreas Gohr $query = urldecode($query); 5716a367d4SAndreas Gohr 5816a367d4SAndreas Gohr $data = ft_pageLookup($query, true, useHeading('navigation')); 5916a367d4SAndreas Gohr 6024870174SAndreas Gohr if ($data === []) return; 6116a367d4SAndreas Gohr 62*26dfc232SAndreas Gohr echo '<strong>' . $lang['quickhits'] . '</strong>'; 63*26dfc232SAndreas Gohr echo '<ul>'; 6416a367d4SAndreas Gohr $counter = 0; 6516a367d4SAndreas Gohr foreach ($data as $id => $title) { 6616a367d4SAndreas Gohr if (useHeading('navigation')) { 6716a367d4SAndreas Gohr $name = $title; 6816a367d4SAndreas Gohr } else { 6916a367d4SAndreas Gohr $ns = getNS($id); 7016a367d4SAndreas Gohr if ($ns) { 7116a367d4SAndreas Gohr $name = noNS($id) . ' (' . $ns . ')'; 7216a367d4SAndreas Gohr } else { 7316a367d4SAndreas Gohr $name = $id; 7416a367d4SAndreas Gohr } 7516a367d4SAndreas Gohr } 7616a367d4SAndreas Gohr echo '<li>' . html_wikilink(':' . $id, $name) . '</li>'; 7716a367d4SAndreas Gohr 7816a367d4SAndreas Gohr $counter++; 7916a367d4SAndreas Gohr if ($counter > $maxnumbersuggestions) { 8016a367d4SAndreas Gohr echo '<li>...</li>'; 8116a367d4SAndreas Gohr break; 8216a367d4SAndreas Gohr } 8316a367d4SAndreas Gohr } 84*26dfc232SAndreas Gohr echo '</ul>'; 8516a367d4SAndreas Gohr } 8616a367d4SAndreas Gohr 8716a367d4SAndreas Gohr /** 8816a367d4SAndreas Gohr * Support OpenSearch suggestions 8916a367d4SAndreas Gohr * 9016a367d4SAndreas Gohr * @link http://www.opensearch.org/Specifications/OpenSearch/Extensions/Suggestions/1.0 9116a367d4SAndreas Gohr * @author Mike Frysinger <vapier@gentoo.org> 9216a367d4SAndreas Gohr */ 93d868eb89SAndreas Gohr protected function callSuggestions() 94d868eb89SAndreas Gohr { 9516a367d4SAndreas Gohr global $INPUT; 9616a367d4SAndreas Gohr 9716a367d4SAndreas Gohr $query = cleanID($INPUT->post->str('q')); 9816a367d4SAndreas Gohr if (empty($query)) $query = cleanID($INPUT->get->str('q')); 9916a367d4SAndreas Gohr if (empty($query)) return; 10016a367d4SAndreas Gohr 10116a367d4SAndreas Gohr $data = ft_pageLookup($query); 10224870174SAndreas Gohr if ($data === []) return; 10316a367d4SAndreas Gohr $data = array_keys($data); 10416a367d4SAndreas Gohr 10516a367d4SAndreas Gohr // limit results to 15 hits 10616a367d4SAndreas Gohr $data = array_slice($data, 0, 15); 10716a367d4SAndreas Gohr $data = array_map('trim', $data); 10816a367d4SAndreas Gohr $data = array_map('noNS', $data); 10916a367d4SAndreas Gohr $data = array_unique($data); 1102d85e841SAndreas Gohr Sort::sort($data); 11116a367d4SAndreas Gohr 11216a367d4SAndreas Gohr /* now construct a json */ 11324870174SAndreas Gohr $suggestions = [ 11416a367d4SAndreas Gohr $query, // the original query 11516a367d4SAndreas Gohr $data, // some suggestions 11624870174SAndreas Gohr [], // no description 11724870174SAndreas Gohr [], // no urls 11824870174SAndreas Gohr ]; 11916a367d4SAndreas Gohr 12016a367d4SAndreas Gohr header('Content-Type: application/x-suggestions+json'); 121*26dfc232SAndreas Gohr echo json_encode($suggestions, JSON_THROW_ON_ERROR); 12216a367d4SAndreas Gohr } 12316a367d4SAndreas Gohr 12416a367d4SAndreas Gohr /** 12516a367d4SAndreas Gohr * Refresh a page lock and save draft 12616a367d4SAndreas Gohr * 12716a367d4SAndreas Gohr * Andreas Gohr <andi@splitbrain.org> 12816a367d4SAndreas Gohr */ 129d868eb89SAndreas Gohr protected function callLock() 130d868eb89SAndreas Gohr { 13116a367d4SAndreas Gohr global $ID; 13216a367d4SAndreas Gohr global $INFO; 13316a367d4SAndreas Gohr global $INPUT; 13416a367d4SAndreas Gohr 13516a367d4SAndreas Gohr $ID = cleanID($INPUT->post->str('id')); 13616a367d4SAndreas Gohr if (empty($ID)) return; 13716a367d4SAndreas Gohr 13816a367d4SAndreas Gohr $INFO = pageinfo(); 13916a367d4SAndreas Gohr 140b16fbc3fSMichael Große $response = [ 141b16fbc3fSMichael Große 'errors' => [], 142b16fbc3fSMichael Große 'lock' => '0', 143b16fbc3fSMichael Große 'draft' => '', 144b16fbc3fSMichael Große ]; 14516a367d4SAndreas Gohr if (!$INFO['writable']) { 146b16fbc3fSMichael Große $response['errors'][] = 'Permission to write this page has been denied.'; 147b16fbc3fSMichael Große echo json_encode($response); 14816a367d4SAndreas Gohr return; 14916a367d4SAndreas Gohr } 15016a367d4SAndreas Gohr 15116a367d4SAndreas Gohr if (!checklock($ID)) { 15216a367d4SAndreas Gohr lock($ID); 153b16fbc3fSMichael Große $response['lock'] = '1'; 15416a367d4SAndreas Gohr } 15516a367d4SAndreas Gohr 1560aabe6f8SMichael Große $draft = new Draft($ID, $INFO['client']); 1570aabe6f8SMichael Große if ($draft->saveDraft()) { 158b16fbc3fSMichael Große $response['draft'] = $draft->getDraftMessage(); 159b16fbc3fSMichael Große } else { 160b16fbc3fSMichael Große $response['errors'] = array_merge($response['errors'], $draft->getErrors()); 16116a367d4SAndreas Gohr } 16224870174SAndreas Gohr echo json_encode($response, JSON_THROW_ON_ERROR); 16316a367d4SAndreas Gohr } 16416a367d4SAndreas Gohr 16516a367d4SAndreas Gohr /** 16616a367d4SAndreas Gohr * Delete a draft 16716a367d4SAndreas Gohr * 16816a367d4SAndreas Gohr * @author Andreas Gohr <andi@splitbrain.org> 16916a367d4SAndreas Gohr */ 170d868eb89SAndreas Gohr protected function callDraftdel() 171d868eb89SAndreas Gohr { 17216a367d4SAndreas Gohr global $INPUT; 17316a367d4SAndreas Gohr $id = cleanID($INPUT->str('id')); 17416a367d4SAndreas Gohr if (empty($id)) return; 17516a367d4SAndreas Gohr 1762b9be456SAndreas Gohr $client = $INPUT->server->str('REMOTE_USER'); 17716a367d4SAndreas Gohr if (!$client) $client = clientIP(true); 17816a367d4SAndreas Gohr 17924201594SAndreas Gohr $draft = new Draft($id, $client); 18024201594SAndreas Gohr if ($draft->isDraftAvailable() && checkSecurityToken()) { 18124201594SAndreas Gohr $draft->deleteDraft(); 18224201594SAndreas Gohr } 18316a367d4SAndreas Gohr } 18416a367d4SAndreas Gohr 18516a367d4SAndreas Gohr /** 18616a367d4SAndreas Gohr * Return subnamespaces for the Mediamanager 18716a367d4SAndreas Gohr * 18816a367d4SAndreas Gohr * @author Andreas Gohr <andi@splitbrain.org> 18916a367d4SAndreas Gohr */ 190d868eb89SAndreas Gohr protected function callMedians() 191d868eb89SAndreas Gohr { 19216a367d4SAndreas Gohr global $conf; 19316a367d4SAndreas Gohr global $INPUT; 19416a367d4SAndreas Gohr 19516a367d4SAndreas Gohr // wanted namespace 19616a367d4SAndreas Gohr $ns = cleanID($INPUT->post->str('ns')); 19716a367d4SAndreas Gohr $dir = utf8_encodeFN(str_replace(':', '/', $ns)); 19816a367d4SAndreas Gohr 19916a367d4SAndreas Gohr $lvl = count(explode(':', $ns)); 20016a367d4SAndreas Gohr 20124870174SAndreas Gohr $data = []; 20224870174SAndreas Gohr search($data, $conf['mediadir'], 'search_index', ['nofiles' => true], $dir); 20316a367d4SAndreas Gohr foreach (array_keys($data) as $item) { 20416a367d4SAndreas Gohr $data[$item]['level'] = $lvl + 1; 20516a367d4SAndreas Gohr } 20616a367d4SAndreas Gohr echo html_buildlist($data, 'idx', 'media_nstree_item', 'media_nstree_li'); 20716a367d4SAndreas Gohr } 20816a367d4SAndreas Gohr 20916a367d4SAndreas Gohr /** 21016a367d4SAndreas Gohr * Return list of files for the Mediamanager 21116a367d4SAndreas Gohr * 21216a367d4SAndreas Gohr * @author Andreas Gohr <andi@splitbrain.org> 21316a367d4SAndreas Gohr */ 214d868eb89SAndreas Gohr protected function callMedialist() 215d868eb89SAndreas Gohr { 21616a367d4SAndreas Gohr global $NS; 21716a367d4SAndreas Gohr global $INPUT; 21816a367d4SAndreas Gohr 21916a367d4SAndreas Gohr $NS = cleanID($INPUT->post->str('ns')); 22016a367d4SAndreas Gohr $sort = $INPUT->post->bool('recent') ? 'date' : 'natural'; 22116a367d4SAndreas Gohr if ($INPUT->post->str('do') == 'media') { 22216a367d4SAndreas Gohr tpl_mediaFileList(); 22316a367d4SAndreas Gohr } else { 22416a367d4SAndreas Gohr tpl_mediaContent(true, $sort); 22516a367d4SAndreas Gohr } 22616a367d4SAndreas Gohr } 22716a367d4SAndreas Gohr 22816a367d4SAndreas Gohr /** 22916a367d4SAndreas Gohr * Return the content of the right column 23016a367d4SAndreas Gohr * (image details) for the Mediamanager 23116a367d4SAndreas Gohr * 23216a367d4SAndreas Gohr * @author Kate Arzamastseva <pshns@ukr.net> 23316a367d4SAndreas Gohr */ 234d868eb89SAndreas Gohr protected function callMediadetails() 235d868eb89SAndreas Gohr { 23616a367d4SAndreas Gohr global $IMG, $JUMPTO, $REV, $fullscreen, $INPUT; 23716a367d4SAndreas Gohr $fullscreen = true; 23816a367d4SAndreas Gohr require_once(DOKU_INC . 'lib/exe/mediamanager.php'); 23916a367d4SAndreas Gohr 24016a367d4SAndreas Gohr $image = ''; 24116a367d4SAndreas Gohr if ($INPUT->has('image')) $image = cleanID($INPUT->str('image')); 24216a367d4SAndreas Gohr if (isset($IMG)) $image = $IMG; 24316a367d4SAndreas Gohr if (isset($JUMPTO)) $image = $JUMPTO; 24416a367d4SAndreas Gohr $rev = false; 24516a367d4SAndreas Gohr if (isset($REV) && !$JUMPTO) $rev = $REV; 24616a367d4SAndreas Gohr 24716a367d4SAndreas Gohr html_msgarea(); 24816a367d4SAndreas Gohr tpl_mediaFileDetails($image, $rev); 24916a367d4SAndreas Gohr } 25016a367d4SAndreas Gohr 25116a367d4SAndreas Gohr /** 25216a367d4SAndreas Gohr * Returns image diff representation for mediamanager 25316a367d4SAndreas Gohr * 25416a367d4SAndreas Gohr * @author Kate Arzamastseva <pshns@ukr.net> 25516a367d4SAndreas Gohr */ 256d868eb89SAndreas Gohr protected function callMediadiff() 257d868eb89SAndreas Gohr { 25816a367d4SAndreas Gohr global $INPUT; 25916a367d4SAndreas Gohr 26016a367d4SAndreas Gohr $image = ''; 26116a367d4SAndreas Gohr if ($INPUT->has('image')) $image = cleanID($INPUT->str('image')); 26224870174SAndreas Gohr (new MediaDiff($image))->preference('fromAjax', true)->show(); 26316a367d4SAndreas Gohr } 26416a367d4SAndreas Gohr 26516a367d4SAndreas Gohr /** 26616a367d4SAndreas Gohr * Manages file uploads 26716a367d4SAndreas Gohr * 26816a367d4SAndreas Gohr * @author Kate Arzamastseva <pshns@ukr.net> 26916a367d4SAndreas Gohr */ 270d868eb89SAndreas Gohr protected function callMediaupload() 271d868eb89SAndreas Gohr { 27216a367d4SAndreas Gohr global $NS, $MSG, $INPUT; 27316a367d4SAndreas Gohr 27416a367d4SAndreas Gohr $id = ''; 275aac83cd4SPhy if (isset($_FILES['qqfile']['tmp_name'])) { 27616a367d4SAndreas Gohr $id = $INPUT->post->str('mediaid', $_FILES['qqfile']['name']); 27716a367d4SAndreas Gohr } elseif ($INPUT->get->has('qqfile')) { 27816a367d4SAndreas Gohr $id = $INPUT->get->str('qqfile'); 27916a367d4SAndreas Gohr } 28016a367d4SAndreas Gohr 28116a367d4SAndreas Gohr $id = cleanID($id); 28216a367d4SAndreas Gohr 28316a367d4SAndreas Gohr $NS = $INPUT->str('ns'); 28416a367d4SAndreas Gohr $ns = $NS . ':' . getNS($id); 28516a367d4SAndreas Gohr 28616a367d4SAndreas Gohr $AUTH = auth_quickaclcheck("$ns:*"); 28716a367d4SAndreas Gohr if ($AUTH >= AUTH_UPLOAD) { 28816a367d4SAndreas Gohr io_createNamespace("$ns:xxx", 'media'); 28916a367d4SAndreas Gohr } 29016a367d4SAndreas Gohr 291aac83cd4SPhy if (isset($_FILES['qqfile']['error']) && $_FILES['qqfile']['error']) unset($_FILES['qqfile']); 29216a367d4SAndreas Gohr 29316a367d4SAndreas Gohr $res = false; 29468491db9SPhy if (isset($_FILES['qqfile']['tmp_name'])) $res = media_upload($NS, $AUTH, $_FILES['qqfile']); 29516a367d4SAndreas Gohr if ($INPUT->get->has('qqfile')) $res = media_upload_xhr($NS, $AUTH); 29616a367d4SAndreas Gohr 29716a367d4SAndreas Gohr if ($res) { 29824870174SAndreas Gohr $result = [ 29916a367d4SAndreas Gohr 'success' => true, 30024870174SAndreas Gohr 'link' => media_managerURL(['ns' => $ns, 'image' => $NS . ':' . $id], '&'), 30116a367d4SAndreas Gohr 'id' => $NS . ':' . $id, 30216a367d4SAndreas Gohr 'ns' => $NS 30324870174SAndreas Gohr ]; 30416a367d4SAndreas Gohr } else { 30516a367d4SAndreas Gohr $error = ''; 30616a367d4SAndreas Gohr if (isset($MSG)) { 30716a367d4SAndreas Gohr foreach ($MSG as $msg) { 30816a367d4SAndreas Gohr $error .= $msg['msg']; 30916a367d4SAndreas Gohr } 31016a367d4SAndreas Gohr } 31124870174SAndreas Gohr $result = ['error' => $error, 'ns' => $NS]; 31216a367d4SAndreas Gohr } 313d443762bSAndreas Gohr 31416a367d4SAndreas Gohr header('Content-Type: application/json'); 31524870174SAndreas Gohr echo json_encode($result, JSON_THROW_ON_ERROR); 31616a367d4SAndreas Gohr } 31716a367d4SAndreas Gohr 31816a367d4SAndreas Gohr /** 31916a367d4SAndreas Gohr * Return sub index for index view 32016a367d4SAndreas Gohr * 32116a367d4SAndreas Gohr * @author Andreas Gohr <andi@splitbrain.org> 32216a367d4SAndreas Gohr */ 323d868eb89SAndreas Gohr protected function callIndex() 324d868eb89SAndreas Gohr { 32516a367d4SAndreas Gohr global $conf; 32616a367d4SAndreas Gohr global $INPUT; 32716a367d4SAndreas Gohr 32816a367d4SAndreas Gohr // wanted namespace 32916a367d4SAndreas Gohr $ns = cleanID($INPUT->post->str('idx')); 33016a367d4SAndreas Gohr $dir = utf8_encodeFN(str_replace(':', '/', $ns)); 33116a367d4SAndreas Gohr 33216a367d4SAndreas Gohr $lvl = count(explode(':', $ns)); 33316a367d4SAndreas Gohr 33424870174SAndreas Gohr $data = []; 33524870174SAndreas Gohr search($data, $conf['datadir'], 'search_index', ['ns' => $ns], $dir); 33616a367d4SAndreas Gohr foreach (array_keys($data) as $item) { 33716a367d4SAndreas Gohr $data[$item]['level'] = $lvl + 1; 33816a367d4SAndreas Gohr } 33973022918SAndreas Gohr $idx = new Index(); 340d11e205cSSatoshi Sahara echo html_buildlist($data, 'idx', [$idx,'formatListItem'], [$idx,'tagListItem']); 34116a367d4SAndreas Gohr } 34216a367d4SAndreas Gohr 34316a367d4SAndreas Gohr /** 34416a367d4SAndreas Gohr * List matching namespaces and pages for the link wizard 34516a367d4SAndreas Gohr * 34616a367d4SAndreas Gohr * @author Andreas Gohr <gohr@cosmocode.de> 34716a367d4SAndreas Gohr */ 348d868eb89SAndreas Gohr protected function callLinkwiz() 349d868eb89SAndreas Gohr { 35016a367d4SAndreas Gohr global $conf; 35116a367d4SAndreas Gohr global $lang; 35216a367d4SAndreas Gohr global $INPUT; 35316a367d4SAndreas Gohr 35416a367d4SAndreas Gohr $q = ltrim(trim($INPUT->post->str('q')), ':'); 35516a367d4SAndreas Gohr $id = noNS($q); 35616a367d4SAndreas Gohr $ns = getNS($q); 35716a367d4SAndreas Gohr 35816a367d4SAndreas Gohr $ns = cleanID($ns); 35924870174SAndreas Gohr 36016a367d4SAndreas Gohr $id = cleanID($id); 36116a367d4SAndreas Gohr 36216a367d4SAndreas Gohr $nsd = utf8_encodeFN(str_replace(':', '/', $ns)); 36316a367d4SAndreas Gohr 36424870174SAndreas Gohr $data = []; 3655d27cd14SPhy if ($q !== '' && $ns === '') { 36616a367d4SAndreas Gohr // use index to lookup matching pages 36716a367d4SAndreas Gohr $pages = ft_pageLookup($id, true); 36816a367d4SAndreas Gohr 3692aa917afSalexdraconian // If 'useheading' option is 'always' or 'content', 3702aa917afSalexdraconian // search page titles with original query as well. 371fd260edfSalexdraconian if ($conf['useheading'] == '1' || $conf['useheading'] == 'content') { 3722aa917afSalexdraconian $pages = array_merge($pages, ft_pageLookup($q, true, true)); 3732aa917afSalexdraconian asort($pages, SORT_STRING); 3744668fa19Salexdraconian } 37516a367d4SAndreas Gohr 37616a367d4SAndreas Gohr // result contains matches in pages and namespaces 37716a367d4SAndreas Gohr // we now extract the matching namespaces to show 37816a367d4SAndreas Gohr // them seperately 37924870174SAndreas Gohr $dirs = []; 38016a367d4SAndreas Gohr 38116a367d4SAndreas Gohr foreach ($pages as $pid => $title) { 3823c4b22e8Salexdraconian if (strpos(getNS($pid), $id) !== false) { 38316a367d4SAndreas Gohr // match was in the namespace 38416a367d4SAndreas Gohr $dirs[getNS($pid)] = 1; // assoc array avoids dupes 38516a367d4SAndreas Gohr } else { 38616a367d4SAndreas Gohr // it is a matching page, add it to the result 38724870174SAndreas Gohr $data[] = ['id' => $pid, 'title' => $title, 'type' => 'f']; 38816a367d4SAndreas Gohr } 38916a367d4SAndreas Gohr unset($pages[$pid]); 39016a367d4SAndreas Gohr } 39124870174SAndreas Gohr foreach (array_keys($dirs) as $dir) { 39224870174SAndreas Gohr $data[] = ['id' => $dir, 'type' => 'd']; 39316a367d4SAndreas Gohr } 39416a367d4SAndreas Gohr } else { 39524870174SAndreas Gohr $opts = [ 39616a367d4SAndreas Gohr 'depth' => 1, 39716a367d4SAndreas Gohr 'listfiles' => true, 39816a367d4SAndreas Gohr 'listdirs' => true, 39916a367d4SAndreas Gohr 'pagesonly' => true, 40016a367d4SAndreas Gohr 'firsthead' => true, 40124870174SAndreas Gohr 'sneakyacl' => $conf['sneaky_index'] 40224870174SAndreas Gohr ]; 40316a367d4SAndreas Gohr if ($id) $opts['filematch'] = '^.*\/' . $id; 40416a367d4SAndreas Gohr if ($id) $opts['dirmatch'] = '^.*\/' . $id; 40516a367d4SAndreas Gohr search($data, $conf['datadir'], 'search_universal', $opts, $nsd); 40616a367d4SAndreas Gohr 40716a367d4SAndreas Gohr // add back to upper 40816a367d4SAndreas Gohr if ($ns) { 40916a367d4SAndreas Gohr array_unshift( 410dccd6b2bSAndreas Gohr $data, 411dccd6b2bSAndreas Gohr ['id' => getNS($ns), 'type' => 'u'] 41216a367d4SAndreas Gohr ); 41316a367d4SAndreas Gohr } 41416a367d4SAndreas Gohr } 41516a367d4SAndreas Gohr 41616a367d4SAndreas Gohr // fixme sort results in a useful way ? 41716a367d4SAndreas Gohr 41816a367d4SAndreas Gohr if (!count($data)) { 41916a367d4SAndreas Gohr echo $lang['nothingfound']; 42016a367d4SAndreas Gohr exit; 42116a367d4SAndreas Gohr } 42216a367d4SAndreas Gohr 42316a367d4SAndreas Gohr // output the found data 42416a367d4SAndreas Gohr $even = 1; 42516a367d4SAndreas Gohr foreach ($data as $item) { 42616a367d4SAndreas Gohr $even *= -1; //zebra 42716a367d4SAndreas Gohr 42873f05217SPhy if (($item['type'] == 'd' || $item['type'] == 'u') && $item['id'] !== '') $item['id'] .= ':'; 42916a367d4SAndreas Gohr $link = wl($item['id']); 43016a367d4SAndreas Gohr 43116a367d4SAndreas Gohr echo '<div class="' . (($even > 0) ? 'even' : 'odd') . ' type_' . $item['type'] . '">'; 43216a367d4SAndreas Gohr 43316a367d4SAndreas Gohr if ($item['type'] == 'u') { 43416a367d4SAndreas Gohr $name = $lang['upperns']; 43516a367d4SAndreas Gohr } else { 43616a367d4SAndreas Gohr $name = hsc($item['id']); 43716a367d4SAndreas Gohr } 43816a367d4SAndreas Gohr 43916a367d4SAndreas Gohr echo '<a href="' . $link . '" title="' . hsc($item['id']) . '" class="wikilink1">' . $name . '</a>'; 44016a367d4SAndreas Gohr 44116a367d4SAndreas Gohr if (!blank($item['title'])) { 44216a367d4SAndreas Gohr echo '<span>' . hsc($item['title']) . '</span>'; 44316a367d4SAndreas Gohr } 44416a367d4SAndreas Gohr echo '</div>'; 44516a367d4SAndreas Gohr } 44616a367d4SAndreas Gohr } 44716a367d4SAndreas Gohr} 448