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