xref: /plugin/combo/syntax/link.php (revision 325fe0c5d5016188ce55114b3b4989c2bac99858)
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                    $qualifiedPageId = LinkUtility::toQualifiedLink($id);
163                    $page = new Page($qualifiedPageId);
164                    if ($this->getConf(LowQualityPage::CONF_LOW_QUALITY_PAGE_PROTECTION_ENABLE)
165                        && $page->isLowQualityPage()) {
166
167                        $lowLink = true;
168                    }
169                }
170
171                /**
172                 * Render the link
173                 */
174                $htmlLink = LinkUtility::renderLinkDefault($renderer, $attributes, $lowLink);
175
176                /**
177                 * Extra styling
178                 */
179                $parentClassWithoutClass = array(
180                    syntax_plugin_combo_button::TAG,
181                    syntax_plugin_combo_cite::TAG,
182                    syntax_plugin_combo_dropdown::TAG,
183                    syntax_plugin_combo_listitem::TAG,
184                    syntax_plugin_combo_preformatted::TAG
185                );
186                if (page_exists($id) && in_array($data[PluginUtility::PARENT_TAG], $parentClassWithoutClass)) {
187                    $htmlLink = LinkUtility::deleteDokuWikiClass($htmlLink);
188                }
189
190                if ($data[PluginUtility::PARENT_TAG] == syntax_plugin_combo_button::TAG) {
191                    // We could also apply the class ie btn-secondary ...
192                    $htmlLink = LinkUtility::inheritColorFromParent($htmlLink);
193                }
194
195                /**
196                 * Add it to the rendering
197                 */
198                $renderer->doc .= $htmlLink;
199
200                return true;
201                break;
202
203            case
204            'metadata':
205
206                /**
207                 * Keep track of the backlinks ie meta['relation']['references']
208                 * @var Doku_Renderer_metadata $renderer
209                 */
210                if (isset($data[PluginUtility::ATTRIBUTES])) {
211                    $attributes = $data[PluginUtility::ATTRIBUTES];
212                } else {
213                    $attributes = $data;
214                }
215                LinkUtility::handleMetadata($renderer, $attributes);
216
217                return true;
218                break;
219
220            case Analytics::RENDERER_FORMAT:
221                /**
222                 *
223                 * @var renderer_plugin_combo_analytics $renderer
224                 */
225                $attributes = $data[PluginUtility::ATTRIBUTES];
226                LinkUtility::processLinkStats($attributes, $renderer->stats);
227                break;
228
229        }
230        // unsupported $mode
231        return false;
232    }
233
234
235}
236
237