xref: /template/strap/ComboStrap/IconTag.php (revision 04fd306c7c155fa133ebb3669986875d65988276)
1*04fd306cSNickeau<?php
2*04fd306cSNickeau
3*04fd306cSNickeaunamespace ComboStrap;
4*04fd306cSNickeau
5*04fd306cSNickeauuse Doku_Handler;
6*04fd306cSNickeauuse Doku_Renderer_metadata;
7*04fd306cSNickeauuse Exception;
8*04fd306cSNickeauuse syntax_plugin_combo_link;
9*04fd306cSNickeauuse syntax_plugin_combo_media;
10*04fd306cSNickeauuse syntax_plugin_combo_note;
11*04fd306cSNickeauuse syntax_plugin_combo_tooltip;
12*04fd306cSNickeau
13*04fd306cSNickeauclass IconTag
14*04fd306cSNickeau{
15*04fd306cSNickeau
16*04fd306cSNickeau    const CANONICAL = "icon";
17*04fd306cSNickeau    public const TAG = "icon";
18*04fd306cSNickeau
19*04fd306cSNickeau    public static function handleSpecial(TagAttributes $tagAttributes, Doku_Handler $handler): array
20*04fd306cSNickeau    {
21*04fd306cSNickeau        // Get the parameters
22*04fd306cSNickeau        $callStack = CallStack::createFromHandler($handler);
23*04fd306cSNickeau        $parent = $callStack->moveToParent();
24*04fd306cSNickeau        $context = "";
25*04fd306cSNickeau        if ($parent !== false) {
26*04fd306cSNickeau            $context = $parent->getTagName();
27*04fd306cSNickeau            if ($context === syntax_plugin_combo_link::TAG) {
28*04fd306cSNickeau                $context = $parent->getTagName();
29*04fd306cSNickeau            }
30*04fd306cSNickeau        }
31*04fd306cSNickeau        /**
32*04fd306cSNickeau         * Color setting should know the color of its parent
33*04fd306cSNickeau         * For now, we don't set any color if the parent is a button, note, link
34*04fd306cSNickeau         * As a header is not a parent, we may say that if the icon is contained, the default
35*04fd306cSNickeau         * branding color is not set ?
36*04fd306cSNickeau         */
37*04fd306cSNickeau        $requestedColor = $tagAttributes->getValue(ColorRgb::COLOR);
38*04fd306cSNickeau        if (
39*04fd306cSNickeau            $requestedColor === null &&
40*04fd306cSNickeau            Site::isBrandingColorInheritanceEnabled() &&
41*04fd306cSNickeau            !in_array($context, [
42*04fd306cSNickeau                ButtonTag::MARKUP_LONG,
43*04fd306cSNickeau                syntax_plugin_combo_note::TAG,
44*04fd306cSNickeau                syntax_plugin_combo_link::TAG
45*04fd306cSNickeau            ])
46*04fd306cSNickeau        ) {
47*04fd306cSNickeau
48*04fd306cSNickeau            $requestedWidth = $tagAttributes->getValue(Dimension::WIDTH_KEY, FetcherSvg::DEFAULT_ICON_LENGTH);
49*04fd306cSNickeau
50*04fd306cSNickeau            // By default, a character icon
51*04fd306cSNickeau            $color = Site::getSecondaryColor();
52*04fd306cSNickeau            try {
53*04fd306cSNickeau                $requestedWidthInPx = ConditionalLength::createFromString($requestedWidth)->toPixelNumber();
54*04fd306cSNickeau                if ($requestedWidthInPx > 36) {
55*04fd306cSNickeau                    // Illustrative icon
56*04fd306cSNickeau                    $color = Site::getPrimaryColor();
57*04fd306cSNickeau                }
58*04fd306cSNickeau            } catch (ExceptionBadArgument $e) {
59*04fd306cSNickeau                LogUtility::error("The requested icon width ($requestedWidth) is not a conform width. Error: " . $e->getMessage(), self::CANONICAL, $e);
60*04fd306cSNickeau            }
61*04fd306cSNickeau
62*04fd306cSNickeau            if ($color !== null) {
63*04fd306cSNickeau                $tagAttributes->setComponentAttributeValue(ColorRgb::COLOR, $color);
64*04fd306cSNickeau            }
65*04fd306cSNickeau        }
66*04fd306cSNickeau        return array(PluginUtility::CONTEXT => $context);
67*04fd306cSNickeau    }
68*04fd306cSNickeau
69*04fd306cSNickeau    public static function exceptionHandling(Exception $e, $tagAttribute): string
70*04fd306cSNickeau    {
71*04fd306cSNickeau        $errorClass = syntax_plugin_combo_media::SVG_RENDERING_ERROR_CLASS;
72*04fd306cSNickeau        $message = "Icon ({$tagAttribute->getValue("name")}). Error while rendering: {$e->getMessage()}";
73*04fd306cSNickeau        $html = "<span class=\"text-danger $errorClass\">" . hsc(trim($message)) . "</span>";
74*04fd306cSNickeau        LogUtility::warning($message, self::CANONICAL, $e);
75*04fd306cSNickeau        return $html;
76*04fd306cSNickeau    }
77*04fd306cSNickeau
78*04fd306cSNickeau    /**
79*04fd306cSNickeau     * @param TagAttributes $tagAttributes
80*04fd306cSNickeau     * @return string
81*04fd306cSNickeau     */
82*04fd306cSNickeau    public static function renderEmptyTag(TagAttributes $tagAttributes): string
83*04fd306cSNickeau    {
84*04fd306cSNickeau
85*04fd306cSNickeau        try {
86*04fd306cSNickeau            return Icon::createFromTagAttributes($tagAttributes)
87*04fd306cSNickeau                ->toHtml();
88*04fd306cSNickeau        } catch (\Exception $e) {
89*04fd306cSNickeau            // catch all
90*04fd306cSNickeau            return IconTag::exceptionHandling($e, $tagAttributes);
91*04fd306cSNickeau        }
92*04fd306cSNickeau
93*04fd306cSNickeau    }
94*04fd306cSNickeau
95*04fd306cSNickeau    /**
96*04fd306cSNickeau     * @param Doku_Renderer_metadata $renderer
97*04fd306cSNickeau     * @param $tagAttribute
98*04fd306cSNickeau     * @return void
99*04fd306cSNickeau     */
100*04fd306cSNickeau    public static function metadata(Doku_Renderer_metadata $renderer, $tagAttribute)
101*04fd306cSNickeau    {
102*04fd306cSNickeau
103*04fd306cSNickeau        try {
104*04fd306cSNickeau            $mediaPath = Icon::createFromTagAttributes($tagAttribute)->getFetchSvg()->getSourcePath();
105*04fd306cSNickeau        } catch (ExceptionCompile $e) {
106*04fd306cSNickeau            // error is already fired in the renderer
107*04fd306cSNickeau            return;
108*04fd306cSNickeau        }
109*04fd306cSNickeau        if (FileSystems::exists($mediaPath)) {
110*04fd306cSNickeau            syntax_plugin_combo_media::registerFirstImage($renderer, $mediaPath);
111*04fd306cSNickeau        }
112*04fd306cSNickeau    }
113*04fd306cSNickeau
114*04fd306cSNickeau    public static function handleEnter(TagAttributes $tagAttributes, Doku_Handler $handler): array
115*04fd306cSNickeau    {
116*04fd306cSNickeau        return self::handleSpecial($tagAttributes, $handler);
117*04fd306cSNickeau    }
118*04fd306cSNickeau
119*04fd306cSNickeau    public static function handleExit(Doku_Handler $handler): array
120*04fd306cSNickeau    {
121*04fd306cSNickeau        $callStack = CallStack::createFromHandler($handler);
122*04fd306cSNickeau        $openingCall = $callStack->moveToPreviousCorrespondingOpeningCall();
123*04fd306cSNickeau        return array(
124*04fd306cSNickeau            PluginUtility::ATTRIBUTES => $openingCall->getAttributes(),
125*04fd306cSNickeau            PluginUtility::CONTEXT => $openingCall->getContext()
126*04fd306cSNickeau        );
127*04fd306cSNickeau    }
128*04fd306cSNickeau
129*04fd306cSNickeau    public static function renderEnterTag(TagAttributes $tagAttributes): string
130*04fd306cSNickeau    {
131*04fd306cSNickeau        $tooltip = $tagAttributes->getValueAndRemoveIfPresent(Tooltip::TOOLTIP_ATTRIBUTE);
132*04fd306cSNickeau        $html = "";
133*04fd306cSNickeau        if ($tooltip !== null) {
134*04fd306cSNickeau            /**
135*04fd306cSNickeau             * If there is a tooltip, we need
136*04fd306cSNickeau             * to start with a span to wrap the svg with it
137*04fd306cSNickeau             */
138*04fd306cSNickeau
139*04fd306cSNickeau
140*04fd306cSNickeau            $tooltipTag = TagAttributes::createFromCallStackArray([Tooltip::TOOLTIP_ATTRIBUTE => $tooltip])
141*04fd306cSNickeau                ->addClassName(syntax_plugin_combo_tooltip::TOOLTIP_CLASS_INLINE_BLOCK);
142*04fd306cSNickeau            $html .= $tooltipTag->toHtmlEnterTag("span");
143*04fd306cSNickeau        }
144*04fd306cSNickeau        /**
145*04fd306cSNickeau         * Print the icon
146*04fd306cSNickeau         */
147*04fd306cSNickeau        $html .= IconTag::renderEmptyTag($tagAttributes);
148*04fd306cSNickeau        /**
149*04fd306cSNickeau         * Close the span if we are in a tooltip context
150*04fd306cSNickeau         */
151*04fd306cSNickeau        if ($tooltip !== null) {
152*04fd306cSNickeau            $html .= "</span>";
153*04fd306cSNickeau        }
154*04fd306cSNickeau        return $html;
155*04fd306cSNickeau    }
156*04fd306cSNickeau}
157