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 $this->Lexer->addSpecialPattern(LinkUtility::LINK_PATTERN, $mode, PluginUtility::getModeForComponent($this->getPluginComponent())); 82 83 } 84 85 86 /** 87 * The handler for an internal link 88 * based on `internallink` in {@link Doku_Handler} 89 * The handler call the good renderer in {@link Doku_Renderer_xhtml} with 90 * the parameters (ie for instance internallink) 91 * @param string $match 92 * @param int $state 93 * @param int $pos 94 * @param Doku_Handler $handler 95 * @return array|bool 96 */ 97 function handle($match, $state, $pos, Doku_Handler $handler) 98 { 99 100 /** 101 * Because we use the specialPattern, there is only one state ie DOKU_LEXER_SPECIAL 102 */ 103 $attributes = LinkUtility::getAttributes($match); 104 $tag = new Tag(self::TAG, $attributes, $state, $handler->calls); 105 $parent = $tag->getParent(); 106 $parentName = ""; 107 if ($parent != null) { 108 $parentName = $parent->getName(); 109 } 110 return array( 111 PluginUtility::ATTRIBUTES => $attributes, 112 PluginUtility::PARENT_TAG => $parentName 113 ); 114 115 116 } 117 118 /** 119 * Render the output 120 * @param string $format 121 * @param Doku_Renderer $renderer 122 * @param array $data - what the function handle() return'ed 123 * @return boolean - rendered correctly? (however, returned value is not used at the moment) 124 * @see DokuWiki_Syntax_Plugin::render() 125 * 126 * 127 */ 128 function render($format, Doku_Renderer $renderer, $data) 129 { 130 // The data 131 switch ($format) { 132 case 'xhtml': 133 134 /** @var Doku_Renderer_xhtml $renderer */ 135 136 /** 137 * Cache problem 138 */ 139 if (isset($data[PluginUtility::ATTRIBUTES])) { 140 $attributes = $data[PluginUtility::ATTRIBUTES]; 141 } else { 142 $attributes = $data; 143 } 144 145 $type = $attributes[LinkUtility::ATTRIBUTE_TYPE]; 146 $id = $attributes[LinkUtility::ATTRIBUTE_ID]; 147 /** 148 * If this is a low quality internal page, 149 * print a shallow link for the anonymous user 150 */ 151 if ( 152 $type == "internal" 153 && $this->getConf(LowQualityPage::CONF_LOW_QUALITY_PAGE_PROTECTION_ENABLE) 154 && LowQualityPage::isPageToExclude($id) 155 ) { 156 157 $htmlLink = LinkUtility::renderLowQualityProtectedLink($attributes); 158 159 } else { 160 161 $htmlLink = LinkUtility::renderAsAnchorElement($renderer, $attributes); 162 $parentClassWithoutClass = array( 163 syntax_plugin_combo_button::TAG, 164 syntax_plugin_combo_cite::TAG, 165 syntax_plugin_combo_dropdown::TAG, 166 syntax_plugin_combo_listitem::TAG, 167 syntax_plugin_combo_preformatted::TAG 168 ); 169 if (page_exists($id) && in_array($data[PluginUtility::PARENT_TAG], $parentClassWithoutClass)) { 170 $htmlLink = LinkUtility::deleteDokuWikiClass($htmlLink); 171 } 172 173 if ($data[PluginUtility::PARENT_TAG] == syntax_plugin_combo_button::TAG) { 174 // We could also apply the class ie btn-secondary ... 175 $htmlLink = LinkUtility::inheritColorFromParent($htmlLink); 176 } 177 } 178 $renderer->doc .= $htmlLink; 179 180 return true; 181 break; 182 183 184 case 'metadata': 185 186 /** 187 * Keep track of the backlinks ie meta['relation']['references'] 188 * @var Doku_Renderer_metadata $renderer 189 */ 190 if (isset($data[PluginUtility::ATTRIBUTES])) { 191 $attributes = $data[PluginUtility::ATTRIBUTES]; 192 } else { 193 $attributes = $data; 194 } 195 LinkUtility::handleMetadata($renderer, $attributes); 196 197 return true; 198 break; 199 200 case Analytics::RENDERER_FORMAT: 201 /** 202 * 203 * @var renderer_plugin_combo_analytics $renderer 204 */ 205 $attributes = $data[PluginUtility::ATTRIBUTES]; 206 LinkUtility::processLinkStats($attributes, $renderer->stats); 207 break; 208 209 } 210 // unsupported $mode 211 return false; 212 } 213 214 215} 216 217