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 $id = $attributes[LinkUtility::ATTRIBUTE_ID]; 147 $name = $attributes[LinkUtility::ATTRIBUTE_NAME]; 148 $type = $attributes[LinkUtility::ATTRIBUTE_TYPE]; 149 $link = new LinkUtility($id); 150 if ($name!=null) { 151 $link->setName($name); 152 } 153 $link->setType($type); 154 155 /** 156 * Render the link 157 */ 158 $htmlLink = $link->render($renderer); 159 160 /** 161 * Extra styling for internal link 162 */ 163 if ($link->getType()==LinkUtility::TYPE_INTERNAL) { 164 $parentClassWithoutClass = array( 165 syntax_plugin_combo_button::TAG, 166 syntax_plugin_combo_cite::TAG, 167 syntax_plugin_combo_dropdown::TAG, 168 syntax_plugin_combo_listitem::TAG, 169 syntax_plugin_combo_preformatted::TAG 170 ); 171 $internalPage = $link->getInternalPage(); 172 if ($internalPage->existInFs() && in_array($data[PluginUtility::PARENT_TAG], $parentClassWithoutClass)) { 173 $htmlLink = LinkUtility::deleteDokuWikiClass($htmlLink); 174 } 175 } 176 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 /** 183 * Add it to the rendering 184 */ 185 $renderer->doc .= $htmlLink; 186 187 return true; 188 break; 189 190 case 191 'metadata': 192 193 /** 194 * Keep track of the backlinks ie meta['relation']['references'] 195 * @var Doku_Renderer_metadata $renderer 196 */ 197 if (isset($data[PluginUtility::ATTRIBUTES])) { 198 $attributes = $data[PluginUtility::ATTRIBUTES]; 199 } else { 200 $attributes = $data; 201 } 202 LinkUtility::handleMetadata($renderer, $attributes); 203 204 return true; 205 break; 206 207 case Analytics::RENDERER_FORMAT: 208 /** 209 * 210 * @var renderer_plugin_combo_analytics $renderer 211 */ 212 $attributes = $data[PluginUtility::ATTRIBUTES]; 213 LinkUtility::processLinkStats($attributes, $renderer->stats); 214 break; 215 216 } 217 // unsupported $mode 218 return false; 219 } 220 221 222} 223 224