xref: /dokuwiki/inc/Parsing/ParserMode/Media.php (revision 71096e46fcbfaeaa808667aba794e77fe2780169)
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