xref: /plugin/combo/syntax/media.php (revision 23723136447b7913f53b9b11536e95bab29a3790)
1<?php
2
3
4use ComboStrap\DokuPath;
5use ComboStrap\LogUtility;
6use ComboStrap\MediaLink;
7use ComboStrap\PluginUtility;
8use ComboStrap\Tag;
9use ComboStrap\TagAttributes;
10
11require_once(__DIR__ . '/../class/RasterImageLink.php');
12
13if (!defined('DOKU_INC')) die();
14
15
16/**
17 * Media
18 *
19 * Takes over the {@link \dokuwiki\Parsing\ParserMode\Media media mode}
20 * that is processed by {@link Doku_Handler_Parse_Media}
21 *
22 *
23 *
24 * It can be a internal / external media
25 */
26class syntax_plugin_combo_media extends DokuWiki_Syntax_Plugin
27{
28
29
30    const TAG = "media";
31
32    /**
33     * Used in the move plugin
34     * !!! The two last word of the plugin class !!!
35     */
36    const COMPONENT = 'combo_' . self::TAG;
37
38    /**
39     * The attribute that defines if the image is the first image in
40     * the component
41     *
42     */
43    const IS_FIRST_IMAGE_KEY = "isFirstImage";
44
45    /**
46     * Found at {@link \dokuwiki\Parsing\ParserMode\Media}
47     */
48    const MEDIA_PATTERN = "\{\{(?:[^>\}]|(?:\}[^\}]))+\}\}";
49
50
51    function getType()
52    {
53        return 'formatting';
54    }
55
56    /**
57     * How Dokuwiki will add P element
58     *
59     *  * 'normal' - The plugin can be used inside paragraphs (inline)
60     *  * 'block'  - Open paragraphs need to be closed before plugin output - block should not be inside paragraphs
61     *  * 'stack'  - Special case. Plugin wraps other paragraphs. - Stacks can contain paragraphs
62     *
63     * @see DokuWiki_Syntax_Plugin::getPType()
64     */
65    function getPType()
66    {
67        /**
68         * An image is not a block (it can be inside paragraph)
69         */
70        return 'normal';
71    }
72
73    function getAllowedTypes()
74    {
75        return array('substition', 'formatting', 'disabled');
76    }
77
78    /**
79     * It should be less than {@link \dokuwiki\Parsing\ParserMode\Media::getSort()}
80     * (It was 320 at the time of writing this code)
81     * @return int
82     *
83     */
84    function getSort()
85    {
86        return 319;
87    }
88
89
90    function connectTo($mode)
91    {
92        $enable = $this->getConf(MediaLink::CONF_IMAGE_ENABLE, 1);
93        if (!$enable) {
94
95            // Inside a card, we need to take over and enable it
96            $modes = [
97                PluginUtility::getModeForComponent(syntax_plugin_combo_card::TAG),
98            ];
99            $enable = in_array($mode, $modes);
100        }
101
102        if ($enable) {
103            $this->Lexer->addSpecialPattern(self::MEDIA_PATTERN, $mode, PluginUtility::getModeForComponent($this->getPluginComponent()));
104        }
105    }
106
107
108    function handle($match, $state, $pos, Doku_Handler $handler)
109    {
110
111        switch ($state) {
112
113
114            // As this is a container, this cannot happens but yeah, now, you know
115            case DOKU_LEXER_SPECIAL :
116                $media = MediaLink::createFromRenderMatch($match);
117                $attributes = $media->toCallStackArray();
118                $tag = new Tag(self::TAG, $attributes, $state, $handler);
119                $parent = $tag->getParent();
120                $parentTag = "";
121                if (!empty($parent)) {
122                    $parentTag = $parent->getName();
123                    if ($parentTag == syntax_plugin_combo_link::TAG) {
124                        /**
125                         * The image is in a link, we don't want another link
126                         * to the image
127                         */
128                        $attributes[TagAttributes::LINKING_KEY] = MediaLink::LINKING_NOLINK_VALUE;
129                    }
130                }
131                $isFirstSibling = $tag->isFirstMeaningFullSibling();
132                return array(
133                    PluginUtility::STATE => $state,
134                    PluginUtility::ATTRIBUTES => $attributes,
135                    PluginUtility::CONTEXT => $parentTag,
136                    self::IS_FIRST_IMAGE_KEY => $isFirstSibling
137                );
138
139
140        }
141        return array();
142
143    }
144
145    /**
146     * Render the output
147     * @param string $format
148     * @param Doku_Renderer $renderer
149     * @param array $data - what the function handle() return'ed
150     * @return boolean - rendered correctly? (however, returned value is not used at the moment)
151     * @see DokuWiki_Syntax_Plugin::render()
152     *
153     *
154     */
155    function render($format, Doku_Renderer $renderer, $data)
156    {
157
158        $attributes = $data[PluginUtility::ATTRIBUTES];
159        switch ($format) {
160
161            case 'xhtml':
162
163                /** @var Doku_Renderer_xhtml $renderer */
164                $attributes = $data[PluginUtility::ATTRIBUTES];
165                $media = MediaLink::createFromCallStackArray($attributes);
166                if ($media->getScheme() == DokuPath::LOCAL_SCHEME) {
167                    $media = MediaLink::createFromCallStackArray($attributes, $renderer->date_at);
168                    if ($media->isImage()) {
169                        $renderer->doc .= $media->renderMediaTagWithLink();
170                        return true;
171                    }
172                }
173
174                /**
175                 * This is not an local internal media image (a video or an url image)
176                 * Dokuwiki takes over
177                 */
178                $type = $attributes['type'];
179                $src = $attributes['src'];
180                $title = $attributes['title'];
181                $align = $attributes['align'];
182                $width = $attributes['width'];
183                $height = $attributes['height'];
184                $cache = $attributes['cache'];
185                $linking = $attributes['linking'];
186                switch ($type) {
187                    case MediaLink::INTERNAL_MEDIA:
188                        $renderer->doc .= $renderer->internalmedia($src, $title, $align, $width, $height, $cache, $linking, true);
189                        break;
190                    case MediaLink::EXTERNAL_MEDIA:
191                        $renderer->doc .= $renderer->externalmedia($src, $title, $align, $width, $height, $cache, $linking, true);
192                        break;
193                    default:
194                        LogUtility::msg("The dokuwiki media type ($type) is unknown");
195                        break;
196                }
197
198                return true;
199
200            case "metadata":
201
202                /**
203                 * Keep track of the metadata
204                 * @var Doku_Renderer_metadata $renderer
205                 */
206                self::registerImageMeta($attributes, $renderer);
207                return true;
208
209        }
210        // unsupported $mode
211        return false;
212    }
213
214    /**
215     * @param array $attributes
216     * @param Doku_Renderer_metadata $renderer
217     */
218    static public function registerImageMeta($attributes, $renderer)
219    {
220        $type = $attributes['type'];
221        $src = $attributes['src'];
222        $title = $attributes['title'];
223        $align = $attributes['align'];
224        $width = $attributes['width'];
225        $height = $attributes['height'];
226        $cache = $attributes['cache']; // Cache: https://www.dokuwiki.org/images#caching
227        $linking = $attributes['linking'];
228
229        switch ($type) {
230            case MediaLink::INTERNAL_MEDIA:
231                $renderer->internalmedia($src, $title, $align, $width, $height, $cache, $linking);
232                break;
233            case MediaLink::EXTERNAL_MEDIA:
234                $renderer->externalmedia($src, $title, $align, $width, $height, $cache, $linking);
235                break;
236            default:
237                LogUtility::msg("The dokuwiki media type ($type)  for metadata registration is unknown");
238                break;
239        }
240
241    }
242
243
244}
245
246