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