xref: /plugin/discussion/syntax/threads.php (revision dfc5d08b5eea7cef6dcb63789032dcac586bcb87)
1f0fda08aSwikidesign<?php
2f0fda08aSwikidesign/**
3f0fda08aSwikidesign * Discussion Plugin, threads component: displays a list of recently active discussions
4f0fda08aSwikidesign *
5f0fda08aSwikidesign * @license  GPL 2 (http://www.gnu.org/licenses/gpl.html)
6f0fda08aSwikidesign * @author   Esther Brunner <wikidesign@gmail.com>
7f0fda08aSwikidesign */
8f0fda08aSwikidesign
9e7ac9adaSGerrit Uitslag/**
10e7ac9adaSGerrit Uitslag * Class syntax_plugin_discussion_threads
11e7ac9adaSGerrit Uitslag */
12*dfc5d08bSGerrit Uitslagclass syntax_plugin_discussion_threads extends DokuWiki_Syntax_Plugin
13*dfc5d08bSGerrit Uitslag{
14f0fda08aSwikidesign
15e7ac9adaSGerrit Uitslag    /**
16e7ac9adaSGerrit Uitslag     * Syntax Type
17e7ac9adaSGerrit Uitslag     *
18e7ac9adaSGerrit Uitslag     * @return string
19e7ac9adaSGerrit Uitslag     */
20*dfc5d08bSGerrit Uitslag    public function getType()
21*dfc5d08bSGerrit Uitslag    {
22*dfc5d08bSGerrit Uitslag        return 'substition';
23*dfc5d08bSGerrit Uitslag    }
24e7ac9adaSGerrit Uitslag
25e7ac9adaSGerrit Uitslag    /**
26e7ac9adaSGerrit Uitslag     * Paragraph Type
27e7ac9adaSGerrit Uitslag     *
28e7ac9adaSGerrit Uitslag     * @return string
29*dfc5d08bSGerrit Uitslag     * @see Doku_Handler_Block
30e7ac9adaSGerrit Uitslag     */
31*dfc5d08bSGerrit Uitslag    public function getPType()
32*dfc5d08bSGerrit Uitslag    {
33*dfc5d08bSGerrit Uitslag        return 'block';
34*dfc5d08bSGerrit Uitslag    }
35e7ac9adaSGerrit Uitslag
36e7ac9adaSGerrit Uitslag    /**
37e7ac9adaSGerrit Uitslag     * Sort for applying this mode
38e7ac9adaSGerrit Uitslag     *
39e7ac9adaSGerrit Uitslag     * @return int
40e7ac9adaSGerrit Uitslag     */
41*dfc5d08bSGerrit Uitslag    public function getSort()
42*dfc5d08bSGerrit Uitslag    {
43*dfc5d08bSGerrit Uitslag        return 306;
44*dfc5d08bSGerrit Uitslag    }
455fc512fbSwikidesign
46e7ac9adaSGerrit Uitslag    /**
47e7ac9adaSGerrit Uitslag     * @param string $mode
48e7ac9adaSGerrit Uitslag     */
49*dfc5d08bSGerrit Uitslag    public function connectTo($mode)
50*dfc5d08bSGerrit Uitslag    {
515fc512fbSwikidesign        $this->Lexer->addSpecialPattern('\{\{threads>.+?\}\}', $mode, 'plugin_discussion_threads');
525fc512fbSwikidesign    }
53f0fda08aSwikidesign
54e7ac9adaSGerrit Uitslag    /**
55e7ac9adaSGerrit Uitslag     * Handler to prepare matched data for the rendering process
56e7ac9adaSGerrit Uitslag     *
57e7ac9adaSGerrit Uitslag     * @param string $match The text matched by the patterns
58e7ac9adaSGerrit Uitslag     * @param int $state The lexer state for the match
59e7ac9adaSGerrit Uitslag     * @param int $pos The character position of the matched text
60e7ac9adaSGerrit Uitslag     * @param Doku_Handler $handler The Doku_Handler object
61e7ac9adaSGerrit Uitslag     * @return  array Return an array with all data you want to use in render
62e7ac9adaSGerrit Uitslag     */
63*dfc5d08bSGerrit Uitslag    public function handle($match, $state, $pos, Doku_Handler $handler)
64*dfc5d08bSGerrit Uitslag    {
65f0fda08aSwikidesign        global $ID;
665644a1afSlupo49        $customFlags = array();
67f5b180ccSwikidesign
680e0effa1Swikidesign        $match = substr($match, 10, -2); // strip {{threads> from start and }} from end
6964829c37SGerrit Uitslag        list($match, $flags) = array_pad(explode('&', $match, 2), 2, '');
700e0effa1Swikidesign        $flags = explode('&', $flags);
71912b9053Slupo49
725644a1afSlupo49        // Identify the count/skipempty flag and remove it before passing it to pagelist
73912b9053Slupo49        foreach ($flags as $key => $flag) {
74912b9053Slupo49            if (substr($flag, 0, 5) == "count") {
7564829c37SGerrit Uitslag                $tmp = array_pad(explode('=', $flag, 2), 2, 0);
765644a1afSlupo49                $customFlags['count'] = $tmp[1];
77912b9053Slupo49                unset($flags[$key]);
78c2a7577fSLarsGit223            } elseif (substr($flag, 0, 9) == "skipempty") {
795644a1afSlupo49                $customFlags['skipempty'] = true;
805644a1afSlupo49                unset($flags[$key]);
81c2a7577fSLarsGit223            } elseif (substr($flag, 0, 15) == "nonewthreadform") {
82c2a7577fSLarsGit223                $customFlags['nonewthreadform'] = true;
83c2a7577fSLarsGit223                unset($flags[$key]);
84912b9053Slupo49            }
85912b9053Slupo49        }
86912b9053Slupo49
875644a1afSlupo49        // Ignore params if invalid values have been passed
8864829c37SGerrit Uitslag        if (!array_key_exists('count', $customFlags) || $customFlags['count'] <= 0 || !is_numeric($customFlags['count'])) {
8964829c37SGerrit Uitslag            $customFlags['count'] = 0;
9064829c37SGerrit Uitslag        }
9164829c37SGerrit Uitslag        if (!array_key_exists('skipempty', $customFlags) && !$customFlags['skipempty']) {
9264829c37SGerrit Uitslag            $customFlags['skipempty'] = false;
9364829c37SGerrit Uitslag        }
94912b9053Slupo49
9564829c37SGerrit Uitslag        list($ns, $refine) = array_pad(explode(' ', $match, 2), 2, '');
96f0fda08aSwikidesign
9764829c37SGerrit Uitslag        if ($ns == '*' || $ns == ':') {
9864829c37SGerrit Uitslag            $ns = '';
9964829c37SGerrit Uitslag        } elseif ($ns == '.') {
10064829c37SGerrit Uitslag            $ns = getNS($ID);
10164829c37SGerrit Uitslag        } else {
10264829c37SGerrit Uitslag            $ns = cleanID($ns);
10364829c37SGerrit Uitslag        }
104f0fda08aSwikidesign
10564829c37SGerrit Uitslag        return [$ns, $flags, $refine, $customFlags];
106f5b180ccSwikidesign    }
107f5b180ccSwikidesign
108e7ac9adaSGerrit Uitslag    /**
109e7ac9adaSGerrit Uitslag     * Handles the actual output creation.
110e7ac9adaSGerrit Uitslag     *
11164829c37SGerrit Uitslag     * @param string $format output format being rendered
11264829c37SGerrit Uitslag     * @param Doku_Renderer $renderer the current renderer object
11364829c37SGerrit Uitslag     * @param array $data data created by handler()
114e7ac9adaSGerrit Uitslag     * @return boolean rendered correctly?
115e7ac9adaSGerrit Uitslag     */
116*dfc5d08bSGerrit Uitslag    public function render($format, Doku_Renderer $renderer, $data)
117*dfc5d08bSGerrit Uitslag    {
1185644a1afSlupo49        list($ns, $flags, $refine, $customFlags) = $data;
1195644a1afSlupo49        $count = $customFlags['count'];
1205644a1afSlupo49        $skipEmpty = $customFlags['skipempty'];
121c2a7577fSLarsGit223        $noNewThreadForm = $customFlags['nonewthreadform'];
122912b9053Slupo49        $i = 0;
1230e0effa1Swikidesign
12464829c37SGerrit Uitslag        $pages = [];
12564829c37SGerrit Uitslag        /** @var helper_plugin_discussion $helper */
12664829c37SGerrit Uitslag        if ($helper = $this->loadHelper('discussion')) {
12764829c37SGerrit Uitslag            $pages = $helper->getThreads($ns, null, $skipEmpty);
12864829c37SGerrit Uitslag        }
129e2c227dfSwikidesign
130e2c227dfSwikidesign        // use tag refinements?
131e2c227dfSwikidesign        if ($refine) {
132e7ac9adaSGerrit Uitslag            /** @var helper_plugin_tag $tag */
13364829c37SGerrit Uitslag            if (!$tag = $this->loadHelper('tag', false)) {
134e2c227dfSwikidesign                msg('The Tag Plugin must be installed to use tag refinements.', -1);
135e2c227dfSwikidesign            } else {
136e2c227dfSwikidesign                $pages = $tag->tagRefine($pages, $refine);
137e2c227dfSwikidesign            }
138e2c227dfSwikidesign        }
139e2c227dfSwikidesign
14081cc6d2cSwikidesign        if (!$pages) {
14164829c37SGerrit Uitslag            if (auth_quickaclcheck($ns . ':*') >= AUTH_CREATE && $format == 'xhtml') {
142c2e2c575Slpaulsen93                $renderer->nocache();
143c2a7577fSLarsGit223                if ($noNewThreadForm !== true) {
14464829c37SGerrit Uitslag                    $renderer->doc .= $this->newThreadForm($ns);
14577f39d56Swikidesign                }
146c2a7577fSLarsGit223            }
14781cc6d2cSwikidesign            return true; // nothing to display
14881cc6d2cSwikidesign        }
149f0fda08aSwikidesign
15064829c37SGerrit Uitslag        if ($format == 'xhtml') {
15164829c37SGerrit Uitslag            /** @var Doku_Renderer_xhtml $renderer */
152f0fda08aSwikidesign            // prevent caching to ensure content is always fresh
153c2e2c575Slpaulsen93            $renderer->nocache();
154f0fda08aSwikidesign
155cc497149Swikidesign            // show form to start a new discussion thread?
156c2a7577fSLarsGit223            if ($noNewThreadForm !== true) {
15764829c37SGerrit Uitslag                $hasCreatePermission = auth_quickaclcheck($ns . ':*') >= AUTH_CREATE;
15864829c37SGerrit Uitslag                if ($hasCreatePermission && $this->getConf('threads_formposition') == 'top') {
15964829c37SGerrit Uitslag                    $renderer->doc .= $this->newThreadForm($ns);
160c2a7577fSLarsGit223                }
161c2a7577fSLarsGit223            }
162cc497149Swikidesign
1635fc512fbSwikidesign            // let Pagelist Plugin do the work for us
16464829c37SGerrit Uitslag            /** @var helper_plugin_pagelist $pagelist */
16564829c37SGerrit Uitslag            if (!$pagelist = $this->loadHelper('pagelist', false)) {
1665fc512fbSwikidesign                msg('The Pagelist Plugin must be installed for threads lists to work.', -1);
1675fc512fbSwikidesign                return false;
1685fc512fbSwikidesign            }
16964829c37SGerrit Uitslag            $pagelist->addColumn('discussion', 'comments');
1700e0effa1Swikidesign            $pagelist->setFlags($flags);
1715fc512fbSwikidesign            $pagelist->startList();
172e7ac9adaSGerrit Uitslag            foreach ($pages as $page) {
173c5b0470aSMichael Klier                $page['class'] = 'discussion_status' . $page['status'];
1745fc512fbSwikidesign                $pagelist->addPage($page);
175912b9053Slupo49
176912b9053Slupo49                $i++;
17764829c37SGerrit Uitslag                if ($count > 0 && $i >= $count) {
17864829c37SGerrit Uitslag                    // Only display the n discussion threads specified by the count flag
17964829c37SGerrit Uitslag                    break;
18064829c37SGerrit Uitslag                }
1817a292a0dSwikidesign            }
1825fc512fbSwikidesign            $renderer->doc .= $pagelist->finishList();
183f0fda08aSwikidesign
184f0fda08aSwikidesign            // show form to start a new discussion thread?
185c2a7577fSLarsGit223            if ($noNewThreadForm !== true) {
18664829c37SGerrit Uitslag                if ($hasCreatePermission && $this->getConf('threads_formposition') == 'bottom') {
18764829c37SGerrit Uitslag                    $renderer->doc .= $this->newThreadForm($ns);
188c2a7577fSLarsGit223                }
189c2a7577fSLarsGit223            }
190f0fda08aSwikidesign
191f0fda08aSwikidesign            return true;
192f0fda08aSwikidesign
193f0fda08aSwikidesign            // for metadata renderer
19464829c37SGerrit Uitslag        } elseif ($format == 'metadata') {
19564829c37SGerrit Uitslag            /** @var Doku_Renderer_metadata $renderer */
196f0fda08aSwikidesign            foreach ($pages as $page) {
1975fc512fbSwikidesign                $renderer->meta['relation']['references'][$page['id']] = true;
198f0fda08aSwikidesign            }
199f0fda08aSwikidesign
200f0fda08aSwikidesign            return true;
201f0fda08aSwikidesign        }
202f0fda08aSwikidesign        return false;
203f0fda08aSwikidesign    }
204f0fda08aSwikidesign
2055fc512fbSwikidesign    /* ---------- (X)HTML Output Functions ---------- */
206f0fda08aSwikidesign
207f0fda08aSwikidesign    /**
208f0fda08aSwikidesign     * Show the form to start a new discussion thread
209e7ac9adaSGerrit Uitslag     *
210e7ac9adaSGerrit Uitslag     * @param string $ns
21164829c37SGerrit Uitslag     * @return string html
212f0fda08aSwikidesign     */
213*dfc5d08bSGerrit Uitslag    protected function newThreadForm($ns)
214*dfc5d08bSGerrit Uitslag    {
215f0fda08aSwikidesign        global $ID;
216f0fda08aSwikidesign        global $lang;
217f0fda08aSwikidesign
21864829c37SGerrit Uitslag        return '<div class="newthread_form">'
21964829c37SGerrit Uitslag                . '<form id="discussion__newthread_form"  method="post" action="' . script() . '" accept-charset="' . $lang['encoding'] . '">'
22064829c37SGerrit Uitslag                    . '<fieldset>'
22164829c37SGerrit Uitslag                        . '<legend> ' . $this->getLang('newthread') . ': </legend>'
22264829c37SGerrit Uitslag                        . '<input type="hidden" name="id" value="' . $ID . '" />'
22364829c37SGerrit Uitslag                        . '<input type="hidden" name="do" value="newthread" />'
22464829c37SGerrit Uitslag                        . '<input type="hidden" name="ns" value="' . $ns . '" />'
22564829c37SGerrit Uitslag                        . '<input class="edit" type="text" name="title" id="discussion__newthread_title" size="40" tabindex="1" />'
22664829c37SGerrit Uitslag                        . '<input class="button" type="submit" value="' . $lang['btn_create'] . '" tabindex="2" />'
22764829c37SGerrit Uitslag                    . '</fieldset>'
22864829c37SGerrit Uitslag                . '</form>'
22964829c37SGerrit Uitslag            . '</div>';
230f0fda08aSwikidesign    }
231f0fda08aSwikidesign}
232