xref: /plugin/combo/syntax/disqus.php (revision 04fd306c7c155fa133ebb3669986875d65988276)
1007225e5Sgerardnico<?php
2007225e5Sgerardnico
3c3437056SNickeauuse ComboStrap\DisqusIdentifier;
4*04fd306cSNickeauuse ComboStrap\ExceptionNotExists;
5007225e5Sgerardnicouse ComboStrap\LogUtility;
6*04fd306cSNickeauuse ComboStrap\Meta\Store\MetadataDokuWikiStore;
7*04fd306cSNickeauuse ComboStrap\MarkupPath;
8007225e5Sgerardnicouse ComboStrap\PluginUtility;
9007225e5Sgerardnico
10007225e5Sgerardnico
11007225e5Sgerardnico/**
12007225e5Sgerardnico * Disqus integration
13007225e5Sgerardnico * https://combostrap.com/disqus
14007225e5Sgerardnico */
15007225e5Sgerardnicoclass syntax_plugin_combo_disqus extends DokuWiki_Syntax_Plugin
16007225e5Sgerardnico{
17007225e5Sgerardnico
18007225e5Sgerardnico    const CONF_DEFAULT_ATTRIBUTES = 'disqusDefaultAttributes';
19007225e5Sgerardnico
20007225e5Sgerardnico    const ATTRIBUTE_SHORTNAME = "shortname";
21007225e5Sgerardnico    const ATTRIBUTE_IDENTIFIER = 'id';
22007225e5Sgerardnico    const ATTRIBUTE_TITLE = 'title';
23007225e5Sgerardnico    const ATTRIBUTE_URL = 'url';
24007225e5Sgerardnico
25007225e5Sgerardnico    const TAG = 'disqus';
26007225e5Sgerardnico
27007225e5Sgerardnico    const ATTRIBUTE_CATEGORY = "category";
28007225e5Sgerardnico
29007225e5Sgerardnico    /**
30007225e5Sgerardnico     * Syntax Type.
31007225e5Sgerardnico     *
32007225e5Sgerardnico     * Needs to return one of the mode types defined in $PARSER_MODES in parser.php
33007225e5Sgerardnico     * @see https://www.dokuwiki.org/devel:syntax_plugins#syntax_types
34007225e5Sgerardnico     */
35007225e5Sgerardnico    function getType()
36007225e5Sgerardnico    {
37007225e5Sgerardnico        return 'substition';
38007225e5Sgerardnico    }
39007225e5Sgerardnico
40007225e5Sgerardnico    /**
41007225e5Sgerardnico     * Syntax Type.
42007225e5Sgerardnico     *
43007225e5Sgerardnico     * Needs to return one of the mode types defined in $PARSER_MODES in parser.php
44007225e5Sgerardnico     * @see DokuWiki_Syntax_Plugin::getType()
45007225e5Sgerardnico     */
46007225e5Sgerardnico    function getPType()
47007225e5Sgerardnico    {
48007225e5Sgerardnico        return 'block';
49007225e5Sgerardnico    }
50007225e5Sgerardnico
51007225e5Sgerardnico    /**
52007225e5Sgerardnico     * Plugin priority
53007225e5Sgerardnico     *
54007225e5Sgerardnico     * @see Doku_Parser_Mode::getSort()
55007225e5Sgerardnico     *
56007225e5Sgerardnico     * the mode with the lowest sort number will win out
57007225e5Sgerardnico     */
58007225e5Sgerardnico    function getSort()
59007225e5Sgerardnico    {
60007225e5Sgerardnico        return 160;
61007225e5Sgerardnico    }
62007225e5Sgerardnico
63007225e5Sgerardnico    /**
64007225e5Sgerardnico     * Create a pattern that will called this plugin
65007225e5Sgerardnico     *
66007225e5Sgerardnico     * @param string $mode
67007225e5Sgerardnico     * @see Doku_Parser_Mode::connectTo()
68007225e5Sgerardnico     */
69007225e5Sgerardnico    function connectTo($mode)
70007225e5Sgerardnico    {
71007225e5Sgerardnico        $pattern = PluginUtility::getEmptyTagPattern(self::TAG);
729337a630SNickeau        $this->Lexer->addSpecialPattern($pattern, $mode, PluginUtility::getModeFromTag($this->getPluginComponent()));
73007225e5Sgerardnico    }
74007225e5Sgerardnico
75007225e5Sgerardnico    /**
76007225e5Sgerardnico     *
77007225e5Sgerardnico     * The handle function goal is to parse the matched syntax through the pattern function
78007225e5Sgerardnico     * and to return the result for use in the renderer
79007225e5Sgerardnico     * This result is always cached until the page is modified.
80007225e5Sgerardnico     * @param string $match
81007225e5Sgerardnico     * @param int $state
82007225e5Sgerardnico     * @param int $pos
83007225e5Sgerardnico     * @param Doku_Handler $handler
84007225e5Sgerardnico     * @return array|bool
85007225e5Sgerardnico     * @see DokuWiki_Syntax_Plugin::handle()
86007225e5Sgerardnico     *
87007225e5Sgerardnico     */
88007225e5Sgerardnico    function handle($match, $state, $pos, Doku_Handler $handler)
89007225e5Sgerardnico    {
90007225e5Sgerardnico
91007225e5Sgerardnico
92007225e5Sgerardnico        $attributes = PluginUtility::getTagAttributes($match);
93007225e5Sgerardnico        return array($attributes);
94007225e5Sgerardnico
95007225e5Sgerardnico
96007225e5Sgerardnico    }
97007225e5Sgerardnico
98007225e5Sgerardnico    /**
99007225e5Sgerardnico     * Render the output
100007225e5Sgerardnico     * @param string $format
101007225e5Sgerardnico     * @param Doku_Renderer $renderer
102007225e5Sgerardnico     * @param array $data - what the function handle() return'ed
103007225e5Sgerardnico     * @return boolean - rendered correctly? (however, returned value is not used at the moment)
104007225e5Sgerardnico     * @see DokuWiki_Syntax_Plugin::render()
105007225e5Sgerardnico     *
106007225e5Sgerardnico     */
1074cadd4f8SNickeau    function render($format, Doku_Renderer $renderer, $data): bool
108007225e5Sgerardnico    {
109007225e5Sgerardnico
110007225e5Sgerardnico        switch ($format) {
111007225e5Sgerardnico
112007225e5Sgerardnico            case 'xhtml':
113007225e5Sgerardnico
114007225e5Sgerardnico                list($attributes) = $data;
115007225e5Sgerardnico                /** @var Doku_Renderer_xhtml $renderer */
116007225e5Sgerardnico
117*04fd306cSNickeau                $page = MarkupPath::createFromRequestedPage();
118007225e5Sgerardnico
119007225e5Sgerardnico                /**
120007225e5Sgerardnico                 * Disqus configuration
121007225e5Sgerardnico                 * https://help.disqus.com/en/articles/1717084-javascript-configuration-variables
122007225e5Sgerardnico                 */
123007225e5Sgerardnico                $default = PluginUtility::getTagAttributes($this->getConf(self::CONF_DEFAULT_ATTRIBUTES));
124007225e5Sgerardnico                $attributes = PluginUtility::mergeAttributes($attributes, $default);
125007225e5Sgerardnico                $forumShortName = $attributes[self::ATTRIBUTE_SHORTNAME];
126007225e5Sgerardnico                if (empty($forumShortName)) {
127007225e5Sgerardnico                    LogUtility::msg("The disqus forum shortName should not be empty", LogUtility::LVL_MSG_ERROR, self::TAG);
128007225e5Sgerardnico                    return false;
129007225e5Sgerardnico                }
130007225e5Sgerardnico                $forumShortName = hsc($forumShortName);
131007225e5Sgerardnico
132c3437056SNickeau                /**
133c3437056SNickeau                 * @deprecated the page id is used
134c3437056SNickeau                 */
135*04fd306cSNickeau                $disqusIdentifier = MetadataDokuWikiStore::getOrCreateFromResource($page)
136*04fd306cSNickeau                    ->getFromName(DisqusIdentifier::PROPERTY_NAME);
137007225e5Sgerardnico                if (empty($disqusIdentifier)) {
138007225e5Sgerardnico
139007225e5Sgerardnico                    $disqusIdentifier = $attributes[self::ATTRIBUTE_IDENTIFIER];
140007225e5Sgerardnico                    if (empty($disqusIdentifier)) {
141*04fd306cSNickeau                        try {
142c3437056SNickeau                            $disqusIdentifier = $page->getPageId();
143*04fd306cSNickeau                        } catch (ExceptionNotExists $e) {
144*04fd306cSNickeau                            // the page does not exists
145c3437056SNickeau                            return false;
146c3437056SNickeau                        }
147007225e5Sgerardnico                    }
148007225e5Sgerardnico
149007225e5Sgerardnico                }
150007225e5Sgerardnico                $disqusConfig = "this.page.identifier = \"$disqusIdentifier\";";
151007225e5Sgerardnico
152007225e5Sgerardnico                $url = $attributes[self::ATTRIBUTE_URL];
153007225e5Sgerardnico                if (empty($url)) {
154c3437056SNickeau                    $url = $page->getCanonicalUrl();
155007225e5Sgerardnico                }
156007225e5Sgerardnico                $disqusConfig .= "this.page.url = $url;";
1575f891b7eSNickeau
158007225e5Sgerardnico
159007225e5Sgerardnico                $title = $attributes[self::ATTRIBUTE_TITLE];
160007225e5Sgerardnico                if (empty($title)) {
161*04fd306cSNickeau                    $title = action_plugin_combo_metatitle::getHtmlTitle();
162007225e5Sgerardnico                    if (!empty($title)) {
163007225e5Sgerardnico                        $disqusConfig .= "this.page.title = $title;";
164007225e5Sgerardnico                    }
165007225e5Sgerardnico                }
166007225e5Sgerardnico
167007225e5Sgerardnico                $category = $attributes[self::ATTRIBUTE_CATEGORY];
168007225e5Sgerardnico                if (empty($category)) {
169007225e5Sgerardnico                    $disqusConfig .= "this.page.category_id = $category;";
170007225e5Sgerardnico                }
171007225e5Sgerardnico
172007225e5Sgerardnico
173007225e5Sgerardnico                /**
174007225e5Sgerardnico                 * The javascript
175007225e5Sgerardnico                 */
176007225e5Sgerardnico                $renderer->doc .= <<<EOD
177007225e5Sgerardnico<script charset="utf-8" type="text/javascript">
178007225e5Sgerardnico
179007225e5Sgerardnico    // Configuration
180007225e5Sgerardnico
181007225e5Sgerardnico    // The disqus_config should be a var to give it the global scope
182007225e5Sgerardnico    // Otherwise, disqus will see no config
183007225e5Sgerardnico    // noinspection ES6ConvertVarToLetConst
184007225e5Sgerardnico    var disqus_config = function () {
185007225e5Sgerardnico        $disqusConfig
186007225e5Sgerardnico    };
187007225e5Sgerardnico
188007225e5Sgerardnico    // Embed the library
189007225e5Sgerardnico    (function() {
190007225e5Sgerardnico        const d = document, s = d.createElement('script');
191007225e5Sgerardnico        s.src = 'https://$forumShortName.disqus.com/embed.js';
192007225e5Sgerardnico        s.setAttribute('data-timestamp', (+new Date()).toString());
193007225e5Sgerardnico        (d.head || d.body).appendChild(s);
194007225e5Sgerardnico    })();
195007225e5Sgerardnico
196007225e5Sgerardnico</script>
197007225e5Sgerardnico<noscript><a href="https://disqus.com/home/discussion/$forumShortName/$disqusIdentifier/">View the discussion thread.</a></noscript>
198007225e5SgerardnicoEOD;
199007225e5Sgerardnico                // The tag
200007225e5Sgerardnico                $renderer->doc .= '<div id="disqus_thread"></div>';
201007225e5Sgerardnico
202007225e5Sgerardnico                return true;
203*04fd306cSNickeau
204007225e5Sgerardnico            case 'metadata':
205007225e5Sgerardnico
206007225e5Sgerardnico        }
207007225e5Sgerardnico        return false;
208007225e5Sgerardnico
209007225e5Sgerardnico    }
210007225e5Sgerardnico
211007225e5Sgerardnico
212007225e5Sgerardnico}
213007225e5Sgerardnico
214