1<?php
2
3
4require_once(__DIR__ . "/../ComboStrap/PluginUtility.php");
5
6use ComboStrap\Brand;
7use ComboStrap\BrandButton;
8use ComboStrap\ExceptionCombo;
9use ComboStrap\ExceptionComboRuntime;
10use ComboStrap\Icon;
11use ComboStrap\Page;
12use ComboStrap\PluginUtility;
13use ComboStrap\TagAttributes;
14
15
16/**
17 * Just to output the list of brand
18 * Not a real tag
19 */
20class syntax_plugin_combo_brandlist extends DokuWiki_Syntax_Plugin
21{
22
23
24    const TAG = "brand-list";
25
26    function getType()
27    {
28        return 'substition';
29    }
30
31    /**
32     * How Dokuwiki will add P element
33     *
34     *  * 'normal' - The plugin can be used inside paragraphs (inline)
35     *  * 'block'  - Open paragraphs need to be closed before plugin output - block should not be inside paragraphs
36     *  * 'stack'  - Special case. Plugin wraps other paragraphs. - Stacks can contain paragraphs
37     *
38     * @see DokuWiki_Syntax_Plugin::getPType()
39     */
40    function getPType(): string
41    {
42        return 'block';
43    }
44
45    function getAllowedTypes(): array
46    {
47        return array();
48    }
49
50    function getSort(): int
51    {
52        return 201;
53    }
54
55
56    function connectTo($mode)
57    {
58
59        $this->Lexer->addSpecialPattern(PluginUtility::getEmptyTagPattern(self::TAG), $mode, PluginUtility::getModeFromTag($this->getPluginComponent()));
60
61    }
62
63
64    function handle($match, $state, $pos, Doku_Handler $handler): array
65    {
66
67        switch ($state) {
68
69
70            case DOKU_LEXER_SPECIAL :
71
72                $tagAttributes = TagAttributes::createFromTagMatch($match,
73                    [
74                        TagAttributes::TYPE_KEY => BrandButton::TYPE_BUTTON_BRAND
75                    ],
76                    BrandButton::TYPE_BUTTONS
77                );
78                return array(
79                    PluginUtility::STATE => $state,
80                    PluginUtility::ATTRIBUTES => $tagAttributes->toCallStackArray()
81                );
82
83
84        }
85        return array();
86
87    }
88
89    /**
90     * Render the output
91     * @param string $format
92     * @param Doku_Renderer $renderer
93     * @param array $data - what the function handle() return'ed
94     * @return boolean - rendered correctly? (however, returned value is not used at the moment)
95     * @see DokuWiki_Syntax_Plugin::render()
96     *
97     *
98     */
99    function render($format, Doku_Renderer $renderer, $data): bool
100    {
101
102        if ($format == 'xhtml') {
103
104            /** @var Doku_Renderer_xhtml $renderer */
105            try {
106                $brandDictionary = Brand::getBrandDictionary();
107                $brandNames = array_keys($brandDictionary);
108                sort($brandNames);
109            } catch (ExceptionCombo $e) {
110                $renderer->doc .= "Error while creating the brand list. Error: {$e->getMessage()}";
111                return false;
112            }
113
114            $variants = BrandButton::getVariants();
115
116            $snippetManager = PluginUtility::getSnippetManager();
117            $snippetManager->attachCssInternalStyleSheetForSlot("table");
118            $html = <<<EOF
119<table class="table table-non-fluid">
120<thead>
121    <tr>
122    <th scope="col">
123Brand Name
124    </th>
125EOF;
126            foreach ($variants as $variant) {
127                $iconType = ucfirst($variant[syntax_plugin_combo_brand::ICON_ATTRIBUTE]);
128                $widgetType = ucfirst($variant[TagAttributes::TYPE_KEY]);
129                $html .= <<<EOF
130    <th scope="col">
131$widgetType <br/> $iconType
132    </th>
133EOF;
134            }
135
136            $html .= <<<EOF
137</tr>
138</thead>
139<tbody>
140EOF;
141
142            $tagAttributes = TagAttributes::createFromCallStackArray($data[PluginUtility::ATTRIBUTES]);
143            $type = $tagAttributes->getType();
144            foreach ($brandNames as $brandName) {
145
146                try {
147
148                    $brandButton = new BrandButton($brandName, $type);
149                    if (!$brandButton->getBrand()->supportButtonType($type)) {
150                        continue;
151                    }
152                    /**
153                     * Begin row
154                     */
155                    $html .= "<tr>";
156
157                    /**
158                     * First column
159                     */
160
161                    $html .= "<td>" . ucfirst($brandName) . "</td>";
162
163
164                    foreach ($variants as $variant) {
165                        $iconType = $variant[syntax_plugin_combo_brand::ICON_ATTRIBUTE];
166                        $widgetType = $variant[TagAttributes::TYPE_KEY];
167                        $brandButton
168                            ->setIconType($iconType)
169                            ->setWidget($widgetType);
170                        /**
171                         * Second column
172                         */
173                        $html .= "<td>";
174                        $page = null;
175                        if ($type === BrandButton::TYPE_BUTTON_SHARE) {
176                            $page = Page::createPageFromRequestedPage();
177                        }
178                        $html .= $brandButton->getLinkAttributes($page)->toHtmlEnterTag("a");
179
180                        if ($brandButton->hasIcon()) {
181                            $iconArrayAttributes = $brandButton->getIconAttributes();
182                            $iconAttributes = TagAttributes::createFromCallStackArray($iconArrayAttributes);
183                            $name = $iconAttributes->getValueAndRemoveIfPresent(syntax_plugin_combo_icon::ICON_NAME_ATTRIBUTE);
184                            if ($name !== null) {
185                                $html .= Icon::create($name, $iconAttributes)->render();
186                            } else {
187                                $html .= "Icon name is null for brand $brandName";
188                            }
189                        }
190                        $snippetManager->attachCssInternalStyleSheetForSlot($brandButton->getStyleScriptIdentifier(), $brandButton->getStyle());
191                        $html .= "</a></td>";
192                    }
193
194                    /**
195                     * End row
196                     */
197                    $html .= "</tr>" . PHP_EOL;
198                } catch (ExceptionCombo $e) {
199                    $message = "Error while rendering the brand $brandName. Error: {$e->getMessage()}";
200                    if (!PluginUtility::isDevOrTest()) {
201                        $rowSpan = sizeof($variants)+1; // 1 for the brand column
202                        $renderer->doc .= "<tr><td rowspan=\"$rowSpan\" class=\"text-danger\">$message</td></tr>";
203                    } else {
204                        throw new ExceptionComboRuntime($message, self::TAG, 0, $e);
205                    }
206                }
207            }
208            /**
209             * End table
210             */
211            $html .= <<<EOF
212</tbody>
213</table>
214EOF;
215
216            $renderer->doc .= $html;
217
218
219        }
220        // unsupported $mode
221        return false;
222    }
223
224
225}
226
227