1be906b56SAndreas Gohr<?php 2be906b56SAndreas Gohr 3be906b56SAndreas Gohrnamespace dokuwiki\Parsing\ParserMode; 4be906b56SAndreas Gohr 5*71096e46SAndreas Gohruse dokuwiki\Parsing\Handler; 6*71096e46SAndreas Gohr 7be906b56SAndreas Gohrclass Media extends AbstractMode 8be906b56SAndreas Gohr{ 9be906b56SAndreas Gohr /** @inheritdoc */ 10*71096e46SAndreas Gohr public function getSort() 11*71096e46SAndreas Gohr { 12*71096e46SAndreas Gohr return 320; 13*71096e46SAndreas Gohr } 14*71096e46SAndreas Gohr 15*71096e46SAndreas Gohr /** @inheritdoc */ 16be906b56SAndreas Gohr public function connectTo($mode) 17be906b56SAndreas Gohr { 18be906b56SAndreas Gohr // Word boundaries? 19be906b56SAndreas Gohr $this->Lexer->addSpecialPattern("\{\{(?:[^\}]|(?:\}[^\}]))+\}\}", $mode, 'media'); 20be906b56SAndreas Gohr } 21be906b56SAndreas Gohr 22be906b56SAndreas Gohr /** @inheritdoc */ 23*71096e46SAndreas Gohr public function handle($match, $state, $pos, Handler $handler) 24be906b56SAndreas Gohr { 25*71096e46SAndreas Gohr $p = self::parseMedia($match); 26*71096e46SAndreas Gohr 27*71096e46SAndreas Gohr $handler->addCall( 28*71096e46SAndreas Gohr $p['type'], 29*71096e46SAndreas Gohr [$p['src'], $p['title'], $p['align'], $p['width'], $p['height'], $p['cache'], $p['linking']], 30*71096e46SAndreas Gohr $pos 31*71096e46SAndreas Gohr ); 32*71096e46SAndreas Gohr return true; 33*71096e46SAndreas Gohr } 34*71096e46SAndreas Gohr 35*71096e46SAndreas Gohr /** 36*71096e46SAndreas Gohr * Parse media syntax into its components 37*71096e46SAndreas Gohr * 38*71096e46SAndreas Gohr * @param string $match The full media syntax (e.g. {{image.png?200|title}}) 39*71096e46SAndreas Gohr * @return array Parsed media parameters (type, src, title, align, width, height, cache, linking) 40*71096e46SAndreas Gohr */ 41*71096e46SAndreas Gohr public static function parseMedia($match) 42*71096e46SAndreas Gohr { 43*71096e46SAndreas Gohr // Strip the opening and closing markup 44*71096e46SAndreas Gohr $link = preg_replace(['/^\{\{/', '/\}\}$/u'], '', $match); 45*71096e46SAndreas Gohr 46*71096e46SAndreas Gohr // Split title from URL 47*71096e46SAndreas Gohr $link = sexplode('|', $link, 2); 48*71096e46SAndreas Gohr 49*71096e46SAndreas Gohr // Check alignment 50*71096e46SAndreas Gohr $ralign = (bool)preg_match('/^ /', $link[0]); 51*71096e46SAndreas Gohr $lalign = (bool)preg_match('/ $/', $link[0]); 52*71096e46SAndreas Gohr 53*71096e46SAndreas Gohr // Logic = what's that ;)... 54*71096e46SAndreas Gohr if ($lalign & $ralign) { 55*71096e46SAndreas Gohr $align = 'center'; 56*71096e46SAndreas Gohr } elseif ($ralign) { 57*71096e46SAndreas Gohr $align = 'right'; 58*71096e46SAndreas Gohr } elseif ($lalign) { 59*71096e46SAndreas Gohr $align = 'left'; 60*71096e46SAndreas Gohr } else { 61*71096e46SAndreas Gohr $align = null; 62*71096e46SAndreas Gohr } 63*71096e46SAndreas Gohr 64*71096e46SAndreas Gohr // The title... 65*71096e46SAndreas Gohr if (!isset($link[1])) { 66*71096e46SAndreas Gohr $link[1] = null; 67*71096e46SAndreas Gohr } 68*71096e46SAndreas Gohr 69*71096e46SAndreas Gohr //remove aligning spaces 70*71096e46SAndreas Gohr $link[0] = trim($link[0]); 71*71096e46SAndreas Gohr 72*71096e46SAndreas Gohr //split into src and parameters (using the very last questionmark) 73*71096e46SAndreas Gohr $pos = strrpos($link[0], '?'); 74*71096e46SAndreas Gohr if ($pos !== false) { 75*71096e46SAndreas Gohr $src = substr($link[0], 0, $pos); 76*71096e46SAndreas Gohr $param = substr($link[0], $pos + 1); 77*71096e46SAndreas Gohr } else { 78*71096e46SAndreas Gohr $src = $link[0]; 79*71096e46SAndreas Gohr $param = ''; 80*71096e46SAndreas Gohr } 81*71096e46SAndreas Gohr 82*71096e46SAndreas Gohr //parse width and height 83*71096e46SAndreas Gohr if (preg_match('#(\d+)(x(\d+))?#i', $param, $size)) { 84*71096e46SAndreas Gohr $w = empty($size[1]) ? null : $size[1]; 85*71096e46SAndreas Gohr $h = empty($size[3]) ? null : $size[3]; 86*71096e46SAndreas Gohr } else { 87*71096e46SAndreas Gohr $w = null; 88*71096e46SAndreas Gohr $h = null; 89*71096e46SAndreas Gohr } 90*71096e46SAndreas Gohr 91*71096e46SAndreas Gohr //get linking command 92*71096e46SAndreas Gohr if (preg_match('/nolink/i', $param)) { 93*71096e46SAndreas Gohr $linking = 'nolink'; 94*71096e46SAndreas Gohr } elseif (preg_match('/direct/i', $param)) { 95*71096e46SAndreas Gohr $linking = 'direct'; 96*71096e46SAndreas Gohr } elseif (preg_match('/linkonly/i', $param)) { 97*71096e46SAndreas Gohr $linking = 'linkonly'; 98*71096e46SAndreas Gohr } else { 99*71096e46SAndreas Gohr $linking = 'details'; 100*71096e46SAndreas Gohr } 101*71096e46SAndreas Gohr 102*71096e46SAndreas Gohr //get caching command 103*71096e46SAndreas Gohr if (preg_match('/(nocache|recache)/i', $param, $cachemode)) { 104*71096e46SAndreas Gohr $cache = $cachemode[1]; 105*71096e46SAndreas Gohr } else { 106*71096e46SAndreas Gohr $cache = 'cache'; 107*71096e46SAndreas Gohr } 108*71096e46SAndreas Gohr 109*71096e46SAndreas Gohr // Check whether this is a local or remote image or interwiki 110*71096e46SAndreas Gohr if (media_isexternal($src) || link_isinterwiki($src)) { 111*71096e46SAndreas Gohr $call = 'externalmedia'; 112*71096e46SAndreas Gohr } else { 113*71096e46SAndreas Gohr $call = 'internalmedia'; 114*71096e46SAndreas Gohr } 115*71096e46SAndreas Gohr 116*71096e46SAndreas Gohr return [ 117*71096e46SAndreas Gohr 'type' => $call, 118*71096e46SAndreas Gohr 'src' => $src, 119*71096e46SAndreas Gohr 'title' => $link[1], 120*71096e46SAndreas Gohr 'align' => $align, 121*71096e46SAndreas Gohr 'width' => $w, 122*71096e46SAndreas Gohr 'height' => $h, 123*71096e46SAndreas Gohr 'cache' => $cache, 124*71096e46SAndreas Gohr 'linking' => $linking 125*71096e46SAndreas Gohr ]; 126be906b56SAndreas Gohr } 127be906b56SAndreas Gohr} 128