xref: /plugin/struct/types/Media.php (revision 7234bfb14e712ff548d9266ef32fdcc8eaf2d04e)
1<?php
2
3namespace dokuwiki\plugin\struct\types;
4
5use dokuwiki\plugin\struct\meta\ValidationException;
6
7class Media extends AbstractBaseType
8{
9    protected $config = ['mime' => 'image/', 'width' => 90, 'height' => 90, 'agg_width' => '', 'agg_height' => ''];
10
11    /**
12     * Checks against the allowed mime types
13     *
14     * @param string $rawvalue
15     * @return int|string
16     */
17    public function validate($rawvalue)
18    {
19        $rawvalue = parent::validate($rawvalue);
20
21        if (!trim($this->config['mime'])) return $rawvalue;
22        $allows = explode(',', $this->config['mime']);
23        $allows = array_map('trim', $allows);
24        $allows = array_filter($allows);
25
26        [, $mime, ] = mimetype($rawvalue, false);
27        foreach ($allows as $allow) {
28            if (strpos($mime, $allow) === 0) return $rawvalue;
29        }
30
31        throw new ValidationException('Media mime type', $mime, $this->config['mime']);
32    }
33
34    /**
35     * Output the stored data
36     *
37     * If outputted in an aggregation we collect the images into a gallery.
38     *
39     * @param string|int $value the value stored in the database
40     * @param \Doku_Renderer $R the renderer currently used to render the data
41     * @param string $mode The mode the output is rendered in (eg. XHTML)
42     * @return bool true if $mode could be satisfied
43     */
44    public function renderValue($value, \Doku_Renderer $R, $mode)
45    {
46        // get width and height from config
47        $width = null;
48        $height = null;
49        if ($this->config['width']) $width = $this->config['width'];
50        if ($this->config['height']) $height = $this->config['height'];
51        if (!empty($R->info['struct_table_hash'])) {
52            // this is an aggregation, check for special values
53            if ($this->config['agg_width']) $width = $this->config['agg_width'];
54            if ($this->config['agg_height']) $height = $this->config['agg_height'];
55        }
56        $html = '';
57        if (!media_isexternal($value)) {
58            if (is_a($R, '\Doku_Renderer_xhtml')) {
59                /** @var \Doku_Renderer_xhtml $R */
60                $html = $R->internalmedia($value, null, null, $width, $height, null, 'direct', true);
61            } else {
62                $R->internalmedia($value, null, null, $width, $height, null, 'direct');
63            }
64        } elseif (is_a($R, '\Doku_Renderer_xhtml')) {
65            /** @var \Doku_Renderer_xhtml $R */
66            $html = $R->externalmedia($value, null, null, $width, $height, null, 'direct', true);
67        } else {
68            $R->externalmedia($value, null, null, $width, $height, null, 'direct');
69        }
70
71        // add gallery meta data in XHTML
72        if ($mode == 'xhtml') {
73            [, $mime, ] = mimetype($value, false);
74            if (substr($mime, 0, 6) == 'image/') {
75                $hash = empty($R->info['struct_table_hash']) ? '' : "[gal-" . $R->info['struct_table_hash'] . "]";
76                $html = str_replace('href', "rel=\"lightbox$hash\" href", $html);
77            }
78            $R->doc .= $html;
79        }
80
81        return true;
82    }
83
84    /**
85     * Return the editor to edit a single value
86     *
87     * @param string $name the form name where this has to be stored
88     * @param string $rawvalue the current value
89     *
90     * @param string $htmlID
91     *
92     * @return string html
93     */
94    public function valueEditor($name, $rawvalue, $htmlID)
95    {
96        static $count = 0;
97        $count++;
98
99        $id = $htmlID ?: 'struct__' . md5($name . $count);
100
101        $params = ['name' => $name, 'value' => $rawvalue, 'class' => 'struct_media', 'id' => $id];
102        $attributes = buildAttributes($params, true);
103        $html = "<input $attributes />";
104        $html .= "<button type=\"button\" class=\"struct_media\">";
105        $html .= "<img src=\"" . DOKU_BASE . "lib/images/toolbar/image.png\" height=\"16\" width=\"16\">";
106        $html .= "</button>";
107        return $html;
108    }
109
110    /**
111     * @inheritDoc
112     */
113    public function renderTagCloudLink($value, \Doku_Renderer $R, $mode, $page, $filter, $weight)
114    {
115        $media = $this->displayValue($value);
116        if ($mode == 'xhtml' && $this->getConfig()['mime'] == 'image/') {
117            $url = wl($page, $filter);
118            $image = ml($media, ['h' => $weight, 'w' => $weight]);
119            $media_escaped = hsc($media);
120            $R->doc .= "<div style=\"height:{$weight}px; width:{$weight}px\">";
121            $R->doc .= "<a href='$url' class='struct_image' style='background-image:url(\"$image\")'
122                        title='$media_escaped'>";
123            $R->doc .= "<span class='a11y'>$media_escaped</span>";
124            $R->doc .= "</a>";
125            $R->doc .= "</div>";
126            return;
127        }
128        $R->internallink("$page?$filter", $media);
129    }
130}
131