xref: /plugin/combo/syntax/disqus.php (revision 9337a630db122fdba0294f47d72bdf5433c2bf10)
1007225e5Sgerardnico<?php
2007225e5Sgerardnico
3007225e5Sgerardnicouse ComboStrap\LogUtility;
4007225e5Sgerardnicouse ComboStrap\MetadataUtility;
5007225e5Sgerardnicouse ComboStrap\PluginUtility;
671f916b9Sgerardnicouse ComboStrap\Page;
7007225e5Sgerardnico
8007225e5Sgerardnicorequire_once(__DIR__ . '/../class/PluginUtility.php');
9007225e5Sgerardnico
10007225e5Sgerardnico/**
11007225e5Sgerardnico * Disqus integration
12007225e5Sgerardnico * https://combostrap.com/disqus
13007225e5Sgerardnico */
14007225e5Sgerardnicoclass syntax_plugin_combo_disqus extends DokuWiki_Syntax_Plugin
15007225e5Sgerardnico{
16007225e5Sgerardnico
17007225e5Sgerardnico    const CONF_DEFAULT_ATTRIBUTES = 'disqusDefaultAttributes';
18007225e5Sgerardnico
19007225e5Sgerardnico    const ATTRIBUTE_SHORTNAME = "shortname";
20007225e5Sgerardnico    const ATTRIBUTE_IDENTIFIER = 'id';
21007225e5Sgerardnico    const ATTRIBUTE_TITLE = 'title';
22007225e5Sgerardnico    const ATTRIBUTE_URL = 'url';
23007225e5Sgerardnico
24007225e5Sgerardnico    const TAG = 'disqus';
25007225e5Sgerardnico
26007225e5Sgerardnico    const META_DISQUS_IDENTIFIER = "disqus_identifier";
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);
72*9337a630SNickeau        $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     */
107007225e5Sgerardnico    function render($format, Doku_Renderer $renderer, $data)
108007225e5Sgerardnico    {
109007225e5Sgerardnico
110007225e5Sgerardnico        switch ($format) {
111007225e5Sgerardnico
112007225e5Sgerardnico            case 'xhtml':
113007225e5Sgerardnico
114007225e5Sgerardnico                list($attributes) = $data;
115007225e5Sgerardnico                /** @var Doku_Renderer_xhtml $renderer */
116007225e5Sgerardnico
117*9337a630SNickeau                $page = Page::createRequestedPageFromEnvironment();
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
132007225e5Sgerardnico                $disqusIdentifier = MetadataUtility::getMeta(self::META_DISQUS_IDENTIFIER);
133007225e5Sgerardnico                if (empty($disqusIdentifier)) {
134007225e5Sgerardnico
135007225e5Sgerardnico                    $disqusIdentifier = $attributes[self::ATTRIBUTE_IDENTIFIER];
136007225e5Sgerardnico                    if (empty($disqusIdentifier)) {
1375f891b7eSNickeau                        $disqusIdentifier = $page->getId();
138007225e5Sgerardnico                    }
139007225e5Sgerardnico
1405f891b7eSNickeau                    $canonical = $page->getCanonical();
141007225e5Sgerardnico                    if (!empty($canonical)) {
142007225e5Sgerardnico                        $disqusIdentifier = $canonical;
143007225e5Sgerardnico                    }
144007225e5Sgerardnico                    MetadataUtility::setMeta(self::META_DISQUS_IDENTIFIER, $disqusIdentifier);
145007225e5Sgerardnico                }
146007225e5Sgerardnico                $disqusConfig = "this.page.identifier = \"$disqusIdentifier\";";
147007225e5Sgerardnico
148007225e5Sgerardnico                $url = $attributes[self::ATTRIBUTE_URL];
149007225e5Sgerardnico                if (empty($url)) {
1505f891b7eSNickeau                    $url = $page->getCanonicalUrlOrDefault();
151007225e5Sgerardnico                }
152007225e5Sgerardnico                $disqusConfig .= "this.page.url = $url;";
1535f891b7eSNickeau
154007225e5Sgerardnico
155007225e5Sgerardnico                $title = $attributes[self::ATTRIBUTE_TITLE];
156007225e5Sgerardnico                if (empty($title)) {
157007225e5Sgerardnico                    $title = action_plugin_combo_metatitle::getTitle();
158007225e5Sgerardnico                    if (!empty($title)) {
159007225e5Sgerardnico                        $disqusConfig .= "this.page.title = $title;";
160007225e5Sgerardnico                    }
161007225e5Sgerardnico                }
162007225e5Sgerardnico
163007225e5Sgerardnico                $category = $attributes[self::ATTRIBUTE_CATEGORY];
164007225e5Sgerardnico                if (empty($category)) {
165007225e5Sgerardnico                    $disqusConfig .= "this.page.category_id = $category;";
166007225e5Sgerardnico                }
167007225e5Sgerardnico
168007225e5Sgerardnico
169007225e5Sgerardnico                /**
170007225e5Sgerardnico                 * The javascript
171007225e5Sgerardnico                 */
172007225e5Sgerardnico                $renderer->doc .= <<<EOD
173007225e5Sgerardnico<script charset="utf-8" type="text/javascript">
174007225e5Sgerardnico
175007225e5Sgerardnico    // Configuration
176007225e5Sgerardnico
177007225e5Sgerardnico    // The disqus_config should be a var to give it the global scope
178007225e5Sgerardnico    // Otherwise, disqus will see no config
179007225e5Sgerardnico    // noinspection ES6ConvertVarToLetConst
180007225e5Sgerardnico    var disqus_config = function () {
181007225e5Sgerardnico        $disqusConfig
182007225e5Sgerardnico    };
183007225e5Sgerardnico
184007225e5Sgerardnico    // Embed the library
185007225e5Sgerardnico    (function() {
186007225e5Sgerardnico        const d = document, s = d.createElement('script');
187007225e5Sgerardnico        s.src = 'https://$forumShortName.disqus.com/embed.js';
188007225e5Sgerardnico        s.setAttribute('data-timestamp', (+new Date()).toString());
189007225e5Sgerardnico        (d.head || d.body).appendChild(s);
190007225e5Sgerardnico    })();
191007225e5Sgerardnico
192007225e5Sgerardnico</script>
193007225e5Sgerardnico<noscript><a href="https://disqus.com/home/discussion/$forumShortName/$disqusIdentifier/">View the discussion thread.</a></noscript>
194007225e5SgerardnicoEOD;
195007225e5Sgerardnico                // The tag
196007225e5Sgerardnico                $renderer->doc .= '<div id="disqus_thread"></div>';
197007225e5Sgerardnico
198007225e5Sgerardnico                return true;
199007225e5Sgerardnico                break;
200007225e5Sgerardnico            case 'metadata':
201007225e5Sgerardnico
202007225e5Sgerardnico        }
203007225e5Sgerardnico        return false;
204007225e5Sgerardnico
205007225e5Sgerardnico    }
206007225e5Sgerardnico
207007225e5Sgerardnico
208007225e5Sgerardnico}
209007225e5Sgerardnico
210