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