Lexer->addSpecialPattern('<' . self::getElementName(). '[^>]*>', $mode, 'plugin_' . webcomponent::PLUGIN_NAME . '_' . $this->getPluginComponent()); // To replace backlinks, you may add it in the configuration $extraPattern = $this->getConf(self::EXTRA_PATTERN_CONF); if ($extraPattern != ""){ $this->Lexer->addSpecialPattern($extraPattern, $mode, 'plugin_' . webcomponent::PLUGIN_NAME . '_' . $this->getPluginComponent()); } } /** * * The handle function goal is to parse the matched syntax through the pattern function * and to return the result for use in the renderer * This result is always cached until the page is modified. * @see DokuWiki_Syntax_Plugin::handle() * * @param string $match * @param int $state * @param int $pos * @param Doku_Handler $handler * @return array|bool */ function handle($match, $state, $pos, Doku_Handler $handler) { switch ($state) { // As there is only one call to connect to in order to a add a pattern, // there is only one state entering the function // but I leave it for better understanding of the process flow case DOKU_LEXER_SPECIAL : // Parse the parameters $match = utf8_substr($match, strlen(self::getElementName()), -1); // /i not case sensitive $attributePattern = "\\s*(\w+)\\s*=\\s*[\'\"]?([\w\d\s-_\|\*\.\(\)\?\/\\\\]+)[\'\"]?\\s*"; $result = preg_match_all('/' . $attributePattern . '/i', $match, $matches); if ($result != 0) { foreach ($matches[1] as $key => $parameterKey) { $parameters[strtolower($parameterKey)] = $matches[2][$key]; } } } // Cache the values return array($state, $parameters); } /** * Render the output * @see DokuWiki_Syntax_Plugin::render() * * @param string $mode * @param Doku_Renderer $renderer * @param array $data * @return bool */ function render($mode, Doku_Renderer $renderer, $data) { global $lang; global $INFO; global $ID; $id = $ID; // If it's a sidebar, get the original id. if (isset($INFO)) { $id = $INFO['id']; } if ($mode == 'xhtml') { $relatedPages = $this->related($id); $renderer->doc .= '
' . DOKU_LF; if (empty($relatedPages)) { // Dokuwiki debug dbglog("No Backlinks", "Related plugins: all backlinks for page: $id"); $renderer->doc .= "Plugin ".webcomponent::PLUGIN_NAME." - Component ".self::getElementName().": " . $lang['nothingfound'] . "" . DOKU_LF; } else { // Dokuwiki debug dbglog($relatedPages, self::getElementName()." plugins: all backlinks for page: $id"); $renderer->doc .= '' . DOKU_LF; } $renderer->doc .= '
' . DOKU_LF; return true; } return false; } /** * @param $id * @param $max * @return array */ public function related($id, $max = NULL): array { if ($max == NULL){ $max = $this->getConf(self::MAX_LINKS_CONF); } // Call the dokuwiki backlinks function @require_once(DOKU_INC . 'inc/fulltext.php'); // Backlinks called the indexer, for more info // See: https://www.dokuwiki.org/devel:metadata#metadata_index $backlinks = ft_backlinks($id, $ignore_perms = false); // To minimize the pressure on the index // as we asks then the backlinks of the backlinks on the next step if (sizeof($backlinks) > 50){ $backlinks = array_slice($backlinks, 0, 50); } $related = array(); foreach ($backlinks as $backlink){ $page = array(); $page[self::RELATED_PAGE_ID_PROP]=$backlink; $page[self::RELATED_BACKLINKS_COUNT_PROP]=sizeof(ft_backlinks($backlink, $ignore_perms = false)); $related[]=$page; } usort($related, function($a, $b) { return $b[self::RELATED_BACKLINKS_COUNT_PROP] - $a[self::RELATED_BACKLINKS_COUNT_PROP] ; }); if (sizeof($related)> $max){ $related = array_slice($related, 0, $max); $page = array(); $page[self::RELATED_PAGE_ID_PROP] = self::MORE_PAGE_ID; $related[] = $page; } return $related; } public static function getElementName() { return webcomponent::getTagName(get_called_class()); } }