xref: /plugin/discussion/syntax/threads.php (revision c2a7577f624b66e7ed4371ffc84009e7f26aea7a)
1
2<?php
3/**
4 * Discussion Plugin, threads component: displays a list of recently active discussions
5 *
6 * @license  GPL 2 (http://www.gnu.org/licenses/gpl.html)
7 * @author   Esther Brunner <wikidesign@gmail.com>
8 */
9
10// must be run within Dokuwiki
11if(!defined('DOKU_INC')) die();
12
13/**
14 * Class syntax_plugin_discussion_threads
15 */
16class syntax_plugin_discussion_threads extends DokuWiki_Syntax_Plugin {
17
18    /**
19     * Syntax Type
20     *
21     * @return string
22     */
23    function getType() { return 'substition'; }
24
25    /**
26     * Paragraph Type
27     *
28     * @see Doku_Handler_Block
29     * @return string
30     */
31    function getPType() { return 'block'; }
32
33    /**
34     * Sort for applying this mode
35     *
36     * @return int
37     */
38    function getSort() { return 306; }
39
40    /**
41     * @param string $mode
42     */
43    function connectTo($mode) {
44        $this->Lexer->addSpecialPattern('\{\{threads>.+?\}\}', $mode, 'plugin_discussion_threads');
45    }
46
47    /**
48     * Handler to prepare matched data for the rendering process
49     *
50     * @param   string       $match   The text matched by the patterns
51     * @param   int          $state   The lexer state for the match
52     * @param   int          $pos     The character position of the matched text
53     * @param   Doku_Handler $handler The Doku_Handler object
54     * @return  array Return an array with all data you want to use in render
55     */
56    function handle($match, $state, $pos, Doku_Handler $handler) {
57        global $ID;
58        $customFlags = array();
59
60        $match = substr($match, 10, -2); // strip {{threads> from start and }} from end
61        list($match, $flags) = explode('&', $match, 2);
62        $flags = explode('&', $flags);
63
64        // Identify the count/skipempty flag and remove it before passing it to pagelist
65        foreach($flags as $key => $flag) {
66            if (substr($flag, 0, 5) == "count") {
67                $tmp = explode('=', $flag);
68                $customFlags['count'] = $tmp[1];
69                unset($flags[$key]);
70            } elseif (substr($flag, 0, 9) == "skipempty") {
71                $customFlags['skipempty'] = true;
72                unset($flags[$key]);
73            } elseif (substr($flag, 0, 15) == "nonewthreadform") {
74                $customFlags['nonewthreadform'] = true;
75                unset($flags[$key]);
76            }
77        }
78
79        // Ignore params if invalid values have been passed
80        if(!array_key_exists('count', $customFlags) || $customFlags['count'] <= 0 || !is_numeric($customFlags['count'])) $customFlags['count'] = false;
81        if(!array_key_exists('skipempty', $customFlags) && !$customFlags['skipempty']) $customFlags['skipempty'] = false;
82
83        list($ns, $refine) = explode(' ', $match, 2);
84
85        if (($ns == '*') || ($ns == ':')) $ns = '';
86        elseif ($ns == '.') $ns = getNS($ID);
87        else $ns = cleanID($ns);
88
89        return array($ns, $flags, $refine, $customFlags);
90    }
91
92    /**
93     * Handles the actual output creation.
94     *
95     * @param   $mode   string        output format being rendered
96     * @param   $renderer Doku_Renderer the current renderer object
97     * @param   $data     array         data created by handler()
98     * @return  boolean                 rendered correctly?
99     */
100    function render($mode, Doku_Renderer $renderer, $data) {
101        list($ns, $flags, $refine, $customFlags) = $data;
102        $count = $customFlags['count'];
103        $skipEmpty = $customFlags['skipempty'];
104        $noNewThreadForm = $customFlags['nonewthreadform'];
105        $i = 0;
106
107        $pages = array();
108        /** @var helper_plugin_discussion $my */
109        if ($my =& plugin_load('helper', 'discussion')) $pages = $my->getThreads($ns, null, $skipEmpty);
110
111        // use tag refinements?
112        if ($refine) {
113            /** @var helper_plugin_tag $tag */
114            if (plugin_isdisabled('tag') || (!$tag = plugin_load('helper', 'tag'))) {
115                msg('The Tag Plugin must be installed to use tag refinements.', -1);
116            } else {
117                $pages = $tag->tagRefine($pages, $refine);
118            }
119        }
120
121        if (!$pages) {
122            if ((auth_quickaclcheck($ns.':*') >= AUTH_CREATE) && ($mode == 'xhtml')) {
123                $renderer->info['cache'] = false;
124                if ($noNewThreadForm !== true) {
125                    $renderer->doc .= $this->_newThreadForm($ns);
126                }
127            }
128            return true; // nothing to display
129        }
130
131        if ($mode == 'xhtml') {
132            /** @var $renderer Doku_Renderer_xhtml */
133            // prevent caching to ensure content is always fresh
134            $renderer->info['cache'] = false;
135
136            // show form to start a new discussion thread?
137            if ($noNewThreadForm !== true) {
138                $perm_create = (auth_quickaclcheck($ns.':*') >= AUTH_CREATE);
139                if ($perm_create && ($this->getConf('threads_formposition') == 'top')) {
140                    $renderer->doc .= $this->_newThreadForm($ns);
141                }
142            }
143
144            // let Pagelist Plugin do the work for us
145            /** @var $pagelist helper_plugin_pagelist */
146            if (plugin_isdisabled('pagelist')
147                    || (!$pagelist =& plugin_load('helper', 'pagelist'))) {
148                msg('The Pagelist Plugin must be installed for threads lists to work.', -1);
149                return false;
150            }
151            $pagelist->column['comments'] = true;
152            $pagelist->setFlags($flags);
153            $pagelist->startList();
154            foreach ($pages as $page) {
155                $page['class'] = 'discussion_status'.$page['status'];
156                $pagelist->addPage($page);
157
158                $i++;
159                if($count != false && $i >= $count) break; // Only display the n discussion threads specified by the count flag
160            }
161            $renderer->doc .= $pagelist->finishList();
162
163            // show form to start a new discussion thread?
164            if ($noNewThreadForm !== true) {
165                if ($perm_create && ($this->getConf('threads_formposition') == 'bottom')) {
166                    $renderer->doc .= $this->_newThreadForm($ns);
167                }
168            }
169
170            return true;
171
172            // for metadata renderer
173        } elseif ($mode == 'metadata') {
174            /** @var $renderer Doku_Renderer_metadata */
175            foreach ($pages as $page) {
176                $renderer->meta['relation']['references'][$page['id']] = true;
177            }
178
179            return true;
180        }
181        return false;
182    }
183
184    /* ---------- (X)HTML Output Functions ---------- */
185
186    /**
187     * Show the form to start a new discussion thread
188     *
189     * @param string $ns
190     * @return string
191     */
192    function _newThreadForm($ns) {
193        global $ID;
194        global $lang;
195
196        return '<div class="newthread_form">'.DOKU_LF.
197            '<form id="discussion__newthread_form"  method="post" action="'.script().'" accept-charset="'.$lang['encoding'].'">'.DOKU_LF.
198            DOKU_TAB.'<fieldset>'.DOKU_LF.
199            DOKU_TAB.DOKU_TAB.'<legend> '.$this->getLang('newthread').': </legend>'.DOKU_LF.
200            DOKU_TAB.DOKU_TAB.'<input type="hidden" name="id" value="'.$ID.'" />'.DOKU_LF.
201            DOKU_TAB.DOKU_TAB.'<input type="hidden" name="do" value="newthread" />'.DOKU_LF.
202            DOKU_TAB.DOKU_TAB.'<input type="hidden" name="ns" value="'.$ns.'" />'.DOKU_LF.
203            DOKU_TAB.DOKU_TAB.'<input class="edit" type="text" name="title" id="discussion__newthread_title" size="40" tabindex="1" />'.DOKU_LF.
204            DOKU_TAB.DOKU_TAB.'<input class="button" type="submit" value="'.$lang['btn_create'].'" tabindex="2" />'.DOKU_LF.
205            DOKU_TAB.'</fieldset>'.DOKU_LF.
206            '</form>'.DOKU_LF.
207            '</div>'.DOKU_LF;
208    }
209}
210// vim:ts=4:sw=4:et:enc=utf-8:
211