1<?php 2 3 4require_once(__DIR__ . "/../class/Analytics.php"); 5require_once(__DIR__ . "/../class/PluginUtility.php"); 6require_once(__DIR__ . "/../class/LinkUtility.php"); 7require_once(__DIR__ . "/../class/HtmlUtility.php"); 8 9use ComboStrap\Analytics; 10use ComboStrap\LinkUtility; 11use ComboStrap\LogUtility; 12use ComboStrap\Page; 13use ComboStrap\PluginUtility; 14use ComboStrap\LowQualityPage; 15use ComboStrap\Tag; 16 17if (!defined('DOKU_INC')) die(); 18 19/** 20 * 21 * A link pattern to take over the link of Dokuwiki 22 * and transform it as a bootstrap link 23 * 24 * The handle of the move of link is to be found in the 25 * admin action {@link action_plugin_combo_linkmove} 26 * 27 */ 28class syntax_plugin_combo_link extends DokuWiki_Syntax_Plugin 29{ 30 const TAG = 'link'; 31 32 33 /** 34 * Syntax Type. 35 * 36 * Needs to return one of the mode types defined in $PARSER_MODES in parser.php 37 * @see https://www.dokuwiki.org/devel:syntax_plugins#syntax_types 38 */ 39 function getType() 40 { 41 return 'substition'; 42 } 43 44 /** 45 * How Dokuwiki will add P element 46 * 47 * * 'normal' - The plugin can be used inside paragraphs 48 * * 'block' - Open paragraphs need to be closed before plugin output - block should not be inside paragraphs 49 * * 'stack' - Special case. Plugin wraps other paragraphs. - Stacks can contain paragraphs 50 * 51 * @see DokuWiki_Syntax_Plugin::getPType() 52 */ 53 function getPType() 54 { 55 return 'normal'; 56 } 57 58 /** 59 * @return array 60 * Allow which kind of plugin inside 61 * 62 * No one of array('container', 'baseonly', 'formatting', 'substition', 'protected', 'disabled', 'paragraphs') 63 * because we manage self the content and we call self the parser 64 */ 65 function getAllowedTypes() 66 { 67 return array('substition', 'formatting', 'disabled'); 68 } 69 70 /** 71 * @see Doku_Parser_Mode::getSort() 72 * The mode with the lowest sort number will win out 73 */ 74 function getSort() 75 { 76 return 100; 77 } 78 79 80 function connectTo($mode) 81 { 82 83 $this->Lexer->addSpecialPattern(LinkUtility::LINK_PATTERN, $mode, PluginUtility::getModeForComponent($this->getPluginComponent())); 84 85 } 86 87 88 /** 89 * The handler for an internal link 90 * based on `internallink` in {@link Doku_Handler} 91 * The handler call the good renderer in {@link Doku_Renderer_xhtml} with 92 * the parameters (ie for instance internallink) 93 * @param string $match 94 * @param int $state 95 * @param int $pos 96 * @param Doku_Handler $handler 97 * @return array|bool 98 */ 99 function handle($match, $state, $pos, Doku_Handler $handler) 100 { 101 102 /** 103 * Because we use the specialPattern, there is only one state ie DOKU_LEXER_SPECIAL 104 */ 105 $attributes = LinkUtility::getAttributes($match); 106 $tag = new Tag(self::TAG, $attributes, $state, $handler->calls); 107 $parent = $tag->getParent(); 108 $parentName = ""; 109 if ($parent != null) { 110 $parentName = $parent->getName(); 111 } 112 return array( 113 PluginUtility::ATTRIBUTES => $attributes, 114 PluginUtility::PARENT_TAG => $parentName 115 ); 116 117 118 } 119 120 /** 121 * Render the output 122 * @param string $format 123 * @param Doku_Renderer $renderer 124 * @param array $data - what the function handle() return'ed 125 * @return boolean - rendered correctly? (however, returned value is not used at the moment) 126 * @see DokuWiki_Syntax_Plugin::render() 127 * 128 * 129 */ 130 function render($format, Doku_Renderer $renderer, $data) 131 { 132 // The data 133 switch ($format) { 134 case 'xhtml': 135 136 /** @var Doku_Renderer_xhtml $renderer */ 137 138 /** 139 * Cache problem may occurs while releasing 140 */ 141 if (isset($data[PluginUtility::ATTRIBUTES])) { 142 $attributes = $data[PluginUtility::ATTRIBUTES]; 143 } else { 144 $attributes = $data; 145 } 146 147 $type = $attributes[LinkUtility::ATTRIBUTE_TYPE]; 148 $id = $attributes[LinkUtility::ATTRIBUTE_ID]; 149 150 /** 151 * Email are also link for Dokuwiki 152 * And there is no notion of page. 153 * For the low quality page functionality, 154 * we split the process of the internal link 155 */ 156 $lowLink = false; 157 if ($type == LinkUtility::TYPE_INTERNAL) { 158 /** 159 * If this is a low quality internal page, 160 * print a shallow link for the anonymous user 161 */ 162 global $ID; 163 $qualifiedPageId = $id; 164 resolve_pageid(getNS($ID), $qualifiedPageId, $exists); 165 $page = new Page($qualifiedPageId); 166 if ($this->getConf(LowQualityPage::CONF_LOW_QUALITY_PAGE_PROTECTION_ENABLE) 167 && $page->isLowQualityPage()) { 168 169 $lowLink = true; 170 } 171 } 172 173 /** 174 * Render the link 175 */ 176 $htmlLink = LinkUtility::renderLinkDefault($renderer, $attributes, $lowLink); 177 178 /** 179 * Extra styling 180 */ 181 $parentClassWithoutClass = array( 182 syntax_plugin_combo_button::TAG, 183 syntax_plugin_combo_cite::TAG, 184 syntax_plugin_combo_dropdown::TAG, 185 syntax_plugin_combo_listitem::TAG, 186 syntax_plugin_combo_preformatted::TAG 187 ); 188 if (page_exists($id) && in_array($data[PluginUtility::PARENT_TAG], $parentClassWithoutClass)) { 189 $htmlLink = LinkUtility::deleteDokuWikiClass($htmlLink); 190 } 191 192 if ($data[PluginUtility::PARENT_TAG] == syntax_plugin_combo_button::TAG) { 193 // We could also apply the class ie btn-secondary ... 194 $htmlLink = LinkUtility::inheritColorFromParent($htmlLink); 195 } 196 197 /** 198 * Add it to the rendering 199 */ 200 $renderer->doc .= $htmlLink; 201 202 return true; 203 break; 204 205 case 206 'metadata': 207 208 /** 209 * Keep track of the backlinks ie meta['relation']['references'] 210 * @var Doku_Renderer_metadata $renderer 211 */ 212 if (isset($data[PluginUtility::ATTRIBUTES])) { 213 $attributes = $data[PluginUtility::ATTRIBUTES]; 214 } else { 215 $attributes = $data; 216 } 217 LinkUtility::handleMetadata($renderer, $attributes); 218 219 return true; 220 break; 221 222 case Analytics::RENDERER_FORMAT: 223 /** 224 * 225 * @var renderer_plugin_combo_analytics $renderer 226 */ 227 $attributes = $data[PluginUtility::ATTRIBUTES]; 228 LinkUtility::processLinkStats($attributes, $renderer->stats); 229 break; 230 231 } 232 // unsupported $mode 233 return false; 234 } 235 236 237} 238 239