121913ab3SNickeau<?php 221913ab3SNickeau 321913ab3SNickeau 4*e8b2ff59SNickeauuse ComboStrap\Analytics; 523723136Sgerardnicouse ComboStrap\DokuPath; 623723136Sgerardnicouse ComboStrap\LogUtility; 723723136Sgerardnicouse ComboStrap\MediaLink; 821913ab3SNickeauuse ComboStrap\PluginUtility; 921913ab3SNickeauuse ComboStrap\Tag; 1021913ab3SNickeau 1121913ab3SNickeau 1221913ab3SNickeauif (!defined('DOKU_INC')) die(); 1321913ab3SNickeau 1421913ab3SNickeau 1521913ab3SNickeau/** 1623723136Sgerardnico * Media 1723723136Sgerardnico * 1823723136Sgerardnico * Takes over the {@link \dokuwiki\Parsing\ParserMode\Media media mode} 1923723136Sgerardnico * that is processed by {@link Doku_Handler_Parse_Media} 2023723136Sgerardnico * 2123723136Sgerardnico * 2223723136Sgerardnico * 2323723136Sgerardnico * It can be a internal / external media 2421913ab3SNickeau */ 2521913ab3SNickeauclass syntax_plugin_combo_media extends DokuWiki_Syntax_Plugin 2621913ab3SNickeau{ 2721913ab3SNickeau 2821913ab3SNickeau 2921913ab3SNickeau const TAG = "media"; 3021913ab3SNickeau 3121913ab3SNickeau /** 3221913ab3SNickeau * Used in the move plugin 3321913ab3SNickeau * !!! The two last word of the plugin class !!! 3421913ab3SNickeau */ 3521913ab3SNickeau const COMPONENT = 'combo_' . self::TAG; 3621913ab3SNickeau 3721913ab3SNickeau /** 3821913ab3SNickeau * The attribute that defines if the image is the first image in 3921913ab3SNickeau * the component 4021913ab3SNickeau * 4121913ab3SNickeau */ 4221913ab3SNickeau const IS_FIRST_IMAGE_KEY = "isFirstImage"; 4321913ab3SNickeau 4421913ab3SNickeau /** 4523723136Sgerardnico * Found at {@link \dokuwiki\Parsing\ParserMode\Media} 4621913ab3SNickeau */ 4723723136Sgerardnico const MEDIA_PATTERN = "\{\{(?:[^>\}]|(?:\}[^\}]))+\}\}"; 4821913ab3SNickeau 49531e725cSNickeau /** 50531e725cSNickeau * Enable or disable the image 51531e725cSNickeau */ 52531e725cSNickeau const CONF_IMAGE_ENABLE = "imageEnable"; 53531e725cSNickeau 5421913ab3SNickeau 5521913ab3SNickeau function getType() 5621913ab3SNickeau { 5721913ab3SNickeau return 'formatting'; 5821913ab3SNickeau } 5921913ab3SNickeau 6021913ab3SNickeau /** 6121913ab3SNickeau * How Dokuwiki will add P element 6221913ab3SNickeau * 6321913ab3SNickeau * * 'normal' - The plugin can be used inside paragraphs (inline) 6421913ab3SNickeau * * 'block' - Open paragraphs need to be closed before plugin output - block should not be inside paragraphs 6521913ab3SNickeau * * 'stack' - Special case. Plugin wraps other paragraphs. - Stacks can contain paragraphs 6621913ab3SNickeau * 6721913ab3SNickeau * @see DokuWiki_Syntax_Plugin::getPType() 6821913ab3SNickeau */ 6921913ab3SNickeau function getPType() 7021913ab3SNickeau { 7123723136Sgerardnico /** 7223723136Sgerardnico * An image is not a block (it can be inside paragraph) 7323723136Sgerardnico */ 7421913ab3SNickeau return 'normal'; 7521913ab3SNickeau } 7621913ab3SNickeau 7721913ab3SNickeau function getAllowedTypes() 7821913ab3SNickeau { 7921913ab3SNickeau return array('substition', 'formatting', 'disabled'); 8021913ab3SNickeau } 8121913ab3SNickeau 8223723136Sgerardnico /** 8323723136Sgerardnico * It should be less than {@link \dokuwiki\Parsing\ParserMode\Media::getSort()} 8423723136Sgerardnico * (It was 320 at the time of writing this code) 8523723136Sgerardnico * @return int 8623723136Sgerardnico * 8723723136Sgerardnico */ 8821913ab3SNickeau function getSort() 8921913ab3SNickeau { 9023723136Sgerardnico return 319; 9121913ab3SNickeau } 9221913ab3SNickeau 9321913ab3SNickeau 9421913ab3SNickeau function connectTo($mode) 9521913ab3SNickeau { 96531e725cSNickeau $enable = $this->getConf(self::CONF_IMAGE_ENABLE, 1); 9721913ab3SNickeau if (!$enable) { 9821913ab3SNickeau 9921913ab3SNickeau // Inside a card, we need to take over and enable it 10021913ab3SNickeau $modes = [ 1019337a630SNickeau PluginUtility::getModeFromTag(syntax_plugin_combo_card::TAG), 10221913ab3SNickeau ]; 10321913ab3SNickeau $enable = in_array($mode, $modes); 10421913ab3SNickeau } 10521913ab3SNickeau 10621913ab3SNickeau if ($enable) { 1079337a630SNickeau $this->Lexer->addSpecialPattern(self::MEDIA_PATTERN, $mode, PluginUtility::getModeFromTag($this->getPluginComponent())); 10821913ab3SNickeau } 10921913ab3SNickeau } 11021913ab3SNickeau 11121913ab3SNickeau 11221913ab3SNickeau function handle($match, $state, $pos, Doku_Handler $handler) 11321913ab3SNickeau { 11421913ab3SNickeau 11521913ab3SNickeau switch ($state) { 11621913ab3SNickeau 11721913ab3SNickeau 11821913ab3SNickeau // As this is a container, this cannot happens but yeah, now, you know 11921913ab3SNickeau case DOKU_LEXER_SPECIAL : 12023723136Sgerardnico $media = MediaLink::createFromRenderMatch($match); 12121913ab3SNickeau $attributes = $media->toCallStackArray(); 12221913ab3SNickeau $tag = new Tag(self::TAG, $attributes, $state, $handler); 12321913ab3SNickeau $parent = $tag->getParent(); 12421913ab3SNickeau $parentTag = ""; 12521913ab3SNickeau if (!empty($parent)) { 12621913ab3SNickeau $parentTag = $parent->getName(); 12721913ab3SNickeau if ($parentTag == syntax_plugin_combo_link::TAG) { 12821913ab3SNickeau /** 12921913ab3SNickeau * The image is in a link, we don't want another link 13021913ab3SNickeau * to the image 13121913ab3SNickeau */ 132a6bf47aaSNickeau $attributes[MediaLink::LINKING_KEY] = MediaLink::LINKING_NOLINK_VALUE; 13321913ab3SNickeau } 13421913ab3SNickeau } 13521913ab3SNickeau $isFirstSibling = $tag->isFirstMeaningFullSibling(); 13621913ab3SNickeau return array( 13721913ab3SNickeau PluginUtility::STATE => $state, 13821913ab3SNickeau PluginUtility::ATTRIBUTES => $attributes, 13921913ab3SNickeau PluginUtility::CONTEXT => $parentTag, 14021913ab3SNickeau self::IS_FIRST_IMAGE_KEY => $isFirstSibling 14121913ab3SNickeau ); 14221913ab3SNickeau 14321913ab3SNickeau 14421913ab3SNickeau } 14521913ab3SNickeau return array(); 14621913ab3SNickeau 14721913ab3SNickeau } 14821913ab3SNickeau 14921913ab3SNickeau /** 15021913ab3SNickeau * Render the output 15121913ab3SNickeau * @param string $format 15221913ab3SNickeau * @param Doku_Renderer $renderer 15321913ab3SNickeau * @param array $data - what the function handle() return'ed 15421913ab3SNickeau * @return boolean - rendered correctly? (however, returned value is not used at the moment) 15521913ab3SNickeau * @see DokuWiki_Syntax_Plugin::render() 15621913ab3SNickeau * 15721913ab3SNickeau * 15821913ab3SNickeau */ 15921913ab3SNickeau function render($format, Doku_Renderer $renderer, $data) 16021913ab3SNickeau { 16121913ab3SNickeau 16221913ab3SNickeau $attributes = $data[PluginUtility::ATTRIBUTES]; 16321913ab3SNickeau switch ($format) { 16421913ab3SNickeau 16521913ab3SNickeau case 'xhtml': 16621913ab3SNickeau 16721913ab3SNickeau /** @var Doku_Renderer_xhtml $renderer */ 16821913ab3SNickeau $attributes = $data[PluginUtility::ATTRIBUTES]; 16923723136Sgerardnico $media = MediaLink::createFromCallStackArray($attributes); 17023723136Sgerardnico if ($media->getScheme() == DokuPath::LOCAL_SCHEME) { 17123723136Sgerardnico $media = MediaLink::createFromCallStackArray($attributes, $renderer->date_at); 17221913ab3SNickeau if ($media->isImage()) { 1739337a630SNickeau /** 1749337a630SNickeau * We don't support crop 1759337a630SNickeau */ 1769337a630SNickeau $crop = false; 1779337a630SNickeau if ($media->getRequestedWidth() != null && $media->getRequestedHeight() != null) { 1789337a630SNickeau /** 1799337a630SNickeau * Width of 0 = resizing by height (supported) 1809337a630SNickeau */ 1819337a630SNickeau if ($media->getRequestedWidth() != "0") { 1829337a630SNickeau $crop = true; 1839337a630SNickeau } 1849337a630SNickeau } 1859337a630SNickeau if (!$crop) { 18621913ab3SNickeau $renderer->doc .= $media->renderMediaTagWithLink(); 18723723136Sgerardnico return true; 18823723136Sgerardnico } 18923723136Sgerardnico } 1909337a630SNickeau } 19121913ab3SNickeau 19221913ab3SNickeau /** 19323723136Sgerardnico * This is not an local internal media image (a video or an url image) 19421913ab3SNickeau * Dokuwiki takes over 19521913ab3SNickeau */ 196531e725cSNickeau $type = $attributes[MediaLink::MEDIA_DOKUWIKI_TYPE]; 19721913ab3SNickeau $src = $attributes['src']; 19821913ab3SNickeau $title = $attributes['title']; 19921913ab3SNickeau $align = $attributes['align']; 20021913ab3SNickeau $width = $attributes['width']; 20121913ab3SNickeau $height = $attributes['height']; 20221913ab3SNickeau $cache = $attributes['cache']; 203a6bf47aaSNickeau if ($cache == null) { 204a6bf47aaSNickeau // Dokuwiki needs a value 205a6bf47aaSNickeau // If their is no value it will output it without any value 206a6bf47aaSNickeau // in the query string. 207a6bf47aaSNickeau $cache = "cache"; 208a6bf47aaSNickeau } 20921913ab3SNickeau $linking = $attributes['linking']; 21023723136Sgerardnico switch ($type) { 211531e725cSNickeau case MediaLink::INTERNAL_MEDIA_CALL_NAME: 21221913ab3SNickeau $renderer->doc .= $renderer->internalmedia($src, $title, $align, $width, $height, $cache, $linking, true); 21323723136Sgerardnico break; 214531e725cSNickeau case MediaLink::EXTERNAL_MEDIA_CALL_NAME: 21523723136Sgerardnico $renderer->doc .= $renderer->externalmedia($src, $title, $align, $width, $height, $cache, $linking, true); 21623723136Sgerardnico break; 21723723136Sgerardnico default: 21823723136Sgerardnico LogUtility::msg("The dokuwiki media type ($type) is unknown"); 21923723136Sgerardnico break; 22021913ab3SNickeau } 22121913ab3SNickeau 22223723136Sgerardnico return true; 22321913ab3SNickeau 2249337a630SNickeau case 2259337a630SNickeau "metadata": 22621913ab3SNickeau 22721913ab3SNickeau /** 22821913ab3SNickeau * Keep track of the metadata 22921913ab3SNickeau * @var Doku_Renderer_metadata $renderer 23021913ab3SNickeau */ 23121913ab3SNickeau self::registerImageMeta($attributes, $renderer); 23223723136Sgerardnico return true; 23321913ab3SNickeau 234*e8b2ff59SNickeau case renderer_plugin_combo_analytics::RENDERER_FORMAT: 235*e8b2ff59SNickeau 236*e8b2ff59SNickeau /** 237*e8b2ff59SNickeau * Special pattern call 238*e8b2ff59SNickeau * @var renderer_plugin_combo_analytics $renderer 239*e8b2ff59SNickeau */ 240*e8b2ff59SNickeau $attributes = $data[PluginUtility::ATTRIBUTES]; 241*e8b2ff59SNickeau $media = MediaLink::createFromCallStackArray($attributes); 242*e8b2ff59SNickeau $renderer->stats[Analytics::MEDIAS_COUNT]++; 243*e8b2ff59SNickeau $scheme = $media->getScheme(); 244*e8b2ff59SNickeau switch($scheme){ 245*e8b2ff59SNickeau case DokuPath::LOCAL_SCHEME: 246*e8b2ff59SNickeau $renderer->stats[Analytics::INTERNAL_MEDIAS_COUNT]++; 247*e8b2ff59SNickeau if(!$media->exists()){ 248*e8b2ff59SNickeau $renderer->stats[Analytics::INTERNAL_BROKEN_MEDIAS_COUNT]++; 249*e8b2ff59SNickeau } 250*e8b2ff59SNickeau break; 251*e8b2ff59SNickeau case DokuPath::INTERNET_SCHEME: 252*e8b2ff59SNickeau $renderer->stats[Analytics::EXTERNAL_MEDIAS_COUNT]++; 253*e8b2ff59SNickeau break; 254*e8b2ff59SNickeau } 255*e8b2ff59SNickeau return true; 256*e8b2ff59SNickeau 25721913ab3SNickeau } 25821913ab3SNickeau // unsupported $mode 25921913ab3SNickeau return false; 26021913ab3SNickeau } 26121913ab3SNickeau 26221913ab3SNickeau /** 26321913ab3SNickeau * @param array $attributes 26421913ab3SNickeau * @param Doku_Renderer_metadata $renderer 26521913ab3SNickeau */ 26621913ab3SNickeau static public function registerImageMeta($attributes, $renderer) 26721913ab3SNickeau { 268531e725cSNickeau $type = $attributes[MediaLink::MEDIA_DOKUWIKI_TYPE]; 26921913ab3SNickeau $src = $attributes['src']; 270531e725cSNickeau if ($src == null) { 271531e725cSNickeau $src = $attributes[DokuPath::PATH_ATTRIBUTE]; 272531e725cSNickeau } 27321913ab3SNickeau $title = $attributes['title']; 27421913ab3SNickeau $align = $attributes['align']; 27521913ab3SNickeau $width = $attributes['width']; 27621913ab3SNickeau $height = $attributes['height']; 27721913ab3SNickeau $cache = $attributes['cache']; // Cache: https://www.dokuwiki.org/images#caching 27821913ab3SNickeau $linking = $attributes['linking']; 27923723136Sgerardnico 28023723136Sgerardnico switch ($type) { 281531e725cSNickeau case MediaLink::INTERNAL_MEDIA_CALL_NAME: 28221913ab3SNickeau $renderer->internalmedia($src, $title, $align, $width, $height, $cache, $linking); 28323723136Sgerardnico break; 284531e725cSNickeau case MediaLink::EXTERNAL_MEDIA_CALL_NAME: 28523723136Sgerardnico $renderer->externalmedia($src, $title, $align, $width, $height, $cache, $linking); 28623723136Sgerardnico break; 28723723136Sgerardnico default: 28823723136Sgerardnico LogUtility::msg("The dokuwiki media type ($type) for metadata registration is unknown"); 28923723136Sgerardnico break; 29023723136Sgerardnico } 29123723136Sgerardnico 29221913ab3SNickeau } 29321913ab3SNickeau 29421913ab3SNickeau 29521913ab3SNickeau} 29621913ab3SNickeau 297