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