1<?php 2 3use dokuwiki\Extension\SyntaxPlugin; 4use dokuwiki\Utf8\Sort; 5 6/** 7 * DokuWiki Plugin linklist (Syntax Component) 8 * 9 * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html 10 * @author Andreas Gohr <dokuwiki@cosmocode.de> 11 */ 12class syntax_plugin_linklist extends SyntaxPlugin 13{ 14 /** @inheritDoc */ 15 public function getType() 16 { 17 return 'substition'; 18 } 19 20 /** @inheritDoc */ 21 public function getPType() 22 { 23 return 'block'; 24 } 25 26 /** @inheritDoc */ 27 public function getSort() 28 { 29 return 155; 30 } 31 32 /** @inheritDoc */ 33 public function connectTo($mode) 34 { 35 $this->Lexer->addSpecialPattern('\{\{linklist[^\}]*?\}\}', $mode, 'plugin_linklist'); 36 } 37 38 39 /** @inheritDoc */ 40 public function handle($match, $state, $pos, Doku_Handler $handler) 41 { 42 $match = substr($match, 11, -2); 43 $params = explode(' ', $match); 44 $id = array_shift($params); 45 $params = array_map('trim', $params); 46 47 $type = 'internal'; 48 if (in_array('backlinks', $params)) { 49 $type = 'backlinks'; 50 } elseif (in_array('external', $params)) { 51 $type = 'external'; 52 } elseif (in_array('interwiki', $params)) { 53 $type = 'interwiki'; 54 } 55 56 57 $data = [ 58 'id' => $id, 59 'type' => $type, 60 ]; 61 62 return $data; 63 } 64 65 /** @inheritDoc */ 66 public function render($mode, Doku_Renderer $renderer, $data) 67 { 68 if ($mode == 'linklist') return false; 69 if ($mode == 'metadata') return false; 70 71 global $INFO; 72 73 if (!$data['id']) $data['id'] = $INFO['id']; 74 if (!page_exists($data['id'])) return true; 75 if (auth_quickaclcheck($data['id']) < AUTH_READ) return true; 76 77 switch ($data['type']) { 78 case 'backlinks': 79 // backlinks from the index 80 $links = ft_backlinks($data['id'], true); 81 $links = array_map(fn($link) => [$link, helper_plugin_linklist::getTitle($link)], $links); 82 break; 83 case 'internal': 84 case 'external': 85 case 'interwiki': 86 // all other links from our own renderer 87 $results = p_cached_output(wikiFN($data['id']), 'linklist'); 88 $results = json_decode($results, true, JSON_THROW_ON_ERROR); 89 $links = $results[$data['type']]; 90 } 91 92 93 $links = array_filter($links, fn($item) => !isHiddenPage($item)); 94 if (!$links) return true; 95 usort($links, [$this, 'sortByTitle']); 96 97 $renderer->listu_open(); 98 foreach ($links as $params) { 99 $renderer->listitem_open(1); 100 $renderer->listcontent_open(); 101 switch ($data['type']) { 102 case 'backlinks': 103 case 'internal': 104 $renderer->internallink($params[0], $params[1]); 105 break; 106 case 'external': 107 $renderer->externallink($params[0], $params[1]); 108 break; 109 case 'interwiki': 110 $renderer->interwikilink($params[0], $params[1], $params[2], $params[3]); 111 break; 112 } 113 $renderer->listcontent_close(); 114 $renderer->listitem_close(); 115 } 116 $renderer->listu_close(); 117 118 119 return true; 120 } 121 122 /** 123 * Sort the links by title 124 * 125 * Titles are the second parameter in the array 126 * 127 * @param array $a 128 * @param array $b 129 * @return int 130 */ 131 public function sortByTitle($a, $b) 132 { 133 return Sort::strcmp($a[1], $b[1]); 134 } 135} 136