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