xref: /plugin/combo/syntax/media.php (revision 9337a630db122fdba0294f47d72bdf5433c2bf10)
121913ab3SNickeau<?php
221913ab3SNickeau
321913ab3SNickeau
423723136Sgerardnicouse ComboStrap\DokuPath;
523723136Sgerardnicouse ComboStrap\LogUtility;
623723136Sgerardnicouse ComboStrap\MediaLink;
721913ab3SNickeauuse ComboStrap\PluginUtility;
821913ab3SNickeauuse ComboStrap\Tag;
921913ab3SNickeau
1021913ab3SNickeau
1121913ab3SNickeauif (!defined('DOKU_INC')) die();
1221913ab3SNickeau
1321913ab3SNickeau
1421913ab3SNickeau/**
1523723136Sgerardnico * Media
1623723136Sgerardnico *
1723723136Sgerardnico * Takes over the {@link \dokuwiki\Parsing\ParserMode\Media media mode}
1823723136Sgerardnico * that is processed by {@link Doku_Handler_Parse_Media}
1923723136Sgerardnico *
2023723136Sgerardnico *
2123723136Sgerardnico *
2223723136Sgerardnico * It can be a internal / external media
2321913ab3SNickeau */
2421913ab3SNickeauclass syntax_plugin_combo_media extends DokuWiki_Syntax_Plugin
2521913ab3SNickeau{
2621913ab3SNickeau
2721913ab3SNickeau
2821913ab3SNickeau    const TAG = "media";
2921913ab3SNickeau
3021913ab3SNickeau    /**
3121913ab3SNickeau     * Used in the move plugin
3221913ab3SNickeau     * !!! The two last word of the plugin class !!!
3321913ab3SNickeau     */
3421913ab3SNickeau    const COMPONENT = 'combo_' . self::TAG;
3521913ab3SNickeau
3621913ab3SNickeau    /**
3721913ab3SNickeau     * The attribute that defines if the image is the first image in
3821913ab3SNickeau     * the component
3921913ab3SNickeau     *
4021913ab3SNickeau     */
4121913ab3SNickeau    const IS_FIRST_IMAGE_KEY = "isFirstImage";
4221913ab3SNickeau
4321913ab3SNickeau    /**
4423723136Sgerardnico     * Found at {@link \dokuwiki\Parsing\ParserMode\Media}
4521913ab3SNickeau     */
4623723136Sgerardnico    const MEDIA_PATTERN = "\{\{(?:[^>\}]|(?:\}[^\}]))+\}\}";
4721913ab3SNickeau
48531e725cSNickeau    /**
49531e725cSNickeau     * Enable or disable the image
50531e725cSNickeau     */
51531e725cSNickeau    const CONF_IMAGE_ENABLE = "imageEnable";
52531e725cSNickeau
5321913ab3SNickeau
5421913ab3SNickeau    function getType()
5521913ab3SNickeau    {
5621913ab3SNickeau        return 'formatting';
5721913ab3SNickeau    }
5821913ab3SNickeau
5921913ab3SNickeau    /**
6021913ab3SNickeau     * How Dokuwiki will add P element
6121913ab3SNickeau     *
6221913ab3SNickeau     *  * 'normal' - The plugin can be used inside paragraphs (inline)
6321913ab3SNickeau     *  * 'block'  - Open paragraphs need to be closed before plugin output - block should not be inside paragraphs
6421913ab3SNickeau     *  * 'stack'  - Special case. Plugin wraps other paragraphs. - Stacks can contain paragraphs
6521913ab3SNickeau     *
6621913ab3SNickeau     * @see DokuWiki_Syntax_Plugin::getPType()
6721913ab3SNickeau     */
6821913ab3SNickeau    function getPType()
6921913ab3SNickeau    {
7023723136Sgerardnico        /**
7123723136Sgerardnico         * An image is not a block (it can be inside paragraph)
7223723136Sgerardnico         */
7321913ab3SNickeau        return 'normal';
7421913ab3SNickeau    }
7521913ab3SNickeau
7621913ab3SNickeau    function getAllowedTypes()
7721913ab3SNickeau    {
7821913ab3SNickeau        return array('substition', 'formatting', 'disabled');
7921913ab3SNickeau    }
8021913ab3SNickeau
8123723136Sgerardnico    /**
8223723136Sgerardnico     * It should be less than {@link \dokuwiki\Parsing\ParserMode\Media::getSort()}
8323723136Sgerardnico     * (It was 320 at the time of writing this code)
8423723136Sgerardnico     * @return int
8523723136Sgerardnico     *
8623723136Sgerardnico     */
8721913ab3SNickeau    function getSort()
8821913ab3SNickeau    {
8923723136Sgerardnico        return 319;
9021913ab3SNickeau    }
9121913ab3SNickeau
9221913ab3SNickeau
9321913ab3SNickeau    function connectTo($mode)
9421913ab3SNickeau    {
95531e725cSNickeau        $enable = $this->getConf(self::CONF_IMAGE_ENABLE, 1);
9621913ab3SNickeau        if (!$enable) {
9721913ab3SNickeau
9821913ab3SNickeau            // Inside a card, we need to take over and enable it
9921913ab3SNickeau            $modes = [
100*9337a630SNickeau                PluginUtility::getModeFromTag(syntax_plugin_combo_card::TAG),
10121913ab3SNickeau            ];
10221913ab3SNickeau            $enable = in_array($mode, $modes);
10321913ab3SNickeau        }
10421913ab3SNickeau
10521913ab3SNickeau        if ($enable) {
106*9337a630SNickeau            $this->Lexer->addSpecialPattern(self::MEDIA_PATTERN, $mode, PluginUtility::getModeFromTag($this->getPluginComponent()));
10721913ab3SNickeau        }
10821913ab3SNickeau    }
10921913ab3SNickeau
11021913ab3SNickeau
11121913ab3SNickeau    function handle($match, $state, $pos, Doku_Handler $handler)
11221913ab3SNickeau    {
11321913ab3SNickeau
11421913ab3SNickeau        switch ($state) {
11521913ab3SNickeau
11621913ab3SNickeau
11721913ab3SNickeau            // As this is a container, this cannot happens but yeah, now, you know
11821913ab3SNickeau            case DOKU_LEXER_SPECIAL :
11923723136Sgerardnico                $media = MediaLink::createFromRenderMatch($match);
12021913ab3SNickeau                $attributes = $media->toCallStackArray();
12121913ab3SNickeau                $tag = new Tag(self::TAG, $attributes, $state, $handler);
12221913ab3SNickeau                $parent = $tag->getParent();
12321913ab3SNickeau                $parentTag = "";
12421913ab3SNickeau                if (!empty($parent)) {
12521913ab3SNickeau                    $parentTag = $parent->getName();
12621913ab3SNickeau                    if ($parentTag == syntax_plugin_combo_link::TAG) {
12721913ab3SNickeau                        /**
12821913ab3SNickeau                         * The image is in a link, we don't want another link
12921913ab3SNickeau                         * to the image
13021913ab3SNickeau                         */
131a6bf47aaSNickeau                        $attributes[MediaLink::LINKING_KEY] = MediaLink::LINKING_NOLINK_VALUE;
13221913ab3SNickeau                    }
13321913ab3SNickeau                }
13421913ab3SNickeau                $isFirstSibling = $tag->isFirstMeaningFullSibling();
13521913ab3SNickeau                return array(
13621913ab3SNickeau                    PluginUtility::STATE => $state,
13721913ab3SNickeau                    PluginUtility::ATTRIBUTES => $attributes,
13821913ab3SNickeau                    PluginUtility::CONTEXT => $parentTag,
13921913ab3SNickeau                    self::IS_FIRST_IMAGE_KEY => $isFirstSibling
14021913ab3SNickeau                );
14121913ab3SNickeau
14221913ab3SNickeau
14321913ab3SNickeau        }
14421913ab3SNickeau        return array();
14521913ab3SNickeau
14621913ab3SNickeau    }
14721913ab3SNickeau
14821913ab3SNickeau    /**
14921913ab3SNickeau     * Render the output
15021913ab3SNickeau     * @param string $format
15121913ab3SNickeau     * @param Doku_Renderer $renderer
15221913ab3SNickeau     * @param array $data - what the function handle() return'ed
15321913ab3SNickeau     * @return boolean - rendered correctly? (however, returned value is not used at the moment)
15421913ab3SNickeau     * @see DokuWiki_Syntax_Plugin::render()
15521913ab3SNickeau     *
15621913ab3SNickeau     *
15721913ab3SNickeau     */
15821913ab3SNickeau    function render($format, Doku_Renderer $renderer, $data)
15921913ab3SNickeau    {
16021913ab3SNickeau
16121913ab3SNickeau        $attributes = $data[PluginUtility::ATTRIBUTES];
16221913ab3SNickeau        switch ($format) {
16321913ab3SNickeau
16421913ab3SNickeau            case 'xhtml':
16521913ab3SNickeau
16621913ab3SNickeau                /** @var Doku_Renderer_xhtml $renderer */
16721913ab3SNickeau                $attributes = $data[PluginUtility::ATTRIBUTES];
16823723136Sgerardnico                $media = MediaLink::createFromCallStackArray($attributes);
16923723136Sgerardnico                if ($media->getScheme() == DokuPath::LOCAL_SCHEME) {
17023723136Sgerardnico                    $media = MediaLink::createFromCallStackArray($attributes, $renderer->date_at);
17121913ab3SNickeau                    if ($media->isImage()) {
172*9337a630SNickeau                        /**
173*9337a630SNickeau                         * We don't support crop
174*9337a630SNickeau                         */
175*9337a630SNickeau                        $crop = false;
176*9337a630SNickeau                        if ($media->getRequestedWidth() != null && $media->getRequestedHeight() != null) {
177*9337a630SNickeau                            /**
178*9337a630SNickeau                             * Width of 0 = resizing by height (supported)
179*9337a630SNickeau                             */
180*9337a630SNickeau                            if ($media->getRequestedWidth() != "0") {
181*9337a630SNickeau                                $crop = true;
182*9337a630SNickeau                            }
183*9337a630SNickeau                        }
184*9337a630SNickeau                        if (!$crop) {
18521913ab3SNickeau                            $renderer->doc .= $media->renderMediaTagWithLink();
18623723136Sgerardnico                            return true;
18723723136Sgerardnico                        }
18823723136Sgerardnico                    }
189*9337a630SNickeau                }
19021913ab3SNickeau
19121913ab3SNickeau                /**
19223723136Sgerardnico                 * This is not an local internal media image (a video or an url image)
19321913ab3SNickeau                 * Dokuwiki takes over
19421913ab3SNickeau                 */
195531e725cSNickeau                $type = $attributes[MediaLink::MEDIA_DOKUWIKI_TYPE];
19621913ab3SNickeau                $src = $attributes['src'];
19721913ab3SNickeau                $title = $attributes['title'];
19821913ab3SNickeau                $align = $attributes['align'];
19921913ab3SNickeau                $width = $attributes['width'];
20021913ab3SNickeau                $height = $attributes['height'];
20121913ab3SNickeau                $cache = $attributes['cache'];
202a6bf47aaSNickeau                if ($cache == null) {
203a6bf47aaSNickeau                    // Dokuwiki needs a value
204a6bf47aaSNickeau                    // If their is no value it will output it without any value
205a6bf47aaSNickeau                    // in the query string.
206a6bf47aaSNickeau                    $cache = "cache";
207a6bf47aaSNickeau                }
20821913ab3SNickeau                $linking = $attributes['linking'];
20923723136Sgerardnico                switch ($type) {
210531e725cSNickeau                    case MediaLink::INTERNAL_MEDIA_CALL_NAME:
21121913ab3SNickeau                        $renderer->doc .= $renderer->internalmedia($src, $title, $align, $width, $height, $cache, $linking, true);
21223723136Sgerardnico                        break;
213531e725cSNickeau                    case MediaLink::EXTERNAL_MEDIA_CALL_NAME:
21423723136Sgerardnico                        $renderer->doc .= $renderer->externalmedia($src, $title, $align, $width, $height, $cache, $linking, true);
21523723136Sgerardnico                        break;
21623723136Sgerardnico                    default:
21723723136Sgerardnico                        LogUtility::msg("The dokuwiki media type ($type) is unknown");
21823723136Sgerardnico                        break;
21921913ab3SNickeau                }
22021913ab3SNickeau
22123723136Sgerardnico                return true;
22221913ab3SNickeau
223*9337a630SNickeau            case
224*9337a630SNickeau            "metadata":
22521913ab3SNickeau
22621913ab3SNickeau                /**
22721913ab3SNickeau                 * Keep track of the metadata
22821913ab3SNickeau                 * @var Doku_Renderer_metadata $renderer
22921913ab3SNickeau                 */
23021913ab3SNickeau                self::registerImageMeta($attributes, $renderer);
23123723136Sgerardnico                return true;
23221913ab3SNickeau
23321913ab3SNickeau        }
23421913ab3SNickeau        // unsupported $mode
23521913ab3SNickeau        return false;
23621913ab3SNickeau    }
23721913ab3SNickeau
23821913ab3SNickeau    /**
23921913ab3SNickeau     * @param array $attributes
24021913ab3SNickeau     * @param Doku_Renderer_metadata $renderer
24121913ab3SNickeau     */
24221913ab3SNickeau    static public function registerImageMeta($attributes, $renderer)
24321913ab3SNickeau    {
244531e725cSNickeau        $type = $attributes[MediaLink::MEDIA_DOKUWIKI_TYPE];
24521913ab3SNickeau        $src = $attributes['src'];
246531e725cSNickeau        if ($src == null) {
247531e725cSNickeau            $src = $attributes[DokuPath::PATH_ATTRIBUTE];
248531e725cSNickeau        }
24921913ab3SNickeau        $title = $attributes['title'];
25021913ab3SNickeau        $align = $attributes['align'];
25121913ab3SNickeau        $width = $attributes['width'];
25221913ab3SNickeau        $height = $attributes['height'];
25321913ab3SNickeau        $cache = $attributes['cache']; // Cache: https://www.dokuwiki.org/images#caching
25421913ab3SNickeau        $linking = $attributes['linking'];
25523723136Sgerardnico
25623723136Sgerardnico        switch ($type) {
257531e725cSNickeau            case MediaLink::INTERNAL_MEDIA_CALL_NAME:
25821913ab3SNickeau                $renderer->internalmedia($src, $title, $align, $width, $height, $cache, $linking);
25923723136Sgerardnico                break;
260531e725cSNickeau            case MediaLink::EXTERNAL_MEDIA_CALL_NAME:
26123723136Sgerardnico                $renderer->externalmedia($src, $title, $align, $width, $height, $cache, $linking);
26223723136Sgerardnico                break;
26323723136Sgerardnico            default:
26423723136Sgerardnico                LogUtility::msg("The dokuwiki media type ($type)  for metadata registration is unknown");
26523723136Sgerardnico                break;
26623723136Sgerardnico        }
26723723136Sgerardnico
26821913ab3SNickeau    }
26921913ab3SNickeau
27021913ab3SNickeau
27121913ab3SNickeau}
27221913ab3SNickeau
273