xref: /plugin/combo/syntax/link.php (revision e68157ebf6d6af7c088f0d907234fcc5991444e9)
1<?php
2
3
4require_once(__DIR__ . "/../class/Analytics.php");
5require_once(__DIR__ . "/../class/PluginUtility.php");
6require_once(__DIR__ . "/../class/LinkUtility.php");
7require_once(__DIR__ . "/../class/HtmlUtility.php");
8
9use ComboStrap\Analytics;
10use ComboStrap\HtmlUtility;
11use ComboStrap\LinkUtility;
12use ComboStrap\LogUtility;
13use ComboStrap\NavBarUtility;
14use ComboStrap\Page;
15use ComboStrap\PluginUtility;
16use ComboStrap\LowQualityPage;
17use ComboStrap\Tag;
18
19if (!defined('DOKU_INC')) die();
20
21/**
22 *
23 * A link pattern to take over the link of Dokuwiki
24 * and transform it as a bootstrap link
25 *
26 * The handle of the move of link is to be found in the
27 * admin action {@link action_plugin_combo_linkmove}
28 *
29 */
30class syntax_plugin_combo_link extends DokuWiki_Syntax_Plugin
31{
32    const TAG = 'link';
33    const COMPONENT = 'combo_link';
34
35
36    /**
37     * Syntax Type.
38     *
39     * Needs to return one of the mode types defined in $PARSER_MODES in parser.php
40     * @see https://www.dokuwiki.org/devel:syntax_plugins#syntax_types
41     */
42    function getType()
43    {
44        return 'substition';
45    }
46
47    /**
48     * How Dokuwiki will add P element
49     *
50     *  * 'normal' - The plugin can be used inside paragraphs
51     *  * 'block'  - Open paragraphs need to be closed before plugin output - block should not be inside paragraphs
52     *  * 'stack'  - Special case. Plugin wraps other paragraphs. - Stacks can contain paragraphs
53     *
54     * @see DokuWiki_Syntax_Plugin::getPType()
55     */
56    function getPType()
57    {
58        return 'normal';
59    }
60
61    /**
62     * @return array
63     * Allow which kind of plugin inside
64     *
65     * No one of array('container', 'baseonly', 'formatting', 'substition', 'protected', 'disabled', 'paragraphs')
66     * because we manage self the content and we call self the parser
67     */
68    function getAllowedTypes()
69    {
70        return array('substition', 'formatting', 'disabled');
71    }
72
73    /**
74     * @see Doku_Parser_Mode::getSort()
75     * The mode with the lowest sort number will win out
76     */
77    function getSort()
78    {
79        return 100;
80    }
81
82
83    function connectTo($mode)
84    {
85
86        $this->Lexer->addSpecialPattern(LinkUtility::LINK_PATTERN, $mode, PluginUtility::getModeForComponent($this->getPluginComponent()));
87
88    }
89
90
91    /**
92     * The handler for an internal link
93     * based on `internallink` in {@link Doku_Handler}
94     * The handler call the good renderer in {@link Doku_Renderer_xhtml} with
95     * the parameters (ie for instance internallink)
96     * @param string $match
97     * @param int $state
98     * @param int $pos
99     * @param Doku_Handler $handler
100     * @return array|bool
101     */
102    function handle($match, $state, $pos, Doku_Handler $handler)
103    {
104
105        /**
106         * Because we use the specialPattern, there is only one state ie DOKU_LEXER_SPECIAL
107         */
108        $attributes = LinkUtility::getAttributes($match);
109        $tag = new Tag(self::TAG, $attributes, $state, $handler->calls);
110        $parent = $tag->getParent();
111        $parentName = "";
112        if ($parent != null) {
113            $parentName = $parent->getName();
114        }
115        return array(
116            PluginUtility::ATTRIBUTES => $attributes,
117            PluginUtility::PARENT_TAG => $parentName
118        );
119
120
121    }
122
123    /**
124     * Render the output
125     * @param string $format
126     * @param Doku_Renderer $renderer
127     * @param array $data - what the function handle() return'ed
128     * @return boolean - rendered correctly? (however, returned value is not used at the moment)
129     * @see DokuWiki_Syntax_Plugin::render()
130     *
131     *
132     */
133    function render($format, Doku_Renderer $renderer, $data)
134    {
135        // The data
136        switch ($format) {
137            case 'xhtml':
138
139                /** @var Doku_Renderer_xhtml $renderer */
140
141                /**
142                 * Cache problem may occurs while releasing
143                 */
144                if (isset($data[PluginUtility::ATTRIBUTES])) {
145                    $attributes = $data[PluginUtility::ATTRIBUTES];
146                } else {
147                    $attributes = $data;
148                }
149                $ref = $attributes[LinkUtility::ATTRIBUTE_REF];
150                $name = $attributes[LinkUtility::ATTRIBUTE_NAME];
151                $type = $attributes[LinkUtility::ATTRIBUTE_TYPE];
152                $link = new LinkUtility($ref);
153                if ($name != null) {
154                    $link->setName($name);
155                }
156                $link->setType($type);
157
158                /**
159                 * Render the link
160                 */
161                $htmlLink = $link->render($renderer);
162
163                /**
164                 * Extra styling for internal link
165                 */
166                $parentTag = $data[PluginUtility::PARENT_TAG];
167                switch ($parentTag) {
168                    case syntax_plugin_combo_button::TAG:
169                    case syntax_plugin_combo_badge::TAG:
170                        if ($link->getType() == LinkUtility::TYPE_INTERNAL) {
171                            if ($link->getInternalPage()->existInFs()) {
172                                $htmlLink = LinkUtility::deleteDokuWikiClass($htmlLink);
173                                $htmlLink = LinkUtility::inheritColorFromParent($htmlLink);
174                            }
175                        } else {
176                            $htmlLink = LinkUtility::inheritColorFromParent($htmlLink);
177                        }
178                        break;
179                    case syntax_plugin_combo_cite::TAG:
180                    case syntax_plugin_combo_listitem::TAG:
181                    case syntax_plugin_combo_preformatted::TAG:
182                        if ($link->getType() == LinkUtility::TYPE_INTERNAL) {
183                            if ($link->getInternalPage()->existInFs()) {
184                                $htmlLink = LinkUtility::deleteDokuWikiClass($htmlLink);
185                            }
186                        }
187                        break;
188                    case syntax_plugin_combo_dropdown::TAG:
189                        if ($link->getType() == LinkUtility::TYPE_INTERNAL) {
190                            if ($link->getInternalPage()->existInFs()) {
191                                $htmlLink = LinkUtility::deleteDokuWikiClass($htmlLink);
192                            }
193                        }
194                        $htmlLink = HtmlUtility::addAttributeValue($htmlLink, "class", "dropdown-item");
195                        break;
196                    case syntax_plugin_combo_navbarcollapse::COMPONENT:
197                        $htmlLink = '<div class="navbar-nav">' . NavBarUtility::switchDokuwiki2BootstrapClass($htmlLink) . '</div>';
198                        break;
199                    case syntax_plugin_combo_navbargroup::COMPONENT:
200                        $htmlLink = '<li class="nav-item">' . NavBarUtility::switchDokuwiki2BootstrapClass($htmlLink) . '</li>';
201                        break;
202
203                }
204
205
206                /**
207                 * Add it to the rendering
208                 */
209                $renderer->doc .= $htmlLink;
210
211                return true;
212                break;
213
214            case
215            'metadata':
216
217                /**
218                 * Keep track of the backlinks ie meta['relation']['references']
219                 * @var Doku_Renderer_metadata $renderer
220                 */
221                if (isset($data[PluginUtility::ATTRIBUTES])) {
222                    $attributes = $data[PluginUtility::ATTRIBUTES];
223                } else {
224                    $attributes = $data;
225                }
226                $ref = $attributes[LinkUtility::ATTRIBUTE_REF];
227
228                $link = new LinkUtility($ref);
229                $name = $attributes[LinkUtility::ATTRIBUTE_NAME];
230                if ($name != null) {
231                    $link->setName($name);
232                }
233                $link->handleMetadata($renderer);
234
235                return true;
236                break;
237
238            case Analytics::RENDERER_FORMAT:
239                /**
240                 *
241                 * @var renderer_plugin_combo_analytics $renderer
242                 */
243                $attributes = $data[PluginUtility::ATTRIBUTES];
244                $ref = $attributes[LinkUtility::ATTRIBUTE_REF];
245                $link = new LinkUtility($ref);
246                $link->processLinkStats($renderer->stats);
247                break;
248
249        }
250        // unsupported $mode
251        return false;
252    }
253
254
255}
256
257