1<?php 2 3 4use ComboStrap\DokuPath; 5use ComboStrap\LogUtility; 6use ComboStrap\MediaLink; 7use ComboStrap\PluginUtility; 8use ComboStrap\Tag; 9 10 11if (!defined('DOKU_INC')) die(); 12 13 14/** 15 * Media 16 * 17 * Takes over the {@link \dokuwiki\Parsing\ParserMode\Media media mode} 18 * that is processed by {@link Doku_Handler_Parse_Media} 19 * 20 * 21 * 22 * It can be a internal / external media 23 */ 24class syntax_plugin_combo_media extends DokuWiki_Syntax_Plugin 25{ 26 27 28 const TAG = "media"; 29 30 /** 31 * Used in the move plugin 32 * !!! The two last word of the plugin class !!! 33 */ 34 const COMPONENT = 'combo_' . self::TAG; 35 36 /** 37 * The attribute that defines if the image is the first image in 38 * the component 39 * 40 */ 41 const IS_FIRST_IMAGE_KEY = "isFirstImage"; 42 43 /** 44 * Found at {@link \dokuwiki\Parsing\ParserMode\Media} 45 */ 46 const MEDIA_PATTERN = "\{\{(?:[^>\}]|(?:\}[^\}]))+\}\}"; 47 48 /** 49 * Enable or disable the image 50 */ 51 const CONF_IMAGE_ENABLE = "imageEnable"; 52 53 54 function getType() 55 { 56 return 'formatting'; 57 } 58 59 /** 60 * How Dokuwiki will add P element 61 * 62 * * 'normal' - The plugin can be used inside paragraphs (inline) 63 * * 'block' - Open paragraphs need to be closed before plugin output - block should not be inside paragraphs 64 * * 'stack' - Special case. Plugin wraps other paragraphs. - Stacks can contain paragraphs 65 * 66 * @see DokuWiki_Syntax_Plugin::getPType() 67 */ 68 function getPType() 69 { 70 /** 71 * An image is not a block (it can be inside paragraph) 72 */ 73 return 'normal'; 74 } 75 76 function getAllowedTypes() 77 { 78 return array('substition', 'formatting', 'disabled'); 79 } 80 81 /** 82 * It should be less than {@link \dokuwiki\Parsing\ParserMode\Media::getSort()} 83 * (It was 320 at the time of writing this code) 84 * @return int 85 * 86 */ 87 function getSort() 88 { 89 return 319; 90 } 91 92 93 function connectTo($mode) 94 { 95 $enable = $this->getConf(self::CONF_IMAGE_ENABLE, 1); 96 if (!$enable) { 97 98 // Inside a card, we need to take over and enable it 99 $modes = [ 100 PluginUtility::getModeForComponent(syntax_plugin_combo_card::TAG), 101 ]; 102 $enable = in_array($mode, $modes); 103 } 104 105 if ($enable) { 106 $this->Lexer->addSpecialPattern(self::MEDIA_PATTERN, $mode, PluginUtility::getModeForComponent($this->getPluginComponent())); 107 } 108 } 109 110 111 function handle($match, $state, $pos, Doku_Handler $handler) 112 { 113 114 switch ($state) { 115 116 117 // As this is a container, this cannot happens but yeah, now, you know 118 case DOKU_LEXER_SPECIAL : 119 $media = MediaLink::createFromRenderMatch($match); 120 $attributes = $media->toCallStackArray(); 121 $tag = new Tag(self::TAG, $attributes, $state, $handler); 122 $parent = $tag->getParent(); 123 $parentTag = ""; 124 if (!empty($parent)) { 125 $parentTag = $parent->getName(); 126 if ($parentTag == syntax_plugin_combo_link::TAG) { 127 /** 128 * The image is in a link, we don't want another link 129 * to the image 130 */ 131 $attributes[MediaLink::LINKING_KEY] = MediaLink::LINKING_NOLINK_VALUE; 132 } 133 } 134 $isFirstSibling = $tag->isFirstMeaningFullSibling(); 135 return array( 136 PluginUtility::STATE => $state, 137 PluginUtility::ATTRIBUTES => $attributes, 138 PluginUtility::CONTEXT => $parentTag, 139 self::IS_FIRST_IMAGE_KEY => $isFirstSibling 140 ); 141 142 143 } 144 return array(); 145 146 } 147 148 /** 149 * Render the output 150 * @param string $format 151 * @param Doku_Renderer $renderer 152 * @param array $data - what the function handle() return'ed 153 * @return boolean - rendered correctly? (however, returned value is not used at the moment) 154 * @see DokuWiki_Syntax_Plugin::render() 155 * 156 * 157 */ 158 function render($format, Doku_Renderer $renderer, $data) 159 { 160 161 $attributes = $data[PluginUtility::ATTRIBUTES]; 162 switch ($format) { 163 164 case 'xhtml': 165 166 /** @var Doku_Renderer_xhtml $renderer */ 167 $attributes = $data[PluginUtility::ATTRIBUTES]; 168 $media = MediaLink::createFromCallStackArray($attributes); 169 if ($media->getScheme() == DokuPath::LOCAL_SCHEME) { 170 $media = MediaLink::createFromCallStackArray($attributes, $renderer->date_at); 171 if ($media->isImage()) { 172 $renderer->doc .= $media->renderMediaTagWithLink(); 173 return true; 174 } 175 } 176 177 /** 178 * This is not an local internal media image (a video or an url image) 179 * Dokuwiki takes over 180 */ 181 $type = $attributes[MediaLink::MEDIA_DOKUWIKI_TYPE]; 182 $src = $attributes['src']; 183 $title = $attributes['title']; 184 $align = $attributes['align']; 185 $width = $attributes['width']; 186 $height = $attributes['height']; 187 $cache = $attributes['cache']; 188 if ($cache == null) { 189 // Dokuwiki needs a value 190 // If their is no value it will output it without any value 191 // in the query string. 192 $cache = "cache"; 193 } 194 $linking = $attributes['linking']; 195 switch ($type) { 196 case MediaLink::INTERNAL_MEDIA_CALL_NAME: 197 $renderer->doc .= $renderer->internalmedia($src, $title, $align, $width, $height, $cache, $linking, true); 198 break; 199 case MediaLink::EXTERNAL_MEDIA_CALL_NAME: 200 $renderer->doc .= $renderer->externalmedia($src, $title, $align, $width, $height, $cache, $linking, true); 201 break; 202 default: 203 LogUtility::msg("The dokuwiki media type ($type) is unknown"); 204 break; 205 } 206 207 return true; 208 209 case "metadata": 210 211 /** 212 * Keep track of the metadata 213 * @var Doku_Renderer_metadata $renderer 214 */ 215 self::registerImageMeta($attributes, $renderer); 216 return true; 217 218 } 219 // unsupported $mode 220 return false; 221 } 222 223 /** 224 * @param array $attributes 225 * @param Doku_Renderer_metadata $renderer 226 */ 227 static public function registerImageMeta($attributes, $renderer) 228 { 229 $type = $attributes[MediaLink::MEDIA_DOKUWIKI_TYPE]; 230 $src = $attributes['src']; 231 if ($src == null) { 232 $src = $attributes[DokuPath::PATH_ATTRIBUTE]; 233 } 234 $title = $attributes['title']; 235 $align = $attributes['align']; 236 $width = $attributes['width']; 237 $height = $attributes['height']; 238 $cache = $attributes['cache']; // Cache: https://www.dokuwiki.org/images#caching 239 $linking = $attributes['linking']; 240 241 switch ($type) { 242 case MediaLink::INTERNAL_MEDIA_CALL_NAME: 243 $renderer->internalmedia($src, $title, $align, $width, $height, $cache, $linking); 244 break; 245 case MediaLink::EXTERNAL_MEDIA_CALL_NAME: 246 $renderer->externalmedia($src, $title, $align, $width, $height, $cache, $linking); 247 break; 248 default: 249 LogUtility::msg("The dokuwiki media type ($type) for metadata registration is unknown"); 250 break; 251 } 252 253 } 254 255 256} 257 258