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