116a367d4SAndreas Gohr<?php 216a367d4SAndreas Gohr 316a367d4SAndreas Gohrnamespace dokuwiki; 416a367d4SAndreas Gohr 516a367d4SAndreas Gohr/** 616a367d4SAndreas Gohr * Manage all builtin AJAX calls 716a367d4SAndreas Gohr * 816a367d4SAndreas Gohr * @todo The calls should be refactored out to their own proper classes 916a367d4SAndreas Gohr * @package dokuwiki 1016a367d4SAndreas Gohr */ 1116a367d4SAndreas Gohrclass Ajax { 1216a367d4SAndreas Gohr 1316a367d4SAndreas Gohr /** 1416a367d4SAndreas Gohr * Execute the given call 1516a367d4SAndreas Gohr * 1616a367d4SAndreas Gohr * @param string $call name of the ajax call 1716a367d4SAndreas Gohr */ 1816a367d4SAndreas Gohr public function __construct($call) { 1916a367d4SAndreas Gohr $callfn = 'call_' . $call; 2016a367d4SAndreas Gohr if(method_exists($this, $callfn)) { 2116a367d4SAndreas Gohr $this->$callfn(); 2216a367d4SAndreas Gohr } else { 2316a367d4SAndreas Gohr $evt = new \Doku_Event('AJAX_CALL_UNKNOWN', $call); 2416a367d4SAndreas Gohr if($evt->advise_before()) { 2516a367d4SAndreas Gohr print "AJAX call '" . hsc($call) . "' unknown!\n"; 2616a367d4SAndreas Gohr } else { 2716a367d4SAndreas Gohr $evt->advise_after(); 2816a367d4SAndreas Gohr unset($evt); 2916a367d4SAndreas Gohr } 3016a367d4SAndreas Gohr } 3116a367d4SAndreas Gohr } 3216a367d4SAndreas Gohr 3316a367d4SAndreas Gohr /** 3416a367d4SAndreas Gohr * Searches for matching pagenames 3516a367d4SAndreas Gohr * 3616a367d4SAndreas Gohr * @author Andreas Gohr <andi@splitbrain.org> 3716a367d4SAndreas Gohr */ 3816a367d4SAndreas Gohr protected function call_qsearch() { 3916a367d4SAndreas Gohr global $lang; 4016a367d4SAndreas Gohr global $INPUT; 4116a367d4SAndreas Gohr 4216a367d4SAndreas Gohr $maxnumbersuggestions = 50; 4316a367d4SAndreas Gohr 4416a367d4SAndreas Gohr $query = $INPUT->post->str('q'); 4516a367d4SAndreas Gohr if(empty($query)) $query = $INPUT->get->str('q'); 4616a367d4SAndreas Gohr if(empty($query)) return; 4716a367d4SAndreas Gohr 4816a367d4SAndreas Gohr $query = urldecode($query); 4916a367d4SAndreas Gohr 5016a367d4SAndreas Gohr $data = ft_pageLookup($query, true, useHeading('navigation')); 5116a367d4SAndreas Gohr 5216a367d4SAndreas Gohr if(!count($data)) return; 5316a367d4SAndreas Gohr 5416a367d4SAndreas Gohr print '<strong>' . $lang['quickhits'] . '</strong>'; 5516a367d4SAndreas Gohr print '<ul>'; 5616a367d4SAndreas Gohr $counter = 0; 5716a367d4SAndreas Gohr foreach($data as $id => $title) { 5816a367d4SAndreas Gohr if(useHeading('navigation')) { 5916a367d4SAndreas Gohr $name = $title; 6016a367d4SAndreas Gohr } else { 6116a367d4SAndreas Gohr $ns = getNS($id); 6216a367d4SAndreas Gohr if($ns) { 6316a367d4SAndreas Gohr $name = noNS($id) . ' (' . $ns . ')'; 6416a367d4SAndreas Gohr } else { 6516a367d4SAndreas Gohr $name = $id; 6616a367d4SAndreas Gohr } 6716a367d4SAndreas Gohr } 6816a367d4SAndreas Gohr echo '<li>' . html_wikilink(':' . $id, $name) . '</li>'; 6916a367d4SAndreas Gohr 7016a367d4SAndreas Gohr $counter++; 7116a367d4SAndreas Gohr if($counter > $maxnumbersuggestions) { 7216a367d4SAndreas Gohr echo '<li>...</li>'; 7316a367d4SAndreas Gohr break; 7416a367d4SAndreas Gohr } 7516a367d4SAndreas Gohr } 7616a367d4SAndreas Gohr print '</ul>'; 7716a367d4SAndreas Gohr } 7816a367d4SAndreas Gohr 7916a367d4SAndreas Gohr /** 8016a367d4SAndreas Gohr * Support OpenSearch suggestions 8116a367d4SAndreas Gohr * 8216a367d4SAndreas Gohr * @link http://www.opensearch.org/Specifications/OpenSearch/Extensions/Suggestions/1.0 8316a367d4SAndreas Gohr * @author Mike Frysinger <vapier@gentoo.org> 8416a367d4SAndreas Gohr */ 8516a367d4SAndreas Gohr protected function call_suggestions() { 8616a367d4SAndreas Gohr global $INPUT; 8716a367d4SAndreas Gohr 8816a367d4SAndreas Gohr $query = cleanID($INPUT->post->str('q')); 8916a367d4SAndreas Gohr if(empty($query)) $query = cleanID($INPUT->get->str('q')); 9016a367d4SAndreas Gohr if(empty($query)) return; 9116a367d4SAndreas Gohr 9216a367d4SAndreas Gohr $data = ft_pageLookup($query); 9316a367d4SAndreas Gohr if(!count($data)) return; 9416a367d4SAndreas Gohr $data = array_keys($data); 9516a367d4SAndreas Gohr 9616a367d4SAndreas Gohr // limit results to 15 hits 9716a367d4SAndreas Gohr $data = array_slice($data, 0, 15); 9816a367d4SAndreas Gohr $data = array_map('trim', $data); 9916a367d4SAndreas Gohr $data = array_map('noNS', $data); 10016a367d4SAndreas Gohr $data = array_unique($data); 10116a367d4SAndreas Gohr sort($data); 10216a367d4SAndreas Gohr 10316a367d4SAndreas Gohr /* now construct a json */ 10416a367d4SAndreas Gohr $suggestions = array( 10516a367d4SAndreas Gohr $query, // the original query 10616a367d4SAndreas Gohr $data, // some suggestions 10716a367d4SAndreas Gohr array(), // no description 10816a367d4SAndreas Gohr array() // no urls 10916a367d4SAndreas Gohr ); 11016a367d4SAndreas Gohr $json = new \JSON(); 11116a367d4SAndreas Gohr 11216a367d4SAndreas Gohr header('Content-Type: application/x-suggestions+json'); 11316a367d4SAndreas Gohr print $json->encode($suggestions); 11416a367d4SAndreas Gohr } 11516a367d4SAndreas Gohr 11616a367d4SAndreas Gohr /** 11716a367d4SAndreas Gohr * Refresh a page lock and save draft 11816a367d4SAndreas Gohr * 11916a367d4SAndreas Gohr * Andreas Gohr <andi@splitbrain.org> 12016a367d4SAndreas Gohr */ 12116a367d4SAndreas Gohr protected function call_lock() { 12216a367d4SAndreas Gohr global $lang; 12316a367d4SAndreas Gohr global $ID; 12416a367d4SAndreas Gohr global $INFO; 12516a367d4SAndreas Gohr global $INPUT; 12616a367d4SAndreas Gohr 12716a367d4SAndreas Gohr $ID = cleanID($INPUT->post->str('id')); 12816a367d4SAndreas Gohr if(empty($ID)) return; 12916a367d4SAndreas Gohr 13016a367d4SAndreas Gohr $INFO = pageinfo(); 13116a367d4SAndreas Gohr 13216a367d4SAndreas Gohr if(!$INFO['writable']) { 13316a367d4SAndreas Gohr echo 'Permission denied'; 13416a367d4SAndreas Gohr return; 13516a367d4SAndreas Gohr } 13616a367d4SAndreas Gohr 13716a367d4SAndreas Gohr if(!checklock($ID)) { 13816a367d4SAndreas Gohr lock($ID); 13916a367d4SAndreas Gohr echo 1; 14016a367d4SAndreas Gohr } 14116a367d4SAndreas Gohr 142*0aabe6f8SMichael Große $draft = new Draft($ID, $INFO['client']); 143*0aabe6f8SMichael Große if ($draft->saveDraft()) { 144*0aabe6f8SMichael Große echo $draft->getDraftMessage(); 14516a367d4SAndreas Gohr } 14616a367d4SAndreas Gohr } 14716a367d4SAndreas Gohr 14816a367d4SAndreas Gohr /** 14916a367d4SAndreas Gohr * Delete a draft 15016a367d4SAndreas Gohr * 15116a367d4SAndreas Gohr * @author Andreas Gohr <andi@splitbrain.org> 15216a367d4SAndreas Gohr */ 15316a367d4SAndreas Gohr protected function call_draftdel() { 15416a367d4SAndreas Gohr global $INPUT; 15516a367d4SAndreas Gohr $id = cleanID($INPUT->str('id')); 15616a367d4SAndreas Gohr if(empty($id)) return; 15716a367d4SAndreas Gohr 15816a367d4SAndreas Gohr $client = $_SERVER['REMOTE_USER']; 15916a367d4SAndreas Gohr if(!$client) $client = clientIP(true); 16016a367d4SAndreas Gohr 16116a367d4SAndreas Gohr $cname = getCacheName($client . $id, '.draft'); 16216a367d4SAndreas Gohr @unlink($cname); 16316a367d4SAndreas Gohr } 16416a367d4SAndreas Gohr 16516a367d4SAndreas Gohr /** 16616a367d4SAndreas Gohr * Return subnamespaces for the Mediamanager 16716a367d4SAndreas Gohr * 16816a367d4SAndreas Gohr * @author Andreas Gohr <andi@splitbrain.org> 16916a367d4SAndreas Gohr */ 17016a367d4SAndreas Gohr protected function call_medians() { 17116a367d4SAndreas Gohr global $conf; 17216a367d4SAndreas Gohr global $INPUT; 17316a367d4SAndreas Gohr 17416a367d4SAndreas Gohr // wanted namespace 17516a367d4SAndreas Gohr $ns = cleanID($INPUT->post->str('ns')); 17616a367d4SAndreas Gohr $dir = utf8_encodeFN(str_replace(':', '/', $ns)); 17716a367d4SAndreas Gohr 17816a367d4SAndreas Gohr $lvl = count(explode(':', $ns)); 17916a367d4SAndreas Gohr 18016a367d4SAndreas Gohr $data = array(); 18116a367d4SAndreas Gohr search($data, $conf['mediadir'], 'search_index', array('nofiles' => true), $dir); 18216a367d4SAndreas Gohr foreach(array_keys($data) as $item) { 18316a367d4SAndreas Gohr $data[$item]['level'] = $lvl + 1; 18416a367d4SAndreas Gohr } 18516a367d4SAndreas Gohr echo html_buildlist($data, 'idx', 'media_nstree_item', 'media_nstree_li'); 18616a367d4SAndreas Gohr } 18716a367d4SAndreas Gohr 18816a367d4SAndreas Gohr /** 18916a367d4SAndreas Gohr * Return list of files for the Mediamanager 19016a367d4SAndreas Gohr * 19116a367d4SAndreas Gohr * @author Andreas Gohr <andi@splitbrain.org> 19216a367d4SAndreas Gohr */ 19316a367d4SAndreas Gohr protected function call_medialist() { 19416a367d4SAndreas Gohr global $NS; 19516a367d4SAndreas Gohr global $INPUT; 19616a367d4SAndreas Gohr 19716a367d4SAndreas Gohr $NS = cleanID($INPUT->post->str('ns')); 19816a367d4SAndreas Gohr $sort = $INPUT->post->bool('recent') ? 'date' : 'natural'; 19916a367d4SAndreas Gohr if($INPUT->post->str('do') == 'media') { 20016a367d4SAndreas Gohr tpl_mediaFileList(); 20116a367d4SAndreas Gohr } else { 20216a367d4SAndreas Gohr tpl_mediaContent(true, $sort); 20316a367d4SAndreas Gohr } 20416a367d4SAndreas Gohr } 20516a367d4SAndreas Gohr 20616a367d4SAndreas Gohr /** 20716a367d4SAndreas Gohr * Return the content of the right column 20816a367d4SAndreas Gohr * (image details) for the Mediamanager 20916a367d4SAndreas Gohr * 21016a367d4SAndreas Gohr * @author Kate Arzamastseva <pshns@ukr.net> 21116a367d4SAndreas Gohr */ 21216a367d4SAndreas Gohr protected function call_mediadetails() { 21316a367d4SAndreas Gohr global $IMG, $JUMPTO, $REV, $fullscreen, $INPUT; 21416a367d4SAndreas Gohr $fullscreen = true; 21516a367d4SAndreas Gohr require_once(DOKU_INC . 'lib/exe/mediamanager.php'); 21616a367d4SAndreas Gohr 21716a367d4SAndreas Gohr $image = ''; 21816a367d4SAndreas Gohr if($INPUT->has('image')) $image = cleanID($INPUT->str('image')); 21916a367d4SAndreas Gohr if(isset($IMG)) $image = $IMG; 22016a367d4SAndreas Gohr if(isset($JUMPTO)) $image = $JUMPTO; 22116a367d4SAndreas Gohr $rev = false; 22216a367d4SAndreas Gohr if(isset($REV) && !$JUMPTO) $rev = $REV; 22316a367d4SAndreas Gohr 22416a367d4SAndreas Gohr html_msgarea(); 22516a367d4SAndreas Gohr tpl_mediaFileDetails($image, $rev); 22616a367d4SAndreas Gohr } 22716a367d4SAndreas Gohr 22816a367d4SAndreas Gohr /** 22916a367d4SAndreas Gohr * Returns image diff representation for mediamanager 23016a367d4SAndreas Gohr * 23116a367d4SAndreas Gohr * @author Kate Arzamastseva <pshns@ukr.net> 23216a367d4SAndreas Gohr */ 23316a367d4SAndreas Gohr protected function call_mediadiff() { 23416a367d4SAndreas Gohr global $NS; 23516a367d4SAndreas Gohr global $INPUT; 23616a367d4SAndreas Gohr 23716a367d4SAndreas Gohr $image = ''; 23816a367d4SAndreas Gohr if($INPUT->has('image')) $image = cleanID($INPUT->str('image')); 23916a367d4SAndreas Gohr $NS = getNS($image); 24016a367d4SAndreas Gohr $auth = auth_quickaclcheck("$NS:*"); 24116a367d4SAndreas Gohr media_diff($image, $NS, $auth, true); 24216a367d4SAndreas Gohr } 24316a367d4SAndreas Gohr 24416a367d4SAndreas Gohr /** 24516a367d4SAndreas Gohr * Manages file uploads 24616a367d4SAndreas Gohr * 24716a367d4SAndreas Gohr * @author Kate Arzamastseva <pshns@ukr.net> 24816a367d4SAndreas Gohr */ 24916a367d4SAndreas Gohr protected function call_mediaupload() { 25016a367d4SAndreas Gohr global $NS, $MSG, $INPUT; 25116a367d4SAndreas Gohr 25216a367d4SAndreas Gohr $id = ''; 25316a367d4SAndreas Gohr if($_FILES['qqfile']['tmp_name']) { 25416a367d4SAndreas Gohr $id = $INPUT->post->str('mediaid', $_FILES['qqfile']['name']); 25516a367d4SAndreas Gohr } elseif($INPUT->get->has('qqfile')) { 25616a367d4SAndreas Gohr $id = $INPUT->get->str('qqfile'); 25716a367d4SAndreas Gohr } 25816a367d4SAndreas Gohr 25916a367d4SAndreas Gohr $id = cleanID($id); 26016a367d4SAndreas Gohr 26116a367d4SAndreas Gohr $NS = $INPUT->str('ns'); 26216a367d4SAndreas Gohr $ns = $NS . ':' . getNS($id); 26316a367d4SAndreas Gohr 26416a367d4SAndreas Gohr $AUTH = auth_quickaclcheck("$ns:*"); 26516a367d4SAndreas Gohr if($AUTH >= AUTH_UPLOAD) { 26616a367d4SAndreas Gohr io_createNamespace("$ns:xxx", 'media'); 26716a367d4SAndreas Gohr } 26816a367d4SAndreas Gohr 26916a367d4SAndreas Gohr if($_FILES['qqfile']['error']) unset($_FILES['qqfile']); 27016a367d4SAndreas Gohr 27116a367d4SAndreas Gohr $res = false; 27216a367d4SAndreas Gohr if($_FILES['qqfile']['tmp_name']) $res = media_upload($NS, $AUTH, $_FILES['qqfile']); 27316a367d4SAndreas Gohr if($INPUT->get->has('qqfile')) $res = media_upload_xhr($NS, $AUTH); 27416a367d4SAndreas Gohr 27516a367d4SAndreas Gohr if($res) { 27616a367d4SAndreas Gohr $result = array( 27716a367d4SAndreas Gohr 'success' => true, 27816a367d4SAndreas Gohr 'link' => media_managerURL(array('ns' => $ns, 'image' => $NS . ':' . $id), '&'), 27916a367d4SAndreas Gohr 'id' => $NS . ':' . $id, 28016a367d4SAndreas Gohr 'ns' => $NS 28116a367d4SAndreas Gohr ); 28216a367d4SAndreas Gohr } else { 28316a367d4SAndreas Gohr $error = ''; 28416a367d4SAndreas Gohr if(isset($MSG)) { 28516a367d4SAndreas Gohr foreach($MSG as $msg) { 28616a367d4SAndreas Gohr $error .= $msg['msg']; 28716a367d4SAndreas Gohr } 28816a367d4SAndreas Gohr } 28916a367d4SAndreas Gohr $result = array( 29016a367d4SAndreas Gohr 'error' => $error, 29116a367d4SAndreas Gohr 'ns' => $NS 29216a367d4SAndreas Gohr ); 29316a367d4SAndreas Gohr } 29416a367d4SAndreas Gohr $json = new \JSON; 29516a367d4SAndreas Gohr header('Content-Type: application/json'); 29616a367d4SAndreas Gohr echo $json->encode($result); 29716a367d4SAndreas Gohr } 29816a367d4SAndreas Gohr 29916a367d4SAndreas Gohr /** 30016a367d4SAndreas Gohr * Return sub index for index view 30116a367d4SAndreas Gohr * 30216a367d4SAndreas Gohr * @author Andreas Gohr <andi@splitbrain.org> 30316a367d4SAndreas Gohr */ 30416a367d4SAndreas Gohr protected function call_index() { 30516a367d4SAndreas Gohr global $conf; 30616a367d4SAndreas Gohr global $INPUT; 30716a367d4SAndreas Gohr 30816a367d4SAndreas Gohr // wanted namespace 30916a367d4SAndreas Gohr $ns = cleanID($INPUT->post->str('idx')); 31016a367d4SAndreas Gohr $dir = utf8_encodeFN(str_replace(':', '/', $ns)); 31116a367d4SAndreas Gohr 31216a367d4SAndreas Gohr $lvl = count(explode(':', $ns)); 31316a367d4SAndreas Gohr 31416a367d4SAndreas Gohr $data = array(); 31516a367d4SAndreas Gohr search($data, $conf['datadir'], 'search_index', array('ns' => $ns), $dir); 31616a367d4SAndreas Gohr foreach(array_keys($data) as $item) { 31716a367d4SAndreas Gohr $data[$item]['level'] = $lvl + 1; 31816a367d4SAndreas Gohr } 31916a367d4SAndreas Gohr echo html_buildlist($data, 'idx', 'html_list_index', 'html_li_index'); 32016a367d4SAndreas Gohr } 32116a367d4SAndreas Gohr 32216a367d4SAndreas Gohr /** 32316a367d4SAndreas Gohr * List matching namespaces and pages for the link wizard 32416a367d4SAndreas Gohr * 32516a367d4SAndreas Gohr * @author Andreas Gohr <gohr@cosmocode.de> 32616a367d4SAndreas Gohr */ 32716a367d4SAndreas Gohr protected function call_linkwiz() { 32816a367d4SAndreas Gohr global $conf; 32916a367d4SAndreas Gohr global $lang; 33016a367d4SAndreas Gohr global $INPUT; 33116a367d4SAndreas Gohr 33216a367d4SAndreas Gohr $q = ltrim(trim($INPUT->post->str('q')), ':'); 33316a367d4SAndreas Gohr $id = noNS($q); 33416a367d4SAndreas Gohr $ns = getNS($q); 33516a367d4SAndreas Gohr 33616a367d4SAndreas Gohr $ns = cleanID($ns); 33716a367d4SAndreas Gohr $id = cleanID($id); 33816a367d4SAndreas Gohr 33916a367d4SAndreas Gohr $nsd = utf8_encodeFN(str_replace(':', '/', $ns)); 34016a367d4SAndreas Gohr 34116a367d4SAndreas Gohr $data = array(); 34216a367d4SAndreas Gohr if($q && !$ns) { 34316a367d4SAndreas Gohr 34416a367d4SAndreas Gohr // use index to lookup matching pages 34516a367d4SAndreas Gohr $pages = ft_pageLookup($id, true); 34616a367d4SAndreas Gohr 34716a367d4SAndreas Gohr // result contains matches in pages and namespaces 34816a367d4SAndreas Gohr // we now extract the matching namespaces to show 34916a367d4SAndreas Gohr // them seperately 35016a367d4SAndreas Gohr $dirs = array(); 35116a367d4SAndreas Gohr 35216a367d4SAndreas Gohr foreach($pages as $pid => $title) { 35316a367d4SAndreas Gohr if(strpos(noNS($pid), $id) === false) { 35416a367d4SAndreas Gohr // match was in the namespace 35516a367d4SAndreas Gohr $dirs[getNS($pid)] = 1; // assoc array avoids dupes 35616a367d4SAndreas Gohr } else { 35716a367d4SAndreas Gohr // it is a matching page, add it to the result 35816a367d4SAndreas Gohr $data[] = array( 35916a367d4SAndreas Gohr 'id' => $pid, 36016a367d4SAndreas Gohr 'title' => $title, 36116a367d4SAndreas Gohr 'type' => 'f', 36216a367d4SAndreas Gohr ); 36316a367d4SAndreas Gohr } 36416a367d4SAndreas Gohr unset($pages[$pid]); 36516a367d4SAndreas Gohr } 36616a367d4SAndreas Gohr foreach($dirs as $dir => $junk) { 36716a367d4SAndreas Gohr $data[] = array( 36816a367d4SAndreas Gohr 'id' => $dir, 36916a367d4SAndreas Gohr 'type' => 'd', 37016a367d4SAndreas Gohr ); 37116a367d4SAndreas Gohr } 37216a367d4SAndreas Gohr 37316a367d4SAndreas Gohr } else { 37416a367d4SAndreas Gohr 37516a367d4SAndreas Gohr $opts = array( 37616a367d4SAndreas Gohr 'depth' => 1, 37716a367d4SAndreas Gohr 'listfiles' => true, 37816a367d4SAndreas Gohr 'listdirs' => true, 37916a367d4SAndreas Gohr 'pagesonly' => true, 38016a367d4SAndreas Gohr 'firsthead' => true, 38116a367d4SAndreas Gohr 'sneakyacl' => $conf['sneaky_index'], 38216a367d4SAndreas Gohr ); 38316a367d4SAndreas Gohr if($id) $opts['filematch'] = '^.*\/' . $id; 38416a367d4SAndreas Gohr if($id) $opts['dirmatch'] = '^.*\/' . $id; 38516a367d4SAndreas Gohr search($data, $conf['datadir'], 'search_universal', $opts, $nsd); 38616a367d4SAndreas Gohr 38716a367d4SAndreas Gohr // add back to upper 38816a367d4SAndreas Gohr if($ns) { 38916a367d4SAndreas Gohr array_unshift( 39016a367d4SAndreas Gohr $data, array( 39116a367d4SAndreas Gohr 'id' => getNS($ns), 39216a367d4SAndreas Gohr 'type' => 'u', 39316a367d4SAndreas Gohr ) 39416a367d4SAndreas Gohr ); 39516a367d4SAndreas Gohr } 39616a367d4SAndreas Gohr } 39716a367d4SAndreas Gohr 39816a367d4SAndreas Gohr // fixme sort results in a useful way ? 39916a367d4SAndreas Gohr 40016a367d4SAndreas Gohr if(!count($data)) { 40116a367d4SAndreas Gohr echo $lang['nothingfound']; 40216a367d4SAndreas Gohr exit; 40316a367d4SAndreas Gohr } 40416a367d4SAndreas Gohr 40516a367d4SAndreas Gohr // output the found data 40616a367d4SAndreas Gohr $even = 1; 40716a367d4SAndreas Gohr foreach($data as $item) { 40816a367d4SAndreas Gohr $even *= -1; //zebra 40916a367d4SAndreas Gohr 41016a367d4SAndreas Gohr if(($item['type'] == 'd' || $item['type'] == 'u') && $item['id']) $item['id'] .= ':'; 41116a367d4SAndreas Gohr $link = wl($item['id']); 41216a367d4SAndreas Gohr 41316a367d4SAndreas Gohr echo '<div class="' . (($even > 0) ? 'even' : 'odd') . ' type_' . $item['type'] . '">'; 41416a367d4SAndreas Gohr 41516a367d4SAndreas Gohr if($item['type'] == 'u') { 41616a367d4SAndreas Gohr $name = $lang['upperns']; 41716a367d4SAndreas Gohr } else { 41816a367d4SAndreas Gohr $name = hsc($item['id']); 41916a367d4SAndreas Gohr } 42016a367d4SAndreas Gohr 42116a367d4SAndreas Gohr echo '<a href="' . $link . '" title="' . hsc($item['id']) . '" class="wikilink1">' . $name . '</a>'; 42216a367d4SAndreas Gohr 42316a367d4SAndreas Gohr if(!blank($item['title'])) { 42416a367d4SAndreas Gohr echo '<span>' . hsc($item['title']) . '</span>'; 42516a367d4SAndreas Gohr } 42616a367d4SAndreas Gohr echo '</div>'; 42716a367d4SAndreas Gohr } 42816a367d4SAndreas Gohr 42916a367d4SAndreas Gohr } 43016a367d4SAndreas Gohr 43116a367d4SAndreas Gohr} 432