1<?php
2
3
4namespace ComboStrap;
5
6use ComboStrap\TagAttribute\BackgroundAttribute;
7use ComboStrap\TagAttribute\Shadow;
8
9/**
10 * Class Skin
11 * @package ComboStrap
12 * Processing the skin attribute
13 */
14class Skin
15{
16
17    const CANONICAL = self::SKIN_ATTRIBUTE;
18    const SKIN_ATTRIBUTE = "skin";
19    const FILLED_VALUE = "filled";
20
21
22    static $colorsWithoutPrimaryAndSecondary = array(
23        "info" => array(
24            ColorRgb::COLOR => "#0c5460",
25            BackgroundAttribute::BACKGROUND_COLOR => "#d1ecf1",
26            ColorRgb::BORDER_COLOR => "#bee5eb"
27        ),
28        "tip" => array(
29            ColorRgb::COLOR => "#6c6400",
30            BackgroundAttribute::BACKGROUND_COLOR => "#fff79f",
31            ColorRgb::BORDER_COLOR => "#FFF78c"
32        ),
33        "warning" => array(
34            ColorRgb::COLOR => "#856404",
35            BackgroundAttribute::BACKGROUND_COLOR => "#fff3cd",
36            ColorRgb::BORDER_COLOR => "#ffeeba"
37        ),
38        "success" => array(
39            ColorRgb::COLOR => "#fff",
40            BackgroundAttribute::BACKGROUND_COLOR => "#28a745",
41            ColorRgb::BORDER_COLOR => "#28a745"
42        ),
43        "danger" => array(
44            ColorRgb::COLOR => "#fff",
45            BackgroundAttribute::BACKGROUND_COLOR => "#dc3545",
46            ColorRgb::BORDER_COLOR => "#dc3545"
47        ),
48        "dark" => array(
49            ColorRgb::COLOR => "#fff",
50            BackgroundAttribute::BACKGROUND_COLOR => "#343a40",
51            ColorRgb::BORDER_COLOR => "#343a40"
52        ),
53        "light" => array(
54            ColorRgb::COLOR => "#fff",
55            BackgroundAttribute::BACKGROUND_COLOR => "#f8f9fa",
56            ColorRgb::BORDER_COLOR => "#f8f9fa"
57        )
58    );
59
60    public static function getSkinColors(): array
61    {
62        $primaryColorRgbHex = Site::getPrimaryColor("#007bff")->toRgbHex();
63        $secondaryColorRgbHex = Site::getSecondaryColor("#6c757d")->toRgbHex();
64        $brandingColors = array(ColorRgb::PRIMARY_VALUE => array(
65            ColorRgb::COLOR => "#fff",
66            BackgroundAttribute::BACKGROUND_COLOR => $primaryColorRgbHex,
67            ColorRgb::BORDER_COLOR => $primaryColorRgbHex
68        ),
69            ColorRgb::SECONDARY_VALUE => array(
70                ColorRgb::COLOR => "#fff",
71                BackgroundAttribute::BACKGROUND_COLOR => $secondaryColorRgbHex,
72                ColorRgb::BORDER_COLOR => $secondaryColorRgbHex
73            ));
74        return array_merge($brandingColors, self::$colorsWithoutPrimaryAndSecondary);
75    }
76
77    /**
78     * Used with button
79     * @param TagAttributes $attributes
80     */
81    public static function processSkinAttribute(TagAttributes &$attributes)
82    {
83        // Skin
84        if (!$attributes->hasComponentAttribute(self::SKIN_ATTRIBUTE)) {
85            return;
86        }
87        $skinValue = $attributes->getValueAndRemove(self::SKIN_ATTRIBUTE);
88        if (!$attributes->hasComponentAttribute(TagAttributes::TYPE_KEY)) {
89
90            LogUtility::msg("A component type is mandatory when using the skin attribute", LogUtility::LVL_MSG_WARNING, self::CANONICAL);
91
92        } else {
93            $type = $attributes->getValue(TagAttributes::TYPE_KEY);
94            if (
95                $skinValue === self::FILLED_VALUE
96                && ($attributes->hasClass("btn-$type")||$attributes->hasClass("alert-$type"))
97            ) {
98                $isBrandingColor = in_array($type, [ColorRgb::PRIMARY_VALUE, ColorRgb::SECONDARY_VALUE]);
99                if (!$isBrandingColor) {
100                    // example: light
101                    return;
102                }
103                if (!Site::isBrandingColorInheritanceFunctional()) {
104                    // example: primary, secondary
105                    return;
106                }
107            }
108
109            $skinColors = self::getSkinColors();
110            if (!isset($skinColors[$type])) {
111                $types = implode(", ", array_keys($skinColors));
112                LogUtility::msg("The type value ($type) is not supported. Only the following types value may be used: $types", LogUtility::LVL_MSG_WARNING, self::CANONICAL);
113            } else {
114                $color = $skinColors[$type];
115                switch ($skinValue) {
116                    case "contained":
117                        $attributes->addStyleDeclarationIfNotSet(ColorRgb::COLOR, $color[ColorRgb::COLOR]);
118                        $attributes->addStyleDeclarationIfNotSet(BackgroundAttribute::BACKGROUND_COLOR, $color[BackgroundAttribute::BACKGROUND_COLOR]);
119                        $attributes->addStyleDeclarationIfNotSet(ColorRgb::BORDER_COLOR, $color[ColorRgb::BORDER_COLOR]);
120                        Shadow::addMediumElevation($attributes);
121                        break;
122                    case self::FILLED_VALUE:
123                    case "solid":
124                        $attributes->addStyleDeclarationIfNotSet(ColorRgb::COLOR, $color[ColorRgb::COLOR]);
125                        $attributes->addStyleDeclarationIfNotSet(BackgroundAttribute::BACKGROUND_COLOR, $color[BackgroundAttribute::BACKGROUND_COLOR]);
126                        $attributes->addStyleDeclarationIfNotSet(ColorRgb::BORDER_COLOR, $color[ColorRgb::BORDER_COLOR]);
127                        break;
128                    case "outline":
129                        $primaryColor = $color[ColorRgb::COLOR];
130                        if ($primaryColor === "#fff") {
131                            $primaryColor = $color[BackgroundAttribute::BACKGROUND_COLOR];
132                        }
133                        $attributes->addStyleDeclarationIfNotSet(ColorRgb::COLOR, $primaryColor);
134                        $attributes->addStyleDeclarationIfNotSet(BackgroundAttribute::BACKGROUND_COLOR, "transparent");
135                        $borderColor = $color[BackgroundAttribute::BACKGROUND_COLOR];
136                        if ($attributes->hasStyleDeclaration(ColorRgb::BORDER_COLOR)) {
137                            // Color in the `border` attribute
138                            // takes precedence in the `border-color` if located afterwards
139                            // We don't take the risk
140                            $borderColor = $attributes->getAndRemoveStyleDeclaration(ColorRgb::BORDER_COLOR);
141                        }
142                        $attributes->addStyleDeclarationIfNotSet("border", "1px solid " . $borderColor);
143
144                        break;
145                    case "text":
146                        $primaryColor = $color[ColorRgb::COLOR];
147                        if ($primaryColor === "#fff") {
148                            $primaryColor = $color[BackgroundAttribute::BACKGROUND_COLOR];
149                        }
150                        $attributes->addStyleDeclarationIfNotSet(ColorRgb::COLOR, "$primaryColor!important");
151                        $attributes->addStyleDeclarationIfNotSet(BackgroundAttribute::BACKGROUND_COLOR, "transparent");
152                        $attributes->addStyleDeclarationIfNotSet(ColorRgb::BORDER_COLOR, "transparent");
153                        break;
154                }
155            }
156        }
157    }
158
159}
160