1<?php
2
3namespace ComboStrap;
4
5class Icon
6{
7
8    public const ICON_CANONICAL_NAME = "icon";
9
10    private TagAttributes $tagAttributes;
11    private FetcherSvg $fetchSvg;
12
13    /**
14     * @param string $name
15     * @param TagAttributes|null $iconAttributes
16     * @return Icon
17     * @throws ExceptionBadArgument
18     * @throws ExceptionBadSyntax
19     * @throws ExceptionCompile
20     * @throws ExceptionNotExists
21     * @throws ExceptionNotFound
22     */
23    public static function createFromName(string $name, TagAttributes $iconAttributes = null): Icon
24    {
25        if ($iconAttributes === null) {
26            $iconAttributes = TagAttributes::createEmpty(self::ICON_CANONICAL_NAME);
27        }
28        $iconAttributes->addComponentAttributeValue(FetcherSvg::NAME_ATTRIBUTE, $name);
29        return self::createFromTagAttributes($iconAttributes);
30    }
31
32    /**
33     * @throws ExceptionBadArgument
34     * @throws ExceptionBadSyntax
35     * @throws ExceptionNotExists
36     * @throws ExceptionNotFound
37     * @throws ExceptionCompile
38     */
39    public static function createFromTagAttributes(TagAttributes $tagAttributes): Icon
40    {
41        /**
42         * The svg
43         * Adding the icon type is mandatory if there is no media
44         */
45        $tagAttributes->addComponentAttributeValue(TagAttributes::TYPE_KEY, FetcherSvg::ICON_TYPE);
46
47        /**
48         * Icon Svg file or Icon Library
49         */
50        $name = $tagAttributes->getValue(FetcherSvg::NAME_ATTRIBUTE);
51        if ($name === null) {
52            throw new ExceptionNotFound("A name is mandatory as attribute for an icon. It was not found.", Icon::ICON_CANONICAL_NAME);
53        }
54
55        /**
56         * If the name have an extension, it's a file from the media directory
57         * Otherwise, it's an icon from a library
58         */
59        $mediaDokuPath = WikiPath::createMediaPathFromId($name);
60        try {
61            $extension = $mediaDokuPath->getExtension();
62            if ($extension !== "svg") {
63                throw new ExceptionBadArgument("The extension of the icon ($name) is not `svg`", Icon::ICON_CANONICAL_NAME);
64            }
65            if (!FileSystems::exists($mediaDokuPath)) {
66
67                // Trying to see if it's not in the template images directory
68                $message = "The svg icon file ($mediaDokuPath) does not exists. If you want an icon from an icon library, indicate a name without extension.";
69                throw new ExceptionNotExists($message, Icon::ICON_CANONICAL_NAME);
70
71            }
72
73            $tagAttributes->addComponentAttributeValue(MediaMarkup::$MEDIA_QUERY_PARAMETER, $mediaDokuPath->getWikiId());
74            $tagAttributes->setComponentAttributeValue(FetcherSvg::NAME_ATTRIBUTE, $mediaDokuPath->getLastNameWithoutExtension());
75
76
77        } catch (ExceptionNotFound $e) {
78
79            /**
80             * No file extension
81             * From an icon library
82             */
83
84        }
85        $fetcherSvg = FetcherSvg::createFromAttributes($tagAttributes);
86
87        return (new Icon())
88            ->setFetcherSvg($fetcherSvg)
89            ->setTagAttributes($tagAttributes);
90    }
91
92    /**
93     */
94    public static function createFromComboResource(string $name, TagAttributes $tagAttributes = null): Icon
95    {
96        $icon = new Icon();
97        $path = WikiPath::createComboResource(":$name.svg");
98        $fetchSvg = FetcherSvg::createSvgFromPath($path);
99        $icon->setFetcherSvg($fetchSvg);
100        if ($tagAttributes !== null) {
101            $icon->setTagAttributes($tagAttributes);
102        }
103        return $icon;
104    }
105
106    public function setFetcherSvg(FetcherSvg $fetchSvg): Icon
107    {
108        $this->fetchSvg = $fetchSvg;
109        return $this;
110    }
111
112    private function setTagAttributes(TagAttributes $tagAttributes): Icon
113    {
114        $this->tagAttributes = $tagAttributes;
115        return $this;
116    }
117
118    /**
119     * @throws ExceptionCompile
120     */
121    public function toHtml(): string
122    {
123
124
125        $mediaMarkup = MediaMarkup::createFromFetcher($this->fetchSvg)
126            ->setLinking(MediaMarkup::LINKING_NOLINK_VALUE); // no lightbox on icon
127        if (isset($this->tagAttributes)) {
128            $mediaMarkup->buildFromTagAttributes($this->tagAttributes);
129        }
130
131        return SvgImageLink::createFromMediaMarkup($mediaMarkup)
132            ->renderMediaTag();
133
134
135    }
136
137    public function getFetchSvg(): FetcherSvg
138    {
139        return $this->fetchSvg;
140    }
141}
142