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