1*04fd306cSNickeau<?php 2*04fd306cSNickeau 3*04fd306cSNickeau 4*04fd306cSNickeaunamespace ComboStrap; 5*04fd306cSNickeau 6*04fd306cSNickeau 7*04fd306cSNickeauuse ComboStrap\TagAttribute\Align; 8*04fd306cSNickeauuse ComboStrap\TagAttribute\Animation; 9*04fd306cSNickeauuse ComboStrap\TagAttribute\Shadow; 10*04fd306cSNickeauuse ComboStrap\Web\Url; 11*04fd306cSNickeauuse Doku_Renderer_metadata; 12*04fd306cSNickeauuse Doku_Renderer_xhtml; 13*04fd306cSNickeauuse renderer_plugin_combo_analytics; 14*04fd306cSNickeauuse syntax_plugin_combo_media; 15*04fd306cSNickeau 16*04fd306cSNickeau/** 17*04fd306cSNickeau * This class represents a media markup: 18*04fd306cSNickeau * - with a {@link MediaMarkup::getFetcher() fetcher} 19*04fd306cSNickeau * - and {@link MediaMarkup::getExtraMediaTagAttributes() tag/styling attributes} 20*04fd306cSNickeau * 21*04fd306cSNickeau * You can create it: 22*04fd306cSNickeau * * via a {@link MediaMarkup::createFromRef() Markup Ref} (The string ref in the document) 23*04fd306cSNickeau * * via a {@link MediaMarkup::createFromFetcher() Fetcher} 24*04fd306cSNickeau * * via a {@link MediaMarkup::createFromFetchUrl() Fetch Url} 25*04fd306cSNickeau * * via a {@link MediaMarkup::createFromCallStackArray() callstack array} of {@link syntax_plugin_combo_media::render()} 26*04fd306cSNickeau * * via a {@link MediaMarkup::createFromMarkup() string match} of {@link syntax_plugin_combo_media::handle()} 27*04fd306cSNickeau * 28*04fd306cSNickeau * 29*04fd306cSNickeau */ 30*04fd306cSNickeauclass MediaMarkup 31*04fd306cSNickeau{ 32*04fd306cSNickeau 33*04fd306cSNickeau /** 34*04fd306cSNickeau * No name as this is {{ --- }} 35*04fd306cSNickeau */ 36*04fd306cSNickeau public const TAG = "media"; 37*04fd306cSNickeau 38*04fd306cSNickeau /** 39*04fd306cSNickeau * The dokuwiki type and mode name 40*04fd306cSNickeau * (ie call) 41*04fd306cSNickeau * * ie {@link MediaMarkup::EXTERNAL_MEDIA_CALL_NAME} 42*04fd306cSNickeau * or {@link MediaMarkup::INTERNAL_MEDIA_CALL_NAME} 43*04fd306cSNickeau * 44*04fd306cSNickeau * The dokuwiki type (internalmedia/externalmedia) 45*04fd306cSNickeau * 46*04fd306cSNickeau */ 47*04fd306cSNickeau public const MEDIA_DOKUWIKI_TYPE = 'dokuwiki_media_type'; 48*04fd306cSNickeau public const EXTERNAL_MEDIA_CALL_NAME = "externalmedia"; 49*04fd306cSNickeau public const INTERNAL_MEDIA_CALL_NAME = "internalmedia"; 50*04fd306cSNickeau 51*04fd306cSNickeau /** 52*04fd306cSNickeau * Link value: 53*04fd306cSNickeau * * 'nolink' 54*04fd306cSNickeau * * 'direct': directly to the image 55*04fd306cSNickeau * * 'linkonly': show only a url 56*04fd306cSNickeau * * 'details': go to the details media viewer 57*04fd306cSNickeau * 58*04fd306cSNickeau * @var 59*04fd306cSNickeau */ 60*04fd306cSNickeau public const LINKING_KEY = 'linking'; 61*04fd306cSNickeau public const LINKING_DETAILS_VALUE = 'details'; 62*04fd306cSNickeau public const LINKING_DIRECT_VALUE = 'direct'; 63*04fd306cSNickeau /** 64*04fd306cSNickeau * Only used by Dokuwiki 65*04fd306cSNickeau * Contains the path and eventually an anchor 66*04fd306cSNickeau * never query parameters 67*04fd306cSNickeau */ 68*04fd306cSNickeau public const DOKUWIKI_SRC = "src"; 69*04fd306cSNickeau public const LINKING_LINKONLY_VALUE = "linkonly"; 70*04fd306cSNickeau public const LINKING_NOLINK_VALUE = 'nolink'; 71*04fd306cSNickeau /** 72*04fd306cSNickeau * Default image linking value 73*04fd306cSNickeau */ 74*04fd306cSNickeau public const CONF_DEFAULT_LINKING = "defaultImageLinking"; 75*04fd306cSNickeau 76*04fd306cSNickeau const CANONICAL = "media"; 77*04fd306cSNickeau 78*04fd306cSNickeau /** 79*04fd306cSNickeau * This attributes does not apply 80*04fd306cSNickeau * to a fetch (URL) 81*04fd306cSNickeau * They are only for the tag (img, svg, ...) 82*04fd306cSNickeau * or internal 83*04fd306cSNickeau */ 84*04fd306cSNickeau public const STYLE_ATTRIBUTES = [ 85*04fd306cSNickeau TagAttributes::TITLE_KEY, 86*04fd306cSNickeau Hover::ON_HOVER_ATTRIBUTE, 87*04fd306cSNickeau Animation::ON_VIEW_ATTRIBUTE, 88*04fd306cSNickeau Shadow::SHADOW_ATT, 89*04fd306cSNickeau Opacity::OPACITY_ATTRIBUTE, 90*04fd306cSNickeau TagAttributes::CLASS_KEY, 91*04fd306cSNickeau ]; 92*04fd306cSNickeau 93*04fd306cSNickeau /** 94*04fd306cSNickeau * An attribute to set the class of the link if any 95*04fd306cSNickeau */ 96*04fd306cSNickeau public const LINK_CLASS_ATTRIBUTE = "link-class"; 97*04fd306cSNickeau 98*04fd306cSNickeau 99*04fd306cSNickeau private ?string $align = null; 100*04fd306cSNickeau private ?string $label = null; 101*04fd306cSNickeau private ?MarkupRef $markupRef = null; 102*04fd306cSNickeau private ?string $linking = null; 103*04fd306cSNickeau private ?string $lazyLoadMethod = null; 104*04fd306cSNickeau private TagAttributes $extraMediaTagAttributes; 105*04fd306cSNickeau private ?string $linkingClass = null; 106*04fd306cSNickeau private IFetcher $fetcher; 107*04fd306cSNickeau private Url $fetchUrl; 108*04fd306cSNickeau 109*04fd306cSNickeau private function __construct() 110*04fd306cSNickeau { 111*04fd306cSNickeau $this->extraMediaTagAttributes = TagAttributes::createEmpty(); 112*04fd306cSNickeau } 113*04fd306cSNickeau 114*04fd306cSNickeau 115*04fd306cSNickeau /** 116*04fd306cSNickeau * Private method use {@link MediaMarkup::createFromRef()} to create a media markup via a ref 117*04fd306cSNickeau * 118*04fd306cSNickeau * Set and parse a media wiki ref that you can found in the first part of a media markup 119*04fd306cSNickeau * 120*04fd306cSNickeau * @param string $markupRef 121*04fd306cSNickeau * @return MediaMarkup 122*04fd306cSNickeau * @throws ExceptionBadArgument 123*04fd306cSNickeau * @throws ExceptionBadSyntax 124*04fd306cSNickeau * @throws ExceptionNotFound 125*04fd306cSNickeau */ 126*04fd306cSNickeau private function setMarkupRef(string $markupRef): MediaMarkup 127*04fd306cSNickeau { 128*04fd306cSNickeau 129*04fd306cSNickeau $markupRef = trim($markupRef); 130*04fd306cSNickeau $this->markupRef = MarkupRef::createMediaFromRef($markupRef); 131*04fd306cSNickeau 132*04fd306cSNickeau $refUrl = $this->markupRef->getUrl(); 133*04fd306cSNickeau $this->setUrl($refUrl); 134*04fd306cSNickeau 135*04fd306cSNickeau return $this; 136*04fd306cSNickeau } 137*04fd306cSNickeau 138*04fd306cSNickeau /** 139*04fd306cSNickeau * @param $callStackArray 140*04fd306cSNickeau * @return MediaMarkup 141*04fd306cSNickeau * @throws ExceptionBadArgument 142*04fd306cSNickeau * @throws ExceptionBadSyntax 143*04fd306cSNickeau * @throws ExceptionNotFound 144*04fd306cSNickeau * @throws ExceptionNotExists 145*04fd306cSNickeau */ 146*04fd306cSNickeau public static function createFromCallStackArray($callStackArray): MediaMarkup 147*04fd306cSNickeau { 148*04fd306cSNickeau 149*04fd306cSNickeau $tagAttributes = TagAttributes::createFromCallStackArray($callStackArray); 150*04fd306cSNickeau $ref = $tagAttributes->getValueAndRemoveIfPresent(MarkupRef::REF_ATTRIBUTE); 151*04fd306cSNickeau if ($ref === null) { 152*04fd306cSNickeau $ref = $tagAttributes->getValueAndRemoveIfPresent(MediaMarkup::DOKUWIKI_SRC); 153*04fd306cSNickeau if ($ref === null) { 154*04fd306cSNickeau throw new ExceptionBadArgument("The media reference was not found in the callstack array", self::CANONICAL); 155*04fd306cSNickeau } 156*04fd306cSNickeau } 157*04fd306cSNickeau return self::createFromRef($ref) 158*04fd306cSNickeau ->buildFromTagAttributes($tagAttributes); 159*04fd306cSNickeau 160*04fd306cSNickeau 161*04fd306cSNickeau } 162*04fd306cSNickeau 163*04fd306cSNickeau /** 164*04fd306cSNickeau * @throws ExceptionBadArgument 165*04fd306cSNickeau * @throws ExceptionBadSyntax 166*04fd306cSNickeau * @throws ExceptionNotExists 167*04fd306cSNickeau * @throws ExceptionNotFound 168*04fd306cSNickeau * @throws ExceptionInternal 169*04fd306cSNickeau */ 170*04fd306cSNickeau public static function createFromFetchUrl(Url $fetchUrl): MediaMarkup 171*04fd306cSNickeau { 172*04fd306cSNickeau return (new MediaMarkup())->setUrl($fetchUrl); 173*04fd306cSNickeau } 174*04fd306cSNickeau 175*04fd306cSNickeau public static function createFromFetcher(IFetcher $fetcher): MediaMarkup 176*04fd306cSNickeau { 177*04fd306cSNickeau return (new MediaMarkup()) 178*04fd306cSNickeau ->setFetcher($fetcher); 179*04fd306cSNickeau } 180*04fd306cSNickeau 181*04fd306cSNickeau public static function renderSpecial(array $data, Doku_Renderer_xhtml $renderer) 182*04fd306cSNickeau { 183*04fd306cSNickeau 184*04fd306cSNickeau $callStackArray = $data[PluginUtility::ATTRIBUTES]; 185*04fd306cSNickeau $display = $callStackArray[Display::DISPLAY]; 186*04fd306cSNickeau if ($display === Display::DISPLAY_NONE_VALUE) { 187*04fd306cSNickeau /** 188*04fd306cSNickeau * Used primarly to not show the featured images 189*04fd306cSNickeau * in the outline {@link Outline::toHtmlSectionOutlineCallsRecurse()} 190*04fd306cSNickeau * for item page 191*04fd306cSNickeau * But we keep the metadata to move them if any 192*04fd306cSNickeau */ 193*04fd306cSNickeau return false; 194*04fd306cSNickeau } 195*04fd306cSNickeau 196*04fd306cSNickeau /** @var Doku_Renderer_xhtml $renderer */ 197*04fd306cSNickeau try { 198*04fd306cSNickeau $mediaMarkup = MediaMarkup::createFromCallStackArray($callStackArray); 199*04fd306cSNickeau } catch (ExceptionCompile $e) { 200*04fd306cSNickeau return $e->getMessage(); 201*04fd306cSNickeau } 202*04fd306cSNickeau 203*04fd306cSNickeau 204*04fd306cSNickeau if ( 205*04fd306cSNickeau $mediaMarkup->getInternalExternalType() === MediaMarkup::INTERNAL_MEDIA_CALL_NAME 206*04fd306cSNickeau ) { 207*04fd306cSNickeau try { 208*04fd306cSNickeau $isImage = $mediaMarkup->getFetcher()->getMime()->isImage(); 209*04fd306cSNickeau } catch (\Exception $e) { 210*04fd306cSNickeau $isImage = false; 211*04fd306cSNickeau } 212*04fd306cSNickeau if ($isImage) { 213*04fd306cSNickeau try { 214*04fd306cSNickeau return MediaLink::createFromMediaMarkup($mediaMarkup)->renderMediaTag(); 215*04fd306cSNickeau } catch (ExceptionCompile $e) { 216*04fd306cSNickeau if (PluginUtility::isDevOrTest()) { 217*04fd306cSNickeau throw new ExceptionRuntime("Media Rendering Error. {$e->getMessage()}", MediaLink::CANONICAL, 0, $e); 218*04fd306cSNickeau } else { 219*04fd306cSNickeau $errorClass = syntax_plugin_combo_media::SVG_RENDERING_ERROR_CLASS; 220*04fd306cSNickeau $message = "Media ({$mediaMarkup}). Error while rendering: {$e->getMessage()}"; 221*04fd306cSNickeau LogUtility::msg($message, LogUtility::LVL_MSG_ERROR, MediaLink::CANONICAL); 222*04fd306cSNickeau return "<span class=\"text-danger $errorClass\">" . hsc(trim($message)) . "</span>"; 223*04fd306cSNickeau 224*04fd306cSNickeau } 225*04fd306cSNickeau } 226*04fd306cSNickeau } 227*04fd306cSNickeau 228*04fd306cSNickeau } 229*04fd306cSNickeau 230*04fd306cSNickeau 231*04fd306cSNickeau /** 232*04fd306cSNickeau * This is not an local internal media image (a video or an url image) 233*04fd306cSNickeau * Dokuwiki takes over 234*04fd306cSNickeau */ 235*04fd306cSNickeau $mediaType = $mediaMarkup->getInternalExternalType(); 236*04fd306cSNickeau try { 237*04fd306cSNickeau $title = $mediaMarkup->getLabel(); 238*04fd306cSNickeau } catch (ExceptionNotFound $e) { 239*04fd306cSNickeau $title = null; 240*04fd306cSNickeau } 241*04fd306cSNickeau try { 242*04fd306cSNickeau $linking = $mediaMarkup->getLinking(); 243*04fd306cSNickeau } catch (ExceptionNotFound $e) { 244*04fd306cSNickeau $linking = null; 245*04fd306cSNickeau } 246*04fd306cSNickeau try { 247*04fd306cSNickeau $align = $mediaMarkup->getAlign(); 248*04fd306cSNickeau } catch (ExceptionNotFound $e) { 249*04fd306cSNickeau $align = null; 250*04fd306cSNickeau } 251*04fd306cSNickeau try { 252*04fd306cSNickeau /** 253*04fd306cSNickeau * We use the markup ref url 254*04fd306cSNickeau * because we don't support http/https (external) url 255*04fd306cSNickeau * And there is therefore no fetcher available 256*04fd306cSNickeau */ 257*04fd306cSNickeau $markupUrl = $mediaMarkup->getMarkupRef()->getUrl(); 258*04fd306cSNickeau 259*04fd306cSNickeau } catch (ExceptionNotFound $e) { 260*04fd306cSNickeau // the 261*04fd306cSNickeau LogUtility::internalError("As the media markup is created from a markup in the syntax component, it should be available"); 262*04fd306cSNickeau return ""; 263*04fd306cSNickeau } 264*04fd306cSNickeau 265*04fd306cSNickeau try { 266*04fd306cSNickeau $src = $mediaMarkup->getSrc(); 267*04fd306cSNickeau } catch (ExceptionNotFound $e) { 268*04fd306cSNickeau LogUtility::internalError("For an external markup, the src should not be empty", self::CANONICAL); 269*04fd306cSNickeau return ""; 270*04fd306cSNickeau } 271*04fd306cSNickeau try { 272*04fd306cSNickeau $isImage = FileSystems::getMime($markupUrl)->isImage(); 273*04fd306cSNickeau } catch (ExceptionNotFound $e) { 274*04fd306cSNickeau $isImage = false; 275*04fd306cSNickeau } 276*04fd306cSNickeau if ($isImage) { 277*04fd306cSNickeau /** 278*04fd306cSNickeau * We need to delete the 279*04fd306cSNickeau * wXh and other properties 280*04fd306cSNickeau * Dokuwiki does not accept it in its function 281*04fd306cSNickeau */ 282*04fd306cSNickeau try { 283*04fd306cSNickeau $src = Url::createEmpty() 284*04fd306cSNickeau ->setScheme($markupUrl->getScheme()) 285*04fd306cSNickeau ->setHost($markupUrl->getHost()) 286*04fd306cSNickeau ->setPath($markupUrl->getPath()) 287*04fd306cSNickeau ->toString(); 288*04fd306cSNickeau } catch (ExceptionNotFound $e) { 289*04fd306cSNickeau 290*04fd306cSNickeau } 291*04fd306cSNickeau } 292*04fd306cSNickeau try { 293*04fd306cSNickeau $width = $markupUrl->getQueryPropertyValue(Dimension::WIDTH_KEY); 294*04fd306cSNickeau } catch 295*04fd306cSNickeau (ExceptionNotFound $e) { 296*04fd306cSNickeau $width = null; 297*04fd306cSNickeau } 298*04fd306cSNickeau try { 299*04fd306cSNickeau $height = $markupUrl->getQueryPropertyValue(Dimension::HEIGHT_KEY); 300*04fd306cSNickeau } catch (ExceptionNotFound $e) { 301*04fd306cSNickeau $height = null; 302*04fd306cSNickeau } 303*04fd306cSNickeau try { 304*04fd306cSNickeau $cache = $markupUrl->getQueryPropertyValue(IFetcherAbs::CACHE_KEY); 305*04fd306cSNickeau } catch (ExceptionNotFound $e) { 306*04fd306cSNickeau // Dokuwiki needs a value 307*04fd306cSNickeau // If their is no value it will output it without any value 308*04fd306cSNickeau // in the query string. 309*04fd306cSNickeau $cache = IFetcherAbs::CACHE_DEFAULT_VALUE; 310*04fd306cSNickeau } 311*04fd306cSNickeau switch ($mediaType) { 312*04fd306cSNickeau case MediaMarkup::INTERNAL_MEDIA_CALL_NAME: 313*04fd306cSNickeau return $renderer->internalmedia($src, $title, $align, $width, $height, $cache, $linking, true); 314*04fd306cSNickeau case MediaMarkup::EXTERNAL_MEDIA_CALL_NAME: 315*04fd306cSNickeau return $renderer->externalmedia($src, $title, $align, $width, $height, $cache, $linking, true); 316*04fd306cSNickeau default: 317*04fd306cSNickeau LogUtility::msg("The dokuwiki media type ($mediaType) is unknown"); 318*04fd306cSNickeau return ""; 319*04fd306cSNickeau } 320*04fd306cSNickeau } 321*04fd306cSNickeau 322*04fd306cSNickeau 323*04fd306cSNickeau /** 324*04fd306cSNickeau * Compliance: src in dokuwiki is the id and the anchor if any 325*04fd306cSNickeau * Dokuwiki does not understand other property and the reference metadata 326*04fd306cSNickeau * may not work if we send back the `ref` 327*04fd306cSNickeau * @throws ExceptionNotFound 328*04fd306cSNickeau */ 329*04fd306cSNickeau public function getSrc(): string 330*04fd306cSNickeau { 331*04fd306cSNickeau $internalExternalType = $this->getInternalExternalType(); 332*04fd306cSNickeau switch ($internalExternalType) { 333*04fd306cSNickeau case MediaMarkup::INTERNAL_MEDIA_CALL_NAME: 334*04fd306cSNickeau /** 335*04fd306cSNickeau * Absolute id because dokuwiki resolve a relatif id 336*04fd306cSNickeau * to the actual namespace 337*04fd306cSNickeau */ 338*04fd306cSNickeau $src = $this->getPath()->toAbsoluteId(); 339*04fd306cSNickeau try { 340*04fd306cSNickeau $src = "$src#{$this->markupRef->getUrl()->getFragment()}"; 341*04fd306cSNickeau } catch (ExceptionNotFound $e) { 342*04fd306cSNickeau // ok 343*04fd306cSNickeau } 344*04fd306cSNickeau return $src; 345*04fd306cSNickeau case MediaMarkup::EXTERNAL_MEDIA_CALL_NAME: 346*04fd306cSNickeau return $this->getMarkupRef()->getRef(); 347*04fd306cSNickeau default: 348*04fd306cSNickeau LogUtility::internalError("The internal/external type value ($internalExternalType) is unknown"); 349*04fd306cSNickeau return $this->getMarkupRef()->getRef(); 350*04fd306cSNickeau } 351*04fd306cSNickeau 352*04fd306cSNickeau } 353*04fd306cSNickeau 354*04fd306cSNickeau /** 355*04fd306cSNickeau * Media Type Needed by Dokuwiki 356*04fd306cSNickeau */ 357*04fd306cSNickeau public function getInternalExternalType(): string 358*04fd306cSNickeau { 359*04fd306cSNickeau try { 360*04fd306cSNickeau // if there is a path, this is internal 361*04fd306cSNickeau // if interwiki this, wiki id, ... 362*04fd306cSNickeau $this->markupRef->getPath(); 363*04fd306cSNickeau return self::INTERNAL_MEDIA_CALL_NAME; 364*04fd306cSNickeau } catch (ExceptionNotFound $e) { 365*04fd306cSNickeau return self::EXTERNAL_MEDIA_CALL_NAME; 366*04fd306cSNickeau } 367*04fd306cSNickeau 368*04fd306cSNickeau } 369*04fd306cSNickeau 370*04fd306cSNickeau 371*04fd306cSNickeau /** 372*04fd306cSNickeau * @throws ExceptionBadSyntax 373*04fd306cSNickeau * @throws ExceptionBadArgument 374*04fd306cSNickeau * @throws ExceptionNotFound 375*04fd306cSNickeau */ 376*04fd306cSNickeau public static function createFromRef(string $markupRef): MediaMarkup 377*04fd306cSNickeau { 378*04fd306cSNickeau return (new MediaMarkup())->setMarkupRef($markupRef); 379*04fd306cSNickeau } 380*04fd306cSNickeau 381*04fd306cSNickeau /** 382*04fd306cSNickeau * Keep track of the metadata 383*04fd306cSNickeau * @param array $data 384*04fd306cSNickeau * @param Doku_Renderer_metadata $renderer 385*04fd306cSNickeau * @return void 386*04fd306cSNickeau */ 387*04fd306cSNickeau public static function metadata(array $data, Doku_Renderer_metadata $renderer) 388*04fd306cSNickeau { 389*04fd306cSNickeau 390*04fd306cSNickeau $tagAttributes = $data[PluginUtility::ATTRIBUTES]; 391*04fd306cSNickeau if ($tagAttributes === null) { 392*04fd306cSNickeau // error on handle 393*04fd306cSNickeau return; 394*04fd306cSNickeau } 395*04fd306cSNickeau syntax_plugin_combo_media::registerImageMeta($tagAttributes, $renderer); 396*04fd306cSNickeau 397*04fd306cSNickeau } 398*04fd306cSNickeau 399*04fd306cSNickeau /** 400*04fd306cSNickeau * Special pattern call 401*04fd306cSNickeau * @param array $data 402*04fd306cSNickeau * @param renderer_plugin_combo_analytics $renderer 403*04fd306cSNickeau * @return void 404*04fd306cSNickeau * @deprecated - for metadata but yeah ... 405*04fd306cSNickeau */ 406*04fd306cSNickeau public static function analytics(array $data, renderer_plugin_combo_analytics $renderer) 407*04fd306cSNickeau { 408*04fd306cSNickeau 409*04fd306cSNickeau $tagAttributes = $data[PluginUtility::ATTRIBUTES]; 410*04fd306cSNickeau syntax_plugin_combo_media::updateStatistics($tagAttributes, $renderer); 411*04fd306cSNickeau 412*04fd306cSNickeau } 413*04fd306cSNickeau 414*04fd306cSNickeau 415*04fd306cSNickeau /** 416*04fd306cSNickeau * @return Url - an url that has query property as a fetch url 417*04fd306cSNickeau * It permits to select the fetch class 418*04fd306cSNickeau * @deprecated use {@link MediaMarkup::getFetcher()}->getUrl instead 419*04fd306cSNickeau */ 420*04fd306cSNickeau public function getFetchUrl(): Url 421*04fd306cSNickeau { 422*04fd306cSNickeau return $this->getFetcher()->getFetchUrl(); 423*04fd306cSNickeau } 424*04fd306cSNickeau 425*04fd306cSNickeau 426*04fd306cSNickeau /** 427*04fd306cSNickeau * @param string $match - the match of the renderer 428*04fd306cSNickeau * @throws ExceptionBadSyntax - if no ref was found 429*04fd306cSNickeau * @throws ExceptionBadArgument 430*04fd306cSNickeau * @throws ExceptionNotFound|ExceptionNotExists 431*04fd306cSNickeau * @throws ExceptionInternal 432*04fd306cSNickeau */ 433*04fd306cSNickeau public static function createFromMarkup(string $match): MediaMarkup 434*04fd306cSNickeau { 435*04fd306cSNickeau 436*04fd306cSNickeau $mediaMarkup = new MediaMarkup(); 437*04fd306cSNickeau 438*04fd306cSNickeau /** 439*04fd306cSNickeau * * Delete the opening and closing character 440*04fd306cSNickeau * * create the url and description 441*04fd306cSNickeau */ 442*04fd306cSNickeau $match = preg_replace(array('/^{{/', '/}}$/u'), '', $match); 443*04fd306cSNickeau $parts = explode('|', $match, 2); 444*04fd306cSNickeau 445*04fd306cSNickeau $ref = $parts[0]; 446*04fd306cSNickeau if ($ref === null) { 447*04fd306cSNickeau throw new ExceptionBadSyntax("No ref was found"); 448*04fd306cSNickeau } 449*04fd306cSNickeau $mediaMarkup->setMarkupRef($ref); 450*04fd306cSNickeau if (isset($parts[1])) { 451*04fd306cSNickeau $mediaMarkup->setLabel($parts[1]); 452*04fd306cSNickeau } 453*04fd306cSNickeau 454*04fd306cSNickeau 455*04fd306cSNickeau /** 456*04fd306cSNickeau * Media Alignment 457*04fd306cSNickeau */ 458*04fd306cSNickeau $rightAlign = (bool)preg_match('/^ /', $ref); 459*04fd306cSNickeau $leftAlign = (bool)preg_match('/ $/', $ref); 460*04fd306cSNickeau $align = null; 461*04fd306cSNickeau // Logic = what's that ;)... 462*04fd306cSNickeau if ($leftAlign & $rightAlign) { 463*04fd306cSNickeau $align = 'center'; 464*04fd306cSNickeau } else if ($rightAlign) { 465*04fd306cSNickeau $align = 'right'; 466*04fd306cSNickeau } else if ($leftAlign) { 467*04fd306cSNickeau $align = 'left'; 468*04fd306cSNickeau } 469*04fd306cSNickeau if ($align !== null) { 470*04fd306cSNickeau $mediaMarkup->setAlign($align); 471*04fd306cSNickeau } 472*04fd306cSNickeau 473*04fd306cSNickeau return $mediaMarkup; 474*04fd306cSNickeau 475*04fd306cSNickeau 476*04fd306cSNickeau } 477*04fd306cSNickeau 478*04fd306cSNickeau public function setAlign(string $align): MediaMarkup 479*04fd306cSNickeau { 480*04fd306cSNickeau $this->align = $align; 481*04fd306cSNickeau return $this; 482*04fd306cSNickeau } 483*04fd306cSNickeau 484*04fd306cSNickeau public function setLabel(string $label): MediaMarkup 485*04fd306cSNickeau { 486*04fd306cSNickeau $this->label = $label; 487*04fd306cSNickeau return $this; 488*04fd306cSNickeau } 489*04fd306cSNickeau 490*04fd306cSNickeau /** 491*04fd306cSNickeau * just FYI, not used 492*04fd306cSNickeau * 493*04fd306cSNickeau * Create an image from dokuwiki {@link Internallink internal call media attributes} 494*04fd306cSNickeau * 495*04fd306cSNickeau * Dokuwiki extracts already the width, height and align property 496*04fd306cSNickeau * @param array $callAttributes 497*04fd306cSNickeau * @return MediaMarkup 498*04fd306cSNickeau */ 499*04fd306cSNickeau public static function createFromIndexAttributes(array $callAttributes) 500*04fd306cSNickeau { 501*04fd306cSNickeau $src = $callAttributes[0]; 502*04fd306cSNickeau $title = $callAttributes[1]; 503*04fd306cSNickeau $align = $callAttributes[2]; 504*04fd306cSNickeau $width = $callAttributes[3]; 505*04fd306cSNickeau $height = $callAttributes[4]; 506*04fd306cSNickeau $cache = $callAttributes[5]; 507*04fd306cSNickeau $linking = $callAttributes[6]; 508*04fd306cSNickeau 509*04fd306cSNickeau $ref = "$src?{$width}x$height&$cache"; 510*04fd306cSNickeau return (new MediaMarkup()) 511*04fd306cSNickeau ->setMarkupRef($ref) 512*04fd306cSNickeau ->setAlign($align) 513*04fd306cSNickeau ->setLabel($title) 514*04fd306cSNickeau ->setLinking($linking); 515*04fd306cSNickeau 516*04fd306cSNickeau } 517*04fd306cSNickeau 518*04fd306cSNickeau /** 519*04fd306cSNickeau * A function to set explicitly which array format 520*04fd306cSNickeau * is used in the returned data of a {@link SyntaxPlugin::handle()} 521*04fd306cSNickeau * (which ultimately is stored in the {@link CallStack) 522*04fd306cSNickeau * 523*04fd306cSNickeau * This is to make the difference with the {@link MediaLink::createFromIndexAttributes()} 524*04fd306cSNickeau * that is indexed by number (ie without property name) 525*04fd306cSNickeau * 526*04fd306cSNickeau * 527*04fd306cSNickeau * Return the array that is used in the {@link CallStack} 528*04fd306cSNickeau * 529*04fd306cSNickeau * @return array of key string and value 530*04fd306cSNickeau */ 531*04fd306cSNickeau public function toCallStackArray(): array 532*04fd306cSNickeau { 533*04fd306cSNickeau /** 534*04fd306cSNickeau * We store linking as attribute (to make it possible to change the linking by other plugin) 535*04fd306cSNickeau * (ie no linking in heading , ...) 536*04fd306cSNickeau */ 537*04fd306cSNickeau $attributes[MediaMarkup::LINKING_KEY] = $this->linking; 538*04fd306cSNickeau $attributes[MarkupRef::REF_ATTRIBUTE] = $this->markupRef->getRef(); 539*04fd306cSNickeau $attributes[Align::ALIGN_ATTRIBUTE] = $this->align; 540*04fd306cSNickeau $attributes[TagAttributes::TITLE_KEY] = $this->label; 541*04fd306cSNickeau return $attributes; 542*04fd306cSNickeau 543*04fd306cSNickeau } 544*04fd306cSNickeau 545*04fd306cSNickeau public function setLinking(string $linking): MediaMarkup 546*04fd306cSNickeau { 547*04fd306cSNickeau $this->linking = $linking; 548*04fd306cSNickeau return $this; 549*04fd306cSNickeau } 550*04fd306cSNickeau 551*04fd306cSNickeau /** 552*04fd306cSNickeau * @throws ExceptionNotFound 553*04fd306cSNickeau */ 554*04fd306cSNickeau public function getLinking(): string 555*04fd306cSNickeau { 556*04fd306cSNickeau /** 557*04fd306cSNickeau * Linking 558*04fd306cSNickeau */ 559*04fd306cSNickeau $linking = $this->linking; 560*04fd306cSNickeau if ($linking !== null) { 561*04fd306cSNickeau return $linking; 562*04fd306cSNickeau } 563*04fd306cSNickeau throw new ExceptionNotFound("No linking set"); 564*04fd306cSNickeau 565*04fd306cSNickeau 566*04fd306cSNickeau } 567*04fd306cSNickeau 568*04fd306cSNickeau /** 569*04fd306cSNickeau * Align on the url has precedence 570*04fd306cSNickeau * if present 571*04fd306cSNickeau * @throws ExceptionNotFound 572*04fd306cSNickeau */ 573*04fd306cSNickeau public function getAlign(): string 574*04fd306cSNickeau { 575*04fd306cSNickeau 576*04fd306cSNickeau if ($this->align !== null) { 577*04fd306cSNickeau return $this->align; 578*04fd306cSNickeau } 579*04fd306cSNickeau throw new ExceptionNotFound("No align was specified"); 580*04fd306cSNickeau } 581*04fd306cSNickeau 582*04fd306cSNickeau 583*04fd306cSNickeau public function toTagAttributes() 584*04fd306cSNickeau { 585*04fd306cSNickeau 586*04fd306cSNickeau 587*04fd306cSNickeau /** 588*04fd306cSNickeau * The align attribute on an image parse 589*04fd306cSNickeau * is a float right 590*04fd306cSNickeau * ComboStrap does a difference between a block right and a float right 591*04fd306cSNickeau */ 592*04fd306cSNickeau try { 593*04fd306cSNickeau $align = $this->getAlign(); 594*04fd306cSNickeau if ($align === "right") { 595*04fd306cSNickeau $this->extraMediaTagAttributes->addComponentAttributeValue(FloatAttribute::FLOAT_KEY, "right"); 596*04fd306cSNickeau } else { 597*04fd306cSNickeau $this->extraMediaTagAttributes->addComponentAttributeValue(Align::ALIGN_ATTRIBUTE, $align); 598*04fd306cSNickeau } 599*04fd306cSNickeau } catch (ExceptionNotFound $e) { 600*04fd306cSNickeau // ok 601*04fd306cSNickeau } 602*04fd306cSNickeau 603*04fd306cSNickeau return $this->extraMediaTagAttributes; 604*04fd306cSNickeau 605*04fd306cSNickeau } 606*04fd306cSNickeau 607*04fd306cSNickeau /** 608*04fd306cSNickeau * @throws ExceptionNotFound 609*04fd306cSNickeau */ 610*04fd306cSNickeau public function getLabel(): string 611*04fd306cSNickeau { 612*04fd306cSNickeau if (empty($this->label)) { 613*04fd306cSNickeau throw new ExceptionNotFound("No label specified"); 614*04fd306cSNickeau } 615*04fd306cSNickeau return $this->label; 616*04fd306cSNickeau } 617*04fd306cSNickeau 618*04fd306cSNickeau public 619*04fd306cSNickeau function setLazyLoadMethod($false): MediaMarkup 620*04fd306cSNickeau { 621*04fd306cSNickeau $this->lazyLoadMethod = $false; 622*04fd306cSNickeau return $this; 623*04fd306cSNickeau } 624*04fd306cSNickeau 625*04fd306cSNickeau /** 626*04fd306cSNickeau * @throws ExceptionNotFound 627*04fd306cSNickeau */ 628*04fd306cSNickeau public 629*04fd306cSNickeau function getLazyLoadMethod(): string 630*04fd306cSNickeau { 631*04fd306cSNickeau 632*04fd306cSNickeau if ($this->lazyLoadMethod !== null) { 633*04fd306cSNickeau return $this->lazyLoadMethod; 634*04fd306cSNickeau } 635*04fd306cSNickeau throw new ExceptionNotFound("Lazy method is not specified"); 636*04fd306cSNickeau 637*04fd306cSNickeau } 638*04fd306cSNickeau 639*04fd306cSNickeau public 640*04fd306cSNickeau function getLazyLoadMethodOrDefault(): string 641*04fd306cSNickeau { 642*04fd306cSNickeau try { 643*04fd306cSNickeau return $this->getLazyLoadMethod(); 644*04fd306cSNickeau } catch (ExceptionNotFound $e) { 645*04fd306cSNickeau return LazyLoad::getDefault(); 646*04fd306cSNickeau } 647*04fd306cSNickeau 648*04fd306cSNickeau } 649*04fd306cSNickeau 650*04fd306cSNickeau 651*04fd306cSNickeau public 652*04fd306cSNickeau static function isInternalMediaSyntax($text) 653*04fd306cSNickeau { 654*04fd306cSNickeau return preg_match(' / ' . syntax_plugin_combo_media::MEDIA_PATTERN . ' / msSi', $text); 655*04fd306cSNickeau } 656*04fd306cSNickeau 657*04fd306cSNickeau 658*04fd306cSNickeau public function isLazy(): bool 659*04fd306cSNickeau { 660*04fd306cSNickeau 661*04fd306cSNickeau return $this->getLazyLoadMethodOrDefault() !== LazyLoad::LAZY_LOAD_METHOD_NONE_VALUE; 662*04fd306cSNickeau 663*04fd306cSNickeau } 664*04fd306cSNickeau 665*04fd306cSNickeau public function getExtraMediaTagAttributes(): TagAttributes 666*04fd306cSNickeau { 667*04fd306cSNickeau try { 668*04fd306cSNickeau $this->extraMediaTagAttributes->addComponentAttributeValue(Align::ALIGN_ATTRIBUTE, $this->getAlign()); 669*04fd306cSNickeau } catch (ExceptionNotFound $e) { 670*04fd306cSNickeau // ok 671*04fd306cSNickeau } 672*04fd306cSNickeau return $this->extraMediaTagAttributes; 673*04fd306cSNickeau } 674*04fd306cSNickeau 675*04fd306cSNickeau 676*04fd306cSNickeau public function __toString() 677*04fd306cSNickeau { 678*04fd306cSNickeau return $this->toMarkupSyntax(); 679*04fd306cSNickeau } 680*04fd306cSNickeau 681*04fd306cSNickeau public function setLazyLoad(bool $true): MediaMarkup 682*04fd306cSNickeau { 683*04fd306cSNickeau if ($true) { 684*04fd306cSNickeau $this->lazyLoadMethod = LazyLoad::getDefault(); 685*04fd306cSNickeau } else { 686*04fd306cSNickeau $this->lazyLoadMethod = LazyLoad::LAZY_LOAD_METHOD_NONE_VALUE; 687*04fd306cSNickeau } 688*04fd306cSNickeau return $this; 689*04fd306cSNickeau } 690*04fd306cSNickeau 691*04fd306cSNickeau /** 692*04fd306cSNickeau * Get and delete the attribute for the link 693*04fd306cSNickeau * (The rest is for the image) 694*04fd306cSNickeau */ 695*04fd306cSNickeau public 696*04fd306cSNickeau function getLinkingClass() 697*04fd306cSNickeau { 698*04fd306cSNickeau return $this->linkingClass; 699*04fd306cSNickeau } 700*04fd306cSNickeau 701*04fd306cSNickeau /** 702*04fd306cSNickeau * @throws ExceptionNotFound 703*04fd306cSNickeau */ 704*04fd306cSNickeau public function getMarkupRef(): MarkupRef 705*04fd306cSNickeau { 706*04fd306cSNickeau if ($this->markupRef === null) { 707*04fd306cSNickeau throw new ExceptionNotFound("No markup, this media markup was not created from a markup"); 708*04fd306cSNickeau } 709*04fd306cSNickeau return $this->markupRef; 710*04fd306cSNickeau } 711*04fd306cSNickeau 712*04fd306cSNickeau 713*04fd306cSNickeau /** 714*04fd306cSNickeau * @param TagAttributes $tagAttributes - the attributes in a tag format 715*04fd306cSNickeau * @return $this 716*04fd306cSNickeau */ 717*04fd306cSNickeau public function buildFromTagAttributes(TagAttributes $tagAttributes): MediaMarkup 718*04fd306cSNickeau { 719*04fd306cSNickeau 720*04fd306cSNickeau $linking = $tagAttributes->getValueAndRemoveIfPresent(self::LINKING_KEY); 721*04fd306cSNickeau if ($linking !== null) { 722*04fd306cSNickeau $this->setLinking($linking); 723*04fd306cSNickeau } 724*04fd306cSNickeau $label = $tagAttributes->getValueAndRemoveIfPresent(TagAttributes::TITLE_KEY); 725*04fd306cSNickeau if ($label !== null) { 726*04fd306cSNickeau $this->setLabel($label); 727*04fd306cSNickeau } 728*04fd306cSNickeau $align = $tagAttributes->getValueAndRemoveIfPresent(Align::ALIGN_ATTRIBUTE); 729*04fd306cSNickeau if ($align !== null) { 730*04fd306cSNickeau $this->setAlign($align); 731*04fd306cSNickeau } 732*04fd306cSNickeau $lazy = $tagAttributes->getValueAndRemoveIfPresent(LazyLoad::LAZY_LOAD_METHOD); 733*04fd306cSNickeau if ($lazy !== null) { 734*04fd306cSNickeau $this->setLazyLoadMethod($lazy); 735*04fd306cSNickeau } 736*04fd306cSNickeau 737*04fd306cSNickeau /** 738*04fd306cSNickeau * dokuwiki attribute 739*04fd306cSNickeau */ 740*04fd306cSNickeau if (isset($this->fetchUrl)) { 741*04fd306cSNickeau $width = $tagAttributes->getValueAndRemoveIfPresent(Dimension::WIDTH_KEY); 742*04fd306cSNickeau if ($width !== null) { 743*04fd306cSNickeau $this->fetchUrl->addQueryParameterIfNotPresent(Dimension::WIDTH_KEY, $width); 744*04fd306cSNickeau } 745*04fd306cSNickeau $height = $tagAttributes->getValueAndRemoveIfPresent(Dimension::HEIGHT_KEY); 746*04fd306cSNickeau if ($height !== null) { 747*04fd306cSNickeau $this->fetchUrl->addQueryParameterIfNotPresent(Dimension::HEIGHT_KEY, $height); 748*04fd306cSNickeau } 749*04fd306cSNickeau $ratio = $tagAttributes->getValueAndRemoveIfPresent(Dimension::RATIO_ATTRIBUTE); 750*04fd306cSNickeau if ($ratio !== null) { 751*04fd306cSNickeau $this->fetchUrl->addQueryParameterIfNotPresent(Dimension::RATIO_ATTRIBUTE, $ratio); 752*04fd306cSNickeau } 753*04fd306cSNickeau } 754*04fd306cSNickeau 755*04fd306cSNickeau foreach ($tagAttributes->getComponentAttributes() as $key => $value) { 756*04fd306cSNickeau $this->extraMediaTagAttributes->addComponentAttributeValue($key, $value); 757*04fd306cSNickeau } 758*04fd306cSNickeau 759*04fd306cSNickeau foreach ($tagAttributes->getStyleDeclarations() as $key => $value) { 760*04fd306cSNickeau $this->extraMediaTagAttributes->addStyleDeclarationIfNotSet($key, $value); 761*04fd306cSNickeau } 762*04fd306cSNickeau 763*04fd306cSNickeau return $this; 764*04fd306cSNickeau } 765*04fd306cSNickeau 766*04fd306cSNickeau /** 767*04fd306cSNickeau * @throws ExceptionBadArgument 768*04fd306cSNickeau * @throws ExceptionBadSyntax 769*04fd306cSNickeau * @throws ExceptionNotExists 770*04fd306cSNickeau * @throws ExceptionNotFound 771*04fd306cSNickeau */ 772*04fd306cSNickeau public function toHtml(): string 773*04fd306cSNickeau { 774*04fd306cSNickeau return MediaLink::createFromMediaMarkup($this) 775*04fd306cSNickeau ->renderMediaTag(); 776*04fd306cSNickeau } 777*04fd306cSNickeau 778*04fd306cSNickeau /** 779*04fd306cSNickeau * @throws ExceptionBadSyntax 780*04fd306cSNickeau * @throws ExceptionBadArgument 781*04fd306cSNickeau * @throws ExceptionNotExists 782*04fd306cSNickeau * @throws ExceptionNotFound 783*04fd306cSNickeau */ 784*04fd306cSNickeau public function getMediaLink() 785*04fd306cSNickeau { 786*04fd306cSNickeau return MediaLink::createFromMediaMarkup($this); 787*04fd306cSNickeau } 788*04fd306cSNickeau 789*04fd306cSNickeau private 790*04fd306cSNickeau function setLinkingClass($value): MediaMarkup 791*04fd306cSNickeau { 792*04fd306cSNickeau $this->linkingClass = $value; 793*04fd306cSNickeau return $this; 794*04fd306cSNickeau } 795*04fd306cSNickeau 796*04fd306cSNickeau /** 797*04fd306cSNickeau * @return string the wiki syntax 798*04fd306cSNickeau */ 799*04fd306cSNickeau public function toMarkupSyntax(): string 800*04fd306cSNickeau { 801*04fd306cSNickeau $descriptionPart = ""; 802*04fd306cSNickeau try { 803*04fd306cSNickeau $descriptionPart = "|" . $this->getLabel(); 804*04fd306cSNickeau } catch (ExceptionNotFound $e) { 805*04fd306cSNickeau // ok 806*04fd306cSNickeau } 807*04fd306cSNickeau try { 808*04fd306cSNickeau $ref = $this->getRef(); 809*04fd306cSNickeau } catch (ExceptionNotFound $e) { 810*04fd306cSNickeau $ref = $this->getFetchUrl()->toString(); 811*04fd306cSNickeau } 812*04fd306cSNickeau return '{{' . $ref . $descriptionPart . '}}'; 813*04fd306cSNickeau } 814*04fd306cSNickeau 815*04fd306cSNickeau /** 816*04fd306cSNickeau * 817*04fd306cSNickeau * Private method use {@link MediaMarkup::createFromFetchUrl()} to create a media markup via a Url 818*04fd306cSNickeau * 819*04fd306cSNickeau * @throws ExceptionNotFound 820*04fd306cSNickeau */ 821*04fd306cSNickeau private function setUrl(Url $fetchUrl): MediaMarkup 822*04fd306cSNickeau { 823*04fd306cSNickeau 824*04fd306cSNickeau /** 825*04fd306cSNickeau * Tag Attributes 826*04fd306cSNickeau */ 827*04fd306cSNickeau try { 828*04fd306cSNickeau $this->align = $fetchUrl->getQueryPropertyValueAndRemoveIfPresent(Align::ALIGN_ATTRIBUTE); 829*04fd306cSNickeau } catch (ExceptionNotFound $e) { 830*04fd306cSNickeau // ok 831*04fd306cSNickeau } 832*04fd306cSNickeau try { 833*04fd306cSNickeau $this->linking = $fetchUrl->getQueryPropertyValueAndRemoveIfPresent(self::LINKING_KEY); 834*04fd306cSNickeau } catch (ExceptionNotFound $e) { 835*04fd306cSNickeau // ok 836*04fd306cSNickeau } 837*04fd306cSNickeau try { 838*04fd306cSNickeau $this->lazyLoadMethod = $fetchUrl->getQueryPropertyValueAndRemoveIfPresent(LazyLoad::LAZY_LOAD_METHOD); 839*04fd306cSNickeau } catch (ExceptionNotFound $e) { 840*04fd306cSNickeau // ok 841*04fd306cSNickeau } 842*04fd306cSNickeau try { 843*04fd306cSNickeau $this->linkingClass = $fetchUrl->getQueryPropertyValueAndRemoveIfPresent(self::LINK_CLASS_ATTRIBUTE); 844*04fd306cSNickeau } catch (ExceptionNotFound $e) { 845*04fd306cSNickeau // ok 846*04fd306cSNickeau } 847*04fd306cSNickeau 848*04fd306cSNickeau foreach (self::STYLE_ATTRIBUTES as $nonUrlAttribute) { 849*04fd306cSNickeau try { 850*04fd306cSNickeau $value = $fetchUrl->getQueryPropertyValueAndRemoveIfPresent($nonUrlAttribute); 851*04fd306cSNickeau $this->extraMediaTagAttributes->addComponentAttributeValue($nonUrlAttribute, $value); 852*04fd306cSNickeau } catch (ExceptionNotFound $e) { 853*04fd306cSNickeau // ok 854*04fd306cSNickeau } 855*04fd306cSNickeau } 856*04fd306cSNickeau 857*04fd306cSNickeau $this->fetchUrl = $fetchUrl; 858*04fd306cSNickeau return $this; 859*04fd306cSNickeau } 860*04fd306cSNickeau 861*04fd306cSNickeau /** 862*04fd306cSNickeau * @throws ExceptionNotFound 863*04fd306cSNickeau */ 864*04fd306cSNickeau private function getRef(): string 865*04fd306cSNickeau { 866*04fd306cSNickeau if ($this->markupRef === null) { 867*04fd306cSNickeau throw new ExceptionNotFound("No ref was specified"); 868*04fd306cSNickeau } 869*04fd306cSNickeau return $this->markupRef->getRef(); 870*04fd306cSNickeau } 871*04fd306cSNickeau 872*04fd306cSNickeau /** 873*04fd306cSNickeau * @throws ExceptionNotFound - if this markup does not have a path origin 874*04fd306cSNickeau * @deprecated use the {@link self::getFetcher()} instead 875*04fd306cSNickeau * A media may be generated (ie {@link FetcherVignette} 876*04fd306cSNickeau * therefore the path may be not present 877*04fd306cSNickeau * 878*04fd306cSNickeau * If you want to known the mime use {@link self::getFetcher()} then {@link IFetcher::getMime()} 879*04fd306cSNickeau */ 880*04fd306cSNickeau public function getPath(): WikiPath 881*04fd306cSNickeau { 882*04fd306cSNickeau try { 883*04fd306cSNickeau 884*04fd306cSNickeau return $this->getMarkupRef()->getPath(); 885*04fd306cSNickeau 886*04fd306cSNickeau } catch (ExceptionNotFound $e) { 887*04fd306cSNickeau 888*04fd306cSNickeau if ($this->fetcher instanceof IFetcherSource) { 889*04fd306cSNickeau return $this->fetcher->getSourcePath(); 890*04fd306cSNickeau } 891*04fd306cSNickeau throw $e; 892*04fd306cSNickeau 893*04fd306cSNickeau } 894*04fd306cSNickeau } 895*04fd306cSNickeau 896*04fd306cSNickeau /** 897*04fd306cSNickeau * Private method use {@link MediaMarkup::createFromFetcher()} to create a media markup via a Fetcher 898*04fd306cSNickeau * @param IFetcher $fetcher 899*04fd306cSNickeau * @return MediaMarkup 900*04fd306cSNickeau */ 901*04fd306cSNickeau private function setFetcher(IFetcher $fetcher): MediaMarkup 902*04fd306cSNickeau { 903*04fd306cSNickeau $this->fetcher = $fetcher; 904*04fd306cSNickeau return $this; 905*04fd306cSNickeau } 906*04fd306cSNickeau 907*04fd306cSNickeau 908*04fd306cSNickeau /** 909*04fd306cSNickeau * @return IFetcher 910*04fd306cSNickeau */ 911*04fd306cSNickeau public function getFetcher(): IFetcher 912*04fd306cSNickeau { 913*04fd306cSNickeau if (!isset($this->fetcher)) { 914*04fd306cSNickeau if (!isset($this->fetchUrl)) { 915*04fd306cSNickeau throw new ExceptionRuntimeInternal("No fetcher or url was set"); 916*04fd306cSNickeau } 917*04fd306cSNickeau /** 918*04fd306cSNickeau * Fetcher is build later 919*04fd306cSNickeau * because for a raster image 920*04fd306cSNickeau * actually, we can't built it 921*04fd306cSNickeau * if the file does not exists. 922*04fd306cSNickeau * It will throw an error immediatly and we may want not. 923*04fd306cSNickeau * For resources, we want to build the url even if the image does not exists. 924*04fd306cSNickeau */ 925*04fd306cSNickeau try { 926*04fd306cSNickeau $this->fetcher = FetcherSystem::createPathFetcherFromUrl($this->fetchUrl); 927*04fd306cSNickeau } catch (ExceptionBadArgument|ExceptionInternal|ExceptionNotFound $e) { 928*04fd306cSNickeau try { 929*04fd306cSNickeau // we don't support http fetch 930*04fd306cSNickeau if (!($this->getMarkupRef()->getSchemeType() === MarkupRef::WEB_URI)) { 931*04fd306cSNickeau throw ExceptionRuntimeInternal::withMessageAndError("we don't support http fetch", $e); 932*04fd306cSNickeau } 933*04fd306cSNickeau } catch (ExceptionNotFound $e) { 934*04fd306cSNickeau // ok no markup ref 935*04fd306cSNickeau } 936*04fd306cSNickeau } 937*04fd306cSNickeau } 938*04fd306cSNickeau return $this->fetcher; 939*04fd306cSNickeau } 940*04fd306cSNickeau 941*04fd306cSNickeau 942*04fd306cSNickeau} 943