xref: /plugin/combo/syntax/disqus.php (revision 007225e5fb2d3f64edaccd3bd447ca26effb9d68)
1*007225e5Sgerardnico<?php
2*007225e5Sgerardnico
3*007225e5Sgerardnicouse ComboStrap\LogUtility;
4*007225e5Sgerardnicouse ComboStrap\MetadataUtility;
5*007225e5Sgerardnicouse ComboStrap\PluginUtility;
6*007225e5Sgerardnicouse ComboStrap\UrlCanonical;
7*007225e5Sgerardnico
8*007225e5Sgerardnicorequire_once(__DIR__ . '/../class/PluginUtility.php');
9*007225e5Sgerardnico
10*007225e5Sgerardnico/**
11*007225e5Sgerardnico * Disqus integration
12*007225e5Sgerardnico * https://combostrap.com/disqus
13*007225e5Sgerardnico */
14*007225e5Sgerardnicoclass syntax_plugin_combo_disqus extends DokuWiki_Syntax_Plugin
15*007225e5Sgerardnico{
16*007225e5Sgerardnico
17*007225e5Sgerardnico    const CONF_DEFAULT_ATTRIBUTES = 'disqusDefaultAttributes';
18*007225e5Sgerardnico
19*007225e5Sgerardnico    const ATTRIBUTE_SHORTNAME = "shortname";
20*007225e5Sgerardnico    const ATTRIBUTE_IDENTIFIER = 'id';
21*007225e5Sgerardnico    const ATTRIBUTE_TITLE = 'title';
22*007225e5Sgerardnico    const ATTRIBUTE_URL = 'url';
23*007225e5Sgerardnico
24*007225e5Sgerardnico    const TAG = 'disqus';
25*007225e5Sgerardnico
26*007225e5Sgerardnico    const META_DISQUS_IDENTIFIER = "disqus_identifier";
27*007225e5Sgerardnico    const ATTRIBUTE_CATEGORY = "category";
28*007225e5Sgerardnico
29*007225e5Sgerardnico    /**
30*007225e5Sgerardnico     * Syntax Type.
31*007225e5Sgerardnico     *
32*007225e5Sgerardnico     * Needs to return one of the mode types defined in $PARSER_MODES in parser.php
33*007225e5Sgerardnico     * @see https://www.dokuwiki.org/devel:syntax_plugins#syntax_types
34*007225e5Sgerardnico     */
35*007225e5Sgerardnico    function getType()
36*007225e5Sgerardnico    {
37*007225e5Sgerardnico        return 'substition';
38*007225e5Sgerardnico    }
39*007225e5Sgerardnico
40*007225e5Sgerardnico    /**
41*007225e5Sgerardnico     * Syntax Type.
42*007225e5Sgerardnico     *
43*007225e5Sgerardnico     * Needs to return one of the mode types defined in $PARSER_MODES in parser.php
44*007225e5Sgerardnico     * @see DokuWiki_Syntax_Plugin::getType()
45*007225e5Sgerardnico     */
46*007225e5Sgerardnico    function getPType()
47*007225e5Sgerardnico    {
48*007225e5Sgerardnico        return 'block';
49*007225e5Sgerardnico    }
50*007225e5Sgerardnico
51*007225e5Sgerardnico    /**
52*007225e5Sgerardnico     * Plugin priority
53*007225e5Sgerardnico     *
54*007225e5Sgerardnico     * @see Doku_Parser_Mode::getSort()
55*007225e5Sgerardnico     *
56*007225e5Sgerardnico     * the mode with the lowest sort number will win out
57*007225e5Sgerardnico     */
58*007225e5Sgerardnico    function getSort()
59*007225e5Sgerardnico    {
60*007225e5Sgerardnico        return 160;
61*007225e5Sgerardnico    }
62*007225e5Sgerardnico
63*007225e5Sgerardnico    /**
64*007225e5Sgerardnico     * Create a pattern that will called this plugin
65*007225e5Sgerardnico     *
66*007225e5Sgerardnico     * @param string $mode
67*007225e5Sgerardnico     * @see Doku_Parser_Mode::connectTo()
68*007225e5Sgerardnico     */
69*007225e5Sgerardnico    function connectTo($mode)
70*007225e5Sgerardnico    {
71*007225e5Sgerardnico        $pattern = PluginUtility::getEmptyTagPattern(self::TAG);
72*007225e5Sgerardnico        $this->Lexer->addSpecialPattern($pattern, $mode, PluginUtility::getModeForComponent($this->getPluginComponent()));
73*007225e5Sgerardnico    }
74*007225e5Sgerardnico
75*007225e5Sgerardnico    /**
76*007225e5Sgerardnico     *
77*007225e5Sgerardnico     * The handle function goal is to parse the matched syntax through the pattern function
78*007225e5Sgerardnico     * and to return the result for use in the renderer
79*007225e5Sgerardnico     * This result is always cached until the page is modified.
80*007225e5Sgerardnico     * @param string $match
81*007225e5Sgerardnico     * @param int $state
82*007225e5Sgerardnico     * @param int $pos
83*007225e5Sgerardnico     * @param Doku_Handler $handler
84*007225e5Sgerardnico     * @return array|bool
85*007225e5Sgerardnico     * @see DokuWiki_Syntax_Plugin::handle()
86*007225e5Sgerardnico     *
87*007225e5Sgerardnico     */
88*007225e5Sgerardnico    function handle($match, $state, $pos, Doku_Handler $handler)
89*007225e5Sgerardnico    {
90*007225e5Sgerardnico
91*007225e5Sgerardnico
92*007225e5Sgerardnico        $attributes = PluginUtility::getTagAttributes($match);
93*007225e5Sgerardnico        return array($attributes);
94*007225e5Sgerardnico
95*007225e5Sgerardnico
96*007225e5Sgerardnico    }
97*007225e5Sgerardnico
98*007225e5Sgerardnico    /**
99*007225e5Sgerardnico     * Render the output
100*007225e5Sgerardnico     * @param string $format
101*007225e5Sgerardnico     * @param Doku_Renderer $renderer
102*007225e5Sgerardnico     * @param array $data - what the function handle() return'ed
103*007225e5Sgerardnico     * @return boolean - rendered correctly? (however, returned value is not used at the moment)
104*007225e5Sgerardnico     * @see DokuWiki_Syntax_Plugin::render()
105*007225e5Sgerardnico     *
106*007225e5Sgerardnico     */
107*007225e5Sgerardnico    function render($format, Doku_Renderer $renderer, $data)
108*007225e5Sgerardnico    {
109*007225e5Sgerardnico
110*007225e5Sgerardnico        switch ($format) {
111*007225e5Sgerardnico
112*007225e5Sgerardnico            case 'xhtml':
113*007225e5Sgerardnico
114*007225e5Sgerardnico                list($attributes) = $data;
115*007225e5Sgerardnico                /** @var Doku_Renderer_xhtml $renderer */
116*007225e5Sgerardnico
117*007225e5Sgerardnico
118*007225e5Sgerardnico                /**
119*007225e5Sgerardnico                 * Disqus configuration
120*007225e5Sgerardnico                 * https://help.disqus.com/en/articles/1717084-javascript-configuration-variables
121*007225e5Sgerardnico                 */
122*007225e5Sgerardnico                $default = PluginUtility::getTagAttributes($this->getConf(self::CONF_DEFAULT_ATTRIBUTES));
123*007225e5Sgerardnico                $attributes = PluginUtility::mergeAttributes($attributes, $default);
124*007225e5Sgerardnico                $forumShortName = $attributes[self::ATTRIBUTE_SHORTNAME];
125*007225e5Sgerardnico                if (empty($forumShortName)) {
126*007225e5Sgerardnico                    LogUtility::msg("The disqus forum shortName should not be empty", LogUtility::LVL_MSG_ERROR, self::TAG);
127*007225e5Sgerardnico                    return false;
128*007225e5Sgerardnico                }
129*007225e5Sgerardnico                $forumShortName = hsc($forumShortName);
130*007225e5Sgerardnico
131*007225e5Sgerardnico                $disqusIdentifier = MetadataUtility::getMeta(self::META_DISQUS_IDENTIFIER);
132*007225e5Sgerardnico                if (empty($disqusIdentifier)) {
133*007225e5Sgerardnico
134*007225e5Sgerardnico                    $disqusIdentifier = $attributes[self::ATTRIBUTE_IDENTIFIER];
135*007225e5Sgerardnico                    if (empty($disqusIdentifier)) {
136*007225e5Sgerardnico                        $disqusIdentifier = PluginUtility::getPageId();
137*007225e5Sgerardnico                    }
138*007225e5Sgerardnico
139*007225e5Sgerardnico                    $canonical = MetadataUtility::getMeta(UrlCanonical::CANONICAL_PROPERTY);
140*007225e5Sgerardnico                    if (!empty($canonical)) {
141*007225e5Sgerardnico                        $disqusIdentifier = $canonical;
142*007225e5Sgerardnico                    }
143*007225e5Sgerardnico                    MetadataUtility::setMeta(self::META_DISQUS_IDENTIFIER, $disqusIdentifier);
144*007225e5Sgerardnico                }
145*007225e5Sgerardnico                $disqusConfig = "this.page.identifier = \"$disqusIdentifier\";";
146*007225e5Sgerardnico
147*007225e5Sgerardnico                $url = $attributes[self::ATTRIBUTE_URL];
148*007225e5Sgerardnico                if (empty($url)) {
149*007225e5Sgerardnico                    if (!empty($canonical)) {
150*007225e5Sgerardnico                        $url = UrlCanonical::getUrl($canonical);
151*007225e5Sgerardnico                    }
152*007225e5Sgerardnico                }
153*007225e5Sgerardnico
154*007225e5Sgerardnico                if (!empty($url)) {
155*007225e5Sgerardnico                    $disqusConfig .= "this.page.url = $url;";
156*007225e5Sgerardnico                }
157*007225e5Sgerardnico
158*007225e5Sgerardnico                $title = $attributes[self::ATTRIBUTE_TITLE];
159*007225e5Sgerardnico                if (empty($title)) {
160*007225e5Sgerardnico                    $title = action_plugin_combo_metatitle::getTitle();
161*007225e5Sgerardnico                    if (!empty($title)){
162*007225e5Sgerardnico                        $disqusConfig .= "this.page.title = $title;";
163*007225e5Sgerardnico                    }
164*007225e5Sgerardnico                }
165*007225e5Sgerardnico
166*007225e5Sgerardnico                $category = $attributes[self::ATTRIBUTE_CATEGORY];
167*007225e5Sgerardnico                if (empty($category)){
168*007225e5Sgerardnico                    $disqusConfig .= "this.page.category_id = $category;";
169*007225e5Sgerardnico                }
170*007225e5Sgerardnico
171*007225e5Sgerardnico
172*007225e5Sgerardnico                /**
173*007225e5Sgerardnico                 * The javascript
174*007225e5Sgerardnico                 */
175*007225e5Sgerardnico                $renderer->doc .= <<<EOD
176*007225e5Sgerardnico<script charset="utf-8" type="text/javascript">
177*007225e5Sgerardnico
178*007225e5Sgerardnico    // Configuration
179*007225e5Sgerardnico
180*007225e5Sgerardnico    // The disqus_config should be a var to give it the global scope
181*007225e5Sgerardnico    // Otherwise, disqus will see no config
182*007225e5Sgerardnico    // noinspection ES6ConvertVarToLetConst
183*007225e5Sgerardnico    var disqus_config = function () {
184*007225e5Sgerardnico        $disqusConfig
185*007225e5Sgerardnico    };
186*007225e5Sgerardnico
187*007225e5Sgerardnico    // Embed the library
188*007225e5Sgerardnico    (function() {
189*007225e5Sgerardnico        const d = document, s = d.createElement('script');
190*007225e5Sgerardnico        s.src = 'https://$forumShortName.disqus.com/embed.js';
191*007225e5Sgerardnico        s.setAttribute('data-timestamp', (+new Date()).toString());
192*007225e5Sgerardnico        (d.head || d.body).appendChild(s);
193*007225e5Sgerardnico    })();
194*007225e5Sgerardnico
195*007225e5Sgerardnico</script>
196*007225e5Sgerardnico<noscript><a href="https://disqus.com/home/discussion/$forumShortName/$disqusIdentifier/">View the discussion thread.</a></noscript>
197*007225e5SgerardnicoEOD;
198*007225e5Sgerardnico                // The tag
199*007225e5Sgerardnico                $renderer->doc .= '<div id="disqus_thread"></div>';
200*007225e5Sgerardnico
201*007225e5Sgerardnico                return true;
202*007225e5Sgerardnico                break;
203*007225e5Sgerardnico            case 'metadata':
204*007225e5Sgerardnico
205*007225e5Sgerardnico        }
206*007225e5Sgerardnico        return false;
207*007225e5Sgerardnico
208*007225e5Sgerardnico    }
209*007225e5Sgerardnico
210*007225e5Sgerardnico
211*007225e5Sgerardnico}
212*007225e5Sgerardnico
213