xref: /template/strap/syntax/brand.php (revision 04fd306c7c155fa133ebb3669986875d65988276)
1007225e5Sgerardnico<?php
2007225e5Sgerardnico
3007225e5Sgerardnico
4007225e5Sgerardnico// must be run within Dokuwiki
54cadd4f8SNickeauuse ComboStrap\Brand;
64cadd4f8SNickeauuse ComboStrap\BrandButton;
7*04fd306cSNickeauuse ComboStrap\BrandTag;
8*04fd306cSNickeauuse ComboStrap\IconTag;
9*04fd306cSNickeauuse ComboStrap\MarkupCacheDependencies;
104cadd4f8SNickeauuse ComboStrap\CacheManager;
114cadd4f8SNickeauuse ComboStrap\Call;
124cadd4f8SNickeauuse ComboStrap\CallStack;
134cadd4f8SNickeauuse ComboStrap\ColorRgb;
144cadd4f8SNickeauuse ComboStrap\Dimension;
15*04fd306cSNickeauuse ComboStrap\ExceptionCompile;
164cadd4f8SNickeauuse ComboStrap\Icon;
17*04fd306cSNickeauuse ComboStrap\IconDownloader;
184cadd4f8SNickeauuse ComboStrap\LogUtility;
19*04fd306cSNickeauuse ComboStrap\MarkupPath;
20*04fd306cSNickeauuse ComboStrap\MediaMarkup;
21007225e5Sgerardnicouse ComboStrap\PluginUtility;
22*04fd306cSNickeauuse ComboStrap\Site;
23531e725cSNickeauuse ComboStrap\TagAttributes;
244cadd4f8SNickeauuse ComboStrap\Template;
25*04fd306cSNickeauuse ComboStrap\XmlTagProcessing;
26007225e5Sgerardnico
27007225e5Sgerardnicoif (!defined('DOKU_INC')) die();
28007225e5Sgerardnico
29007225e5Sgerardnico
3032b85071SNickeauclass syntax_plugin_combo_brand extends DokuWiki_Syntax_Plugin
3132b85071SNickeau{
3232b85071SNickeau
3332b85071SNickeau    const TAG = "brand";
344cadd4f8SNickeau    const CANONICAL = self::TAG;
354cadd4f8SNickeau
364cadd4f8SNickeau
374cadd4f8SNickeau    public static function addOpenLinkTagInCallStack(CallStack $callStack, TagAttributes $tagAttributes)
384cadd4f8SNickeau    {
394cadd4f8SNickeau        $linkArrayAttributes = $tagAttributes->toCallStackArray();
404cadd4f8SNickeau        $linkArrayAttributes[TagAttributes::TYPE_KEY] = $tagAttributes->getLogicalTag();
414cadd4f8SNickeau        $linkAttributes = TagAttributes::createFromCallStackArray($linkArrayAttributes);
424cadd4f8SNickeau        syntax_plugin_combo_link::addOpenLinkTagInCallStack($callStack, $linkAttributes);
434cadd4f8SNickeau    }
444cadd4f8SNickeau
45007225e5Sgerardnico
46007225e5Sgerardnico    /**
47007225e5Sgerardnico     * Syntax Type.
48007225e5Sgerardnico     *
49007225e5Sgerardnico     * Needs to return one of the mode types defined in $PARSER_MODES in parser.php
50007225e5Sgerardnico     * @see DokuWiki_Syntax_Plugin::getType()
51007225e5Sgerardnico     */
524cadd4f8SNickeau    function getType(): string
5332b85071SNickeau    {
544cadd4f8SNickeau        return 'substition';
55007225e5Sgerardnico    }
56007225e5Sgerardnico
57007225e5Sgerardnico    /**
58007225e5Sgerardnico     * How Dokuwiki will add P element
59007225e5Sgerardnico     *
60007225e5Sgerardnico     *  * 'normal' - The plugin can be used inside paragraphs
61007225e5Sgerardnico     *  * 'block'  - Open paragraphs need to be closed before plugin output - block should not be inside paragraphs
62007225e5Sgerardnico     *  * 'stack'  - Special case. Plugin wraps other paragraphs. - Stacks can contain paragraphs
63007225e5Sgerardnico     *
64007225e5Sgerardnico     * @see DokuWiki_Syntax_Plugin::getPType()
65007225e5Sgerardnico     */
664cadd4f8SNickeau    function getPType(): string
6732b85071SNickeau    {
68007225e5Sgerardnico        return 'normal';
69007225e5Sgerardnico    }
70007225e5Sgerardnico
71007225e5Sgerardnico    /**
72007225e5Sgerardnico     * @return array
73007225e5Sgerardnico     * Allow which kind of plugin inside
74007225e5Sgerardnico     *
75007225e5Sgerardnico     * array('container', 'baseonly', 'formatting', 'substition', 'protected', 'disabled', 'paragraphs')
76007225e5Sgerardnico     *
77007225e5Sgerardnico     */
784cadd4f8SNickeau    function getAllowedTypes(): array
7932b85071SNickeau    {
804cadd4f8SNickeau        return array('baseonly', 'formatting', 'substition', 'protected', 'disabled');
81007225e5Sgerardnico    }
82007225e5Sgerardnico
834cadd4f8SNickeau    function getSort(): int
8432b85071SNickeau    {
85007225e5Sgerardnico        return 201;
86007225e5Sgerardnico    }
87007225e5Sgerardnico
884cadd4f8SNickeau    public
894cadd4f8SNickeau    function accepts($mode): bool
90531e725cSNickeau    {
91531e725cSNickeau        return syntax_plugin_combo_preformatted::disablePreformatted($mode);
92531e725cSNickeau    }
93531e725cSNickeau
94007225e5Sgerardnico
95007225e5Sgerardnico    /**
96007225e5Sgerardnico     * Create a pattern that will called this plugin
97007225e5Sgerardnico     *
98007225e5Sgerardnico     * @param string $mode
9932b85071SNickeau     * @see Doku_Parser_Mode::connectTo()
100007225e5Sgerardnico     */
10132b85071SNickeau    function connectTo($mode)
10232b85071SNickeau    {
103007225e5Sgerardnico
104*04fd306cSNickeau        $pattern = XmlTagProcessing::getContainerTagPattern(self::getTag());
105007225e5Sgerardnico        $this->Lexer->addEntryPattern($pattern, $mode, 'plugin_' . PluginUtility::PLUGIN_BASE_NAME . '_' . $this->getPluginComponent());
106007225e5Sgerardnico
1074cadd4f8SNickeau        /**
1084cadd4f8SNickeau         * The empty tag pattern should be after the container pattern
1094cadd4f8SNickeau         */
1104cadd4f8SNickeau        $this->Lexer->addSpecialPattern(PluginUtility::getEmptyTagPattern(self::TAG), $mode, PluginUtility::getModeFromTag($this->getPluginComponent()));
1114cadd4f8SNickeau
112007225e5Sgerardnico    }
113007225e5Sgerardnico
11432b85071SNickeau    function postConnect()
11532b85071SNickeau    {
116007225e5Sgerardnico
117007225e5Sgerardnico        $this->Lexer->addExitPattern('</' . self::getTag() . '>', 'plugin_' . PluginUtility::PLUGIN_BASE_NAME . '_' . $this->getPluginComponent());
118007225e5Sgerardnico
119007225e5Sgerardnico    }
120007225e5Sgerardnico
12132b85071SNickeau    function handle($match, $state, $pos, Doku_Handler $handler)
12232b85071SNickeau    {
123007225e5Sgerardnico
1244cadd4f8SNickeau
125007225e5Sgerardnico        switch ($state) {
126007225e5Sgerardnico
1274cadd4f8SNickeau            case DOKU_LEXER_SPECIAL :
128007225e5Sgerardnico            case DOKU_LEXER_ENTER :
1294cadd4f8SNickeau
1304cadd4f8SNickeau                /**
131*04fd306cSNickeau                 * Tag building
1324cadd4f8SNickeau                 */
133*04fd306cSNickeau                $defaultAttributes = [TagAttributes::TYPE_KEY => Brand::CURRENT_BRAND];
134*04fd306cSNickeau                $tagAttributes = TagAttributes::createFromTagMatch($match, $defaultAttributes, [], true)
135*04fd306cSNickeau                    ->setLogicalTag(BrandTag::MARKUP);
1364cadd4f8SNickeau
1374cadd4f8SNickeau                /**
138*04fd306cSNickeau                 * Extra properties
1394cadd4f8SNickeau                 */
140*04fd306cSNickeau                $returnedArray = BrandTag::handleSpecialEnter($tagAttributes, $handler);
1414cadd4f8SNickeau
142*04fd306cSNickeau                /**
143*04fd306cSNickeau                 * Common properties
144*04fd306cSNickeau                 */
145*04fd306cSNickeau                $returnedArray[PluginUtility::STATE] = $state;
146*04fd306cSNickeau                $returnedArray[PluginUtility::ATTRIBUTES] = $tagAttributes->toCallStackArray();
147*04fd306cSNickeau                return $returnedArray;
148007225e5Sgerardnico
149007225e5Sgerardnico            case DOKU_LEXER_UNMATCHED :
15032b85071SNickeau                return PluginUtility::handleAndReturnUnmatchedData(self::TAG, $match, $handler);
151007225e5Sgerardnico
152007225e5Sgerardnico            case DOKU_LEXER_EXIT :
153007225e5Sgerardnico
1544cadd4f8SNickeau                $callStack = CallStack::createFromHandler($handler);
1554cadd4f8SNickeau                $openTag = $callStack->moveToPreviousCorrespondingOpeningCall();
1564cadd4f8SNickeau                $openTagAttributes = TagAttributes::createFromCallStackArray($openTag->getAttributes());
1574cadd4f8SNickeau                $openTagContext = $openTag->getContext();
1584cadd4f8SNickeau                /**
1594cadd4f8SNickeau                 * Old syntax
1604cadd4f8SNickeau                 * An icon/image could be already inside
1614cadd4f8SNickeau                 * We go from end to start to
1624cadd4f8SNickeau                 * see if there is also a text, if this is the case,
1634cadd4f8SNickeau                 * there is a class added on the media
1644cadd4f8SNickeau                 */
1654cadd4f8SNickeau                $markupIconImageFound = false;
1664cadd4f8SNickeau                $textFound = false;
1674cadd4f8SNickeau                $callStack->moveToEnd();
1684cadd4f8SNickeau                while ($actualCall = $callStack->previous()) {
1694cadd4f8SNickeau                    $tagName = $actualCall->getTagName();
170*04fd306cSNickeau                    if (in_array($tagName, [IconTag::TAG, syntax_plugin_combo_media::TAG])) {
1714cadd4f8SNickeau
1724cadd4f8SNickeau
1734cadd4f8SNickeau                        if ($textFound && $openTagContext === syntax_plugin_combo_menubar::TAG) {
1744cadd4f8SNickeau                            // if text and icon
1754cadd4f8SNickeau                            // We add it here because, if they are present, we don't add them later
1764cadd4f8SNickeau                            // for all on raster image
177*04fd306cSNickeau                            $actualCall->addClassName(BrandTag::BOOTSTRAP_NAV_BAR_IMAGE_AND_TEXT_CLASS);
1784cadd4f8SNickeau                        }
1794cadd4f8SNickeau
1804cadd4f8SNickeau                        // is it a added call / no content
1814cadd4f8SNickeau                        // or is it an icon from the markup
1824cadd4f8SNickeau                        if ($actualCall->getCapturedContent() === null) {
1834cadd4f8SNickeau
1844cadd4f8SNickeau                            // It's an added call
1854cadd4f8SNickeau                            // No user icon, image can be found anymore
1864cadd4f8SNickeau                            // exiting
1874cadd4f8SNickeau                            break;
1884cadd4f8SNickeau                        }
1894cadd4f8SNickeau
1904cadd4f8SNickeau                        $primary = $openTagAttributes->getValue(ColorRgb::PRIMARY_VALUE);
191*04fd306cSNickeau                        if ($primary !== null && $tagName === IconTag::TAG) {
1924cadd4f8SNickeau                            try {
193*04fd306cSNickeau                                $brandButton = BrandTag::createButtonFromAttributes($openTagAttributes);
1944cadd4f8SNickeau                                $actualCall->addAttribute(ColorRgb::COLOR, $brandButton->getTextColor());
195*04fd306cSNickeau                            } catch (ExceptionCompile $e) {
1964cadd4f8SNickeau                                LogUtility::msg("Error while trying to set the icon color on exit. Error: {$e->getMessage()}");
1974cadd4f8SNickeau                            }
1984cadd4f8SNickeau                        }
1994cadd4f8SNickeau
200*04fd306cSNickeau
201*04fd306cSNickeau                        // no linking inside a brand
202*04fd306cSNickeau                        $actualCall->addAttribute(MediaMarkup::LINKING_KEY, MediaMarkup::LINKING_NOLINK_VALUE);
2034cadd4f8SNickeau                        $markupIconImageFound = true;
204*04fd306cSNickeau
2054cadd4f8SNickeau                    }
2064cadd4f8SNickeau                    if ($actualCall->getState() === DOKU_LEXER_UNMATCHED) {
2074cadd4f8SNickeau                        $textFound = true;
2084cadd4f8SNickeau                    }
2094cadd4f8SNickeau                }
210*04fd306cSNickeau                $openTag->setPluginData(BrandTag::BRAND_IMAGE_FOUND_INDICATOR, $markupIconImageFound);
211*04fd306cSNickeau                $openTag->setPluginData(BrandTag::BRAND_TEXT_FOUND_INDICATOR, $textFound);
2124cadd4f8SNickeau
21332b85071SNickeau                return array(
21432b85071SNickeau                    PluginUtility::STATE => $state
21532b85071SNickeau                );
216007225e5Sgerardnico
217007225e5Sgerardnico
218007225e5Sgerardnico        }
219007225e5Sgerardnico        return array();
220007225e5Sgerardnico
221007225e5Sgerardnico    }
222007225e5Sgerardnico
223007225e5Sgerardnico    /**
224007225e5Sgerardnico     * Render the output
225007225e5Sgerardnico     * @param string $format
226007225e5Sgerardnico     * @param Doku_Renderer $renderer
2274cadd4f8SNickeau     * @param array $data - what the function handle() return
228007225e5Sgerardnico     * @return boolean - rendered correctly? (however, returned value is not used at the moment)
229007225e5Sgerardnico     * @see DokuWiki_Syntax_Plugin::render()
230007225e5Sgerardnico     *
231007225e5Sgerardnico     *
232007225e5Sgerardnico     */
2334cadd4f8SNickeau    function render($format, Doku_Renderer $renderer, $data): bool
23432b85071SNickeau    {
235007225e5Sgerardnico
2364cadd4f8SNickeau        if ($format === "xhtml") {
23732b85071SNickeau            $state = $data[PluginUtility::STATE];
238007225e5Sgerardnico            switch ($state) {
2394cadd4f8SNickeau                case DOKU_LEXER_SPECIAL:
240007225e5Sgerardnico                case DOKU_LEXER_ENTER:
2414cadd4f8SNickeau                    $tagAttributes = TagAttributes::createFromCallStackArray($data[PluginUtility::ATTRIBUTES]);
242*04fd306cSNickeau                    $renderer->doc .= BrandTag::render($tagAttributes, $state, $data);;
243007225e5Sgerardnico                    break;
244007225e5Sgerardnico                case DOKU_LEXER_UNMATCHED:
24532b85071SNickeau                    $renderer->doc .= PluginUtility::renderUnmatched($data);
246007225e5Sgerardnico                    break;
247007225e5Sgerardnico                case DOKU_LEXER_EXIT:
2484cadd4f8SNickeau                    $renderer->doc .= "</a>";
249007225e5Sgerardnico                    break;
2504cadd4f8SNickeau
251007225e5Sgerardnico            }
252007225e5Sgerardnico            return true;
253007225e5Sgerardnico        }
254007225e5Sgerardnico
255007225e5Sgerardnico        // unsupported $mode
256007225e5Sgerardnico        return false;
257007225e5Sgerardnico    }
258007225e5Sgerardnico
2594cadd4f8SNickeau    public
2604cadd4f8SNickeau    static function getTag(): string
261007225e5Sgerardnico    {
2624cadd4f8SNickeau        return self::TAG;
2634cadd4f8SNickeau    }
2644cadd4f8SNickeau
2654cadd4f8SNickeau    /**
2664cadd4f8SNickeau     *
267*04fd306cSNickeau     * @throws ExceptionCompile
2684cadd4f8SNickeau     */
2694cadd4f8SNickeau    public
2704cadd4f8SNickeau    static function addIconInCallStack(CallStack $callStack, BrandButton $brandButton)
2714cadd4f8SNickeau    {
2724cadd4f8SNickeau
2734cadd4f8SNickeau        if (!$brandButton->hasIcon()) {
2744cadd4f8SNickeau            return;
2754cadd4f8SNickeau        }
2764cadd4f8SNickeau        $iconAttributes = $brandButton->getIconAttributes();
2774cadd4f8SNickeau
2784cadd4f8SNickeau        $callStack->appendCallAtTheEnd(
2794cadd4f8SNickeau            Call::createComboCall(
280*04fd306cSNickeau                IconTag::TAG,
2814cadd4f8SNickeau                DOKU_LEXER_SPECIAL,
2824cadd4f8SNickeau                $iconAttributes
2834cadd4f8SNickeau            ));
284007225e5Sgerardnico    }
285007225e5Sgerardnico
286007225e5Sgerardnico}
287007225e5Sgerardnico
288