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