xref: /plugin/discussion/syntax/threads.php (revision 64829c37106252c090bb45ac0286a7d85bfc0e99)
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 */
12f0fda08aSwikidesignclass syntax_plugin_discussion_threads extends DokuWiki_Syntax_Plugin {
13f0fda08aSwikidesign
14e7ac9adaSGerrit Uitslag    /**
15e7ac9adaSGerrit Uitslag     * Syntax Type
16e7ac9adaSGerrit Uitslag     *
17e7ac9adaSGerrit Uitslag     * @return string
18e7ac9adaSGerrit Uitslag     */
19*64829c37SGerrit Uitslag    public function getType() { return 'substition'; }
20e7ac9adaSGerrit Uitslag
21e7ac9adaSGerrit Uitslag    /**
22e7ac9adaSGerrit Uitslag     * Paragraph Type
23e7ac9adaSGerrit Uitslag     *
24e7ac9adaSGerrit Uitslag     * @see Doku_Handler_Block
25e7ac9adaSGerrit Uitslag     * @return string
26e7ac9adaSGerrit Uitslag     */
27*64829c37SGerrit Uitslag    public function getPType() { return 'block'; }
28e7ac9adaSGerrit Uitslag
29e7ac9adaSGerrit Uitslag    /**
30e7ac9adaSGerrit Uitslag     * Sort for applying this mode
31e7ac9adaSGerrit Uitslag     *
32e7ac9adaSGerrit Uitslag     * @return int
33e7ac9adaSGerrit Uitslag     */
34*64829c37SGerrit Uitslag    public function getSort() { return 306; }
355fc512fbSwikidesign
36e7ac9adaSGerrit Uitslag    /**
37e7ac9adaSGerrit Uitslag     * @param string $mode
38e7ac9adaSGerrit Uitslag     */
39*64829c37SGerrit Uitslag    public function connectTo($mode) {
405fc512fbSwikidesign        $this->Lexer->addSpecialPattern('\{\{threads>.+?\}\}', $mode, 'plugin_discussion_threads');
415fc512fbSwikidesign    }
42f0fda08aSwikidesign
43e7ac9adaSGerrit Uitslag    /**
44e7ac9adaSGerrit Uitslag     * Handler to prepare matched data for the rendering process
45e7ac9adaSGerrit Uitslag     *
46e7ac9adaSGerrit Uitslag     * @param   string       $match   The text matched by the patterns
47e7ac9adaSGerrit Uitslag     * @param   int          $state   The lexer state for the match
48e7ac9adaSGerrit Uitslag     * @param   int          $pos     The character position of the matched text
49e7ac9adaSGerrit Uitslag     * @param   Doku_Handler $handler The Doku_Handler object
50e7ac9adaSGerrit Uitslag     * @return  array Return an array with all data you want to use in render
51e7ac9adaSGerrit Uitslag     */
52*64829c37SGerrit Uitslag    public function handle($match, $state, $pos, Doku_Handler $handler) {
53f0fda08aSwikidesign        global $ID;
545644a1afSlupo49        $customFlags = array();
55f5b180ccSwikidesign
560e0effa1Swikidesign        $match = substr($match, 10, -2); // strip {{threads> from start and }} from end
57*64829c37SGerrit Uitslag        list($match, $flags) = array_pad(explode('&', $match, 2),2, '');
580e0effa1Swikidesign        $flags = explode('&', $flags);
59912b9053Slupo49
605644a1afSlupo49        // Identify the count/skipempty flag and remove it before passing it to pagelist
61912b9053Slupo49        foreach($flags as $key => $flag) {
62912b9053Slupo49            if (substr($flag, 0, 5) == "count") {
63*64829c37SGerrit Uitslag                $tmp = array_pad(explode('=', $flag, 2),2, 0);
645644a1afSlupo49                $customFlags['count'] = $tmp[1];
65912b9053Slupo49                unset($flags[$key]);
66c2a7577fSLarsGit223            } elseif (substr($flag, 0, 9) == "skipempty") {
675644a1afSlupo49                $customFlags['skipempty'] = true;
685644a1afSlupo49                unset($flags[$key]);
69c2a7577fSLarsGit223            } elseif (substr($flag, 0, 15) == "nonewthreadform") {
70c2a7577fSLarsGit223                $customFlags['nonewthreadform'] = true;
71c2a7577fSLarsGit223                unset($flags[$key]);
72912b9053Slupo49            }
73912b9053Slupo49        }
74912b9053Slupo49
755644a1afSlupo49        // Ignore params if invalid values have been passed
76*64829c37SGerrit Uitslag        if(!array_key_exists('count', $customFlags) || $customFlags['count'] <= 0 || !is_numeric($customFlags['count'])) {
77*64829c37SGerrit Uitslag            $customFlags['count'] = 0;
78*64829c37SGerrit Uitslag        }
79*64829c37SGerrit Uitslag        if(!array_key_exists('skipempty', $customFlags) && !$customFlags['skipempty']) {
80*64829c37SGerrit Uitslag            $customFlags['skipempty'] = false;
81*64829c37SGerrit Uitslag        }
82912b9053Slupo49
83*64829c37SGerrit Uitslag        list($ns, $refine) = array_pad(explode(' ', $match, 2), 2, '');
84f0fda08aSwikidesign
85*64829c37SGerrit Uitslag        if ($ns == '*' || $ns == ':') {
86*64829c37SGerrit Uitslag            $ns = '';
87*64829c37SGerrit Uitslag        } elseif ($ns == '.') {
88*64829c37SGerrit Uitslag            $ns = getNS($ID);
89*64829c37SGerrit Uitslag        } else {
90*64829c37SGerrit Uitslag            $ns = cleanID($ns);
91*64829c37SGerrit Uitslag        }
92f0fda08aSwikidesign
93*64829c37SGerrit Uitslag        return [$ns, $flags, $refine, $customFlags];
94f5b180ccSwikidesign    }
95f5b180ccSwikidesign
96e7ac9adaSGerrit Uitslag    /**
97e7ac9adaSGerrit Uitslag     * Handles the actual output creation.
98e7ac9adaSGerrit Uitslag     *
99*64829c37SGerrit Uitslag     * @param string $format output format being rendered
100*64829c37SGerrit Uitslag     * @param Doku_Renderer $renderer the current renderer object
101*64829c37SGerrit Uitslag     * @param array $data data created by handler()
102e7ac9adaSGerrit Uitslag     * @return boolean rendered correctly?
103e7ac9adaSGerrit Uitslag     */
104*64829c37SGerrit Uitslag    public function render($format, Doku_Renderer $renderer, $data) {
1055644a1afSlupo49        list($ns, $flags, $refine, $customFlags) = $data;
1065644a1afSlupo49        $count = $customFlags['count'];
1075644a1afSlupo49        $skipEmpty = $customFlags['skipempty'];
108c2a7577fSLarsGit223        $noNewThreadForm = $customFlags['nonewthreadform'];
109912b9053Slupo49        $i = 0;
1100e0effa1Swikidesign
111*64829c37SGerrit Uitslag        $pages = [];
112*64829c37SGerrit Uitslag        /** @var helper_plugin_discussion $helper */
113*64829c37SGerrit Uitslag        if ($helper = $this->loadHelper('discussion')) {
114*64829c37SGerrit Uitslag            $pages = $helper->getThreads($ns, null, $skipEmpty);
115*64829c37SGerrit Uitslag        }
116e2c227dfSwikidesign
117e2c227dfSwikidesign        // use tag refinements?
118e2c227dfSwikidesign        if ($refine) {
119e7ac9adaSGerrit Uitslag            /** @var helper_plugin_tag $tag */
120*64829c37SGerrit Uitslag            if (!$tag = $this->loadHelper('tag', false)) {
121e2c227dfSwikidesign                msg('The Tag Plugin must be installed to use tag refinements.', -1);
122e2c227dfSwikidesign            } else {
123e2c227dfSwikidesign                $pages = $tag->tagRefine($pages, $refine);
124e2c227dfSwikidesign            }
125e2c227dfSwikidesign        }
126e2c227dfSwikidesign
12781cc6d2cSwikidesign        if (!$pages) {
128*64829c37SGerrit Uitslag            if (auth_quickaclcheck($ns.':*') >= AUTH_CREATE && $format == 'xhtml') {
129c2e2c575Slpaulsen93                $renderer->nocache();
130c2a7577fSLarsGit223                if ($noNewThreadForm !== true) {
131*64829c37SGerrit Uitslag                    $renderer->doc .= $this->newThreadForm($ns);
13277f39d56Swikidesign                }
133c2a7577fSLarsGit223            }
13481cc6d2cSwikidesign            return true; // nothing to display
13581cc6d2cSwikidesign        }
136f0fda08aSwikidesign
137*64829c37SGerrit Uitslag        if ($format == 'xhtml') {
138*64829c37SGerrit Uitslag            /** @var Doku_Renderer_xhtml $renderer */
139f0fda08aSwikidesign            // prevent caching to ensure content is always fresh
140c2e2c575Slpaulsen93            $renderer->nocache();
141f0fda08aSwikidesign
142cc497149Swikidesign            // show form to start a new discussion thread?
143c2a7577fSLarsGit223            if ($noNewThreadForm !== true) {
144*64829c37SGerrit Uitslag                $hasCreatePermission = auth_quickaclcheck($ns.':*') >= AUTH_CREATE;
145*64829c37SGerrit Uitslag                if ($hasCreatePermission && $this->getConf('threads_formposition') == 'top') {
146*64829c37SGerrit Uitslag                    $renderer->doc .= $this->newThreadForm($ns);
147c2a7577fSLarsGit223                }
148c2a7577fSLarsGit223            }
149cc497149Swikidesign
1505fc512fbSwikidesign            // let Pagelist Plugin do the work for us
151*64829c37SGerrit Uitslag            /** @var helper_plugin_pagelist $pagelist */
152*64829c37SGerrit Uitslag            if (!$pagelist = $this->loadHelper('pagelist', false)) {
1535fc512fbSwikidesign                msg('The Pagelist Plugin must be installed for threads lists to work.', -1);
1545fc512fbSwikidesign                return false;
1555fc512fbSwikidesign            }
156*64829c37SGerrit Uitslag            $pagelist->addColumn('discussion', 'comments');
1570e0effa1Swikidesign            $pagelist->setFlags($flags);
1585fc512fbSwikidesign            $pagelist->startList();
159e7ac9adaSGerrit Uitslag            foreach ($pages as $page) {
160c5b0470aSMichael Klier                $page['class'] = 'discussion_status'.$page['status'];
1615fc512fbSwikidesign                $pagelist->addPage($page);
162912b9053Slupo49
163912b9053Slupo49                $i++;
164*64829c37SGerrit Uitslag                if($count > 0 && $i >= $count) {
165*64829c37SGerrit Uitslag                    // Only display the n discussion threads specified by the count flag
166*64829c37SGerrit Uitslag                    break;
167*64829c37SGerrit Uitslag                }
1687a292a0dSwikidesign            }
1695fc512fbSwikidesign            $renderer->doc .= $pagelist->finishList();
170f0fda08aSwikidesign
171f0fda08aSwikidesign            // show form to start a new discussion thread?
172c2a7577fSLarsGit223            if ($noNewThreadForm !== true) {
173*64829c37SGerrit Uitslag                if ($hasCreatePermission && $this->getConf('threads_formposition') == 'bottom') {
174*64829c37SGerrit Uitslag                    $renderer->doc .= $this->newThreadForm($ns);
175c2a7577fSLarsGit223                }
176c2a7577fSLarsGit223            }
177f0fda08aSwikidesign
178f0fda08aSwikidesign            return true;
179f0fda08aSwikidesign
180f0fda08aSwikidesign            // for metadata renderer
181*64829c37SGerrit Uitslag        } elseif ($format == 'metadata') {
182*64829c37SGerrit Uitslag            /** @var Doku_Renderer_metadata $renderer */
183f0fda08aSwikidesign            foreach ($pages as $page) {
1845fc512fbSwikidesign                $renderer->meta['relation']['references'][$page['id']] = true;
185f0fda08aSwikidesign            }
186f0fda08aSwikidesign
187f0fda08aSwikidesign            return true;
188f0fda08aSwikidesign        }
189f0fda08aSwikidesign        return false;
190f0fda08aSwikidesign    }
191f0fda08aSwikidesign
1925fc512fbSwikidesign    /* ---------- (X)HTML Output Functions ---------- */
193f0fda08aSwikidesign
194f0fda08aSwikidesign    /**
195f0fda08aSwikidesign     * Show the form to start a new discussion thread
196e7ac9adaSGerrit Uitslag     *
197e7ac9adaSGerrit Uitslag     * @param string $ns
198*64829c37SGerrit Uitslag     * @return string html
199f0fda08aSwikidesign     */
200*64829c37SGerrit Uitslag    protected function newThreadForm($ns) {
201f0fda08aSwikidesign        global $ID;
202f0fda08aSwikidesign        global $lang;
203f0fda08aSwikidesign
204*64829c37SGerrit Uitslag        return '<div class="newthread_form">'
205*64829c37SGerrit Uitslag                . '<form id="discussion__newthread_form"  method="post" action="' . script() . '" accept-charset="' . $lang['encoding'] . '">'
206*64829c37SGerrit Uitslag                    . '<fieldset>'
207*64829c37SGerrit Uitslag                        . '<legend> ' . $this->getLang('newthread') . ': </legend>'
208*64829c37SGerrit Uitslag                        . '<input type="hidden" name="id" value="' . $ID . '" />'
209*64829c37SGerrit Uitslag                        . '<input type="hidden" name="do" value="newthread" />'
210*64829c37SGerrit Uitslag                        . '<input type="hidden" name="ns" value="' . $ns . '" />'
211*64829c37SGerrit Uitslag                        . '<input class="edit" type="text" name="title" id="discussion__newthread_title" size="40" tabindex="1" />'
212*64829c37SGerrit Uitslag                        . '<input class="button" type="submit" value="' . $lang['btn_create'] . '" tabindex="2" />'
213*64829c37SGerrit Uitslag                    . '</fieldset>'
214*64829c37SGerrit Uitslag                . '</form>'
215*64829c37SGerrit Uitslag            . '</div>';
216f0fda08aSwikidesign    }
217f0fda08aSwikidesign}
218