xref: /dokuwiki/inc/Parsing/Helpers/Media.php (revision 884caed926ca0aa0af6ce3f34ae3aa7317a3361a)
1<?php
2
3namespace dokuwiki\Parsing\Helpers;
4
5/**
6 * Pure helper for parsing DokuWiki media parameters.
7 *
8 * Side-effect-free: returns data and leaves handler emission to the
9 * caller. Shared by DokuWiki's Media mode ({{...}}) and GfmMedia
10 * (![alt](url)).
11 */
12class Media
13{
14    /**
15     * Split a media source into src and trailing parameter block.
16     *
17     * DokuWiki media syntax encodes width/height, cache, linking, and
18     * alignment directives as URL-style parameters after the last ?.
19     * Using the last ? means URLs that already carry a query string
20     * survive untouched — e.g. https://example.com/img?v=2?100x200&right
21     * has src https://example.com/img?v=2 and params 100x200&right.
22     *
23     * GfmMedia relies on the left/right/center keywords for alignment
24     * because GFM has no equivalent of DW's whitespace-inside-braces
25     * alignment trick.
26     *
27     * @param string $src Raw media source with optional ?params suffix
28     * @return array{src: string, width: ?string, height: ?string, cache: string, linking: string, align: ?string}
29     */
30    public static function parseParameters(string $src): array
31    {
32        $pos = strrpos($src, '?');
33        if ($pos !== false) {
34            $out = substr($src, 0, $pos);
35            $param = substr($src, $pos + 1);
36        } else {
37            $out = $src;
38            $param = '';
39        }
40        $w = null;
41        $h = null;
42        if (preg_match('#(\d+)(x(\d+))?#i', $param, $size)) {
43            $w = empty($size[1]) ? null : $size[1];
44            $h = empty($size[3]) ? null : $size[3];
45        }
46
47        if (preg_match('/nolink/i', $param)) {
48            $linking = 'nolink';
49        } elseif (preg_match('/direct/i', $param)) {
50            $linking = 'direct';
51        } elseif (preg_match('/linkonly/i', $param)) {
52            $linking = 'linkonly';
53        } else {
54            $linking = 'details';
55        }
56
57        if (preg_match('/(nocache|recache)/i', $param, $cachemode)) {
58            $cache = $cachemode[1];
59        } else {
60            $cache = 'cache';
61        }
62
63        if (preg_match('/(left|right|center)/i', $param, $alignmode)) {
64            $align = strtolower($alignmode[1]);
65        } else {
66            $align = null;
67        }
68
69        return [
70            'src' => $out,
71            'width' => $w,
72            'height' => $h,
73            'cache' => $cache,
74            'linking' => $linking,
75            'align' => $align,
76        ];
77    }
78}
79