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