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