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