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 */ 12dfc5d08bSGerrit Uitslagclass syntax_plugin_discussion_threads extends DokuWiki_Syntax_Plugin 13dfc5d08bSGerrit Uitslag{ 14f0fda08aSwikidesign 15e7ac9adaSGerrit Uitslag /** 16e7ac9adaSGerrit Uitslag * Syntax Type 17e7ac9adaSGerrit Uitslag * 18e7ac9adaSGerrit Uitslag * @return string 19e7ac9adaSGerrit Uitslag */ 20dfc5d08bSGerrit Uitslag public function getType() 21dfc5d08bSGerrit Uitslag { 22dfc5d08bSGerrit Uitslag return 'substition'; 23dfc5d08bSGerrit Uitslag } 24e7ac9adaSGerrit Uitslag 25e7ac9adaSGerrit Uitslag /** 26e7ac9adaSGerrit Uitslag * Paragraph Type 27e7ac9adaSGerrit Uitslag * 28e7ac9adaSGerrit Uitslag * @return string 29dfc5d08bSGerrit Uitslag * @see Doku_Handler_Block 30e7ac9adaSGerrit Uitslag */ 31dfc5d08bSGerrit Uitslag public function getPType() 32dfc5d08bSGerrit Uitslag { 33dfc5d08bSGerrit Uitslag return 'block'; 34dfc5d08bSGerrit Uitslag } 35e7ac9adaSGerrit Uitslag 36e7ac9adaSGerrit Uitslag /** 37e7ac9adaSGerrit Uitslag * Sort for applying this mode 38e7ac9adaSGerrit Uitslag * 39e7ac9adaSGerrit Uitslag * @return int 40e7ac9adaSGerrit Uitslag */ 41dfc5d08bSGerrit Uitslag public function getSort() 42dfc5d08bSGerrit Uitslag { 43dfc5d08bSGerrit Uitslag return 306; 44dfc5d08bSGerrit Uitslag } 455fc512fbSwikidesign 46e7ac9adaSGerrit Uitslag /** 47e7ac9adaSGerrit Uitslag * @param string $mode 48e7ac9adaSGerrit Uitslag */ 49dfc5d08bSGerrit Uitslag public function connectTo($mode) 50dfc5d08bSGerrit 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 */ 63dfc5d08bSGerrit Uitslag public function handle($match, $state, $pos, Doku_Handler $handler) 64dfc5d08bSGerrit Uitslag { 65f0fda08aSwikidesign global $ID; 66*76fdd2cdSGerrit Uitslag $customFlags = [ 67*76fdd2cdSGerrit Uitslag 'count' => 0, 68*76fdd2cdSGerrit Uitslag 'skipempty' => false, 69*76fdd2cdSGerrit Uitslag 'nonewthreadform' => false 70*76fdd2cdSGerrit Uitslag ]; 71f5b180ccSwikidesign 720e0effa1Swikidesign $match = substr($match, 10, -2); // strip {{threads> from start and }} from end 7364829c37SGerrit Uitslag list($match, $flags) = array_pad(explode('&', $match, 2), 2, ''); 740e0effa1Swikidesign $flags = explode('&', $flags); 75912b9053Slupo49 765644a1afSlupo49 // Identify the count/skipempty flag and remove it before passing it to pagelist 77912b9053Slupo49 foreach ($flags as $key => $flag) { 78912b9053Slupo49 if (substr($flag, 0, 5) == "count") { 79*76fdd2cdSGerrit Uitslag list(,$cnt) = array_pad(explode('=', $flag, 2), 2, 0); 80*76fdd2cdSGerrit Uitslag if(is_numeric($cnt) && $cnt > 0) { 81*76fdd2cdSGerrit Uitslag $customFlags['count'] = $cnt; 82*76fdd2cdSGerrit Uitslag } 83912b9053Slupo49 unset($flags[$key]); 84c2a7577fSLarsGit223 } elseif (substr($flag, 0, 9) == "skipempty") { 855644a1afSlupo49 $customFlags['skipempty'] = true; 865644a1afSlupo49 unset($flags[$key]); 87c2a7577fSLarsGit223 } elseif (substr($flag, 0, 15) == "nonewthreadform") { 88c2a7577fSLarsGit223 $customFlags['nonewthreadform'] = true; 89c2a7577fSLarsGit223 unset($flags[$key]); 90912b9053Slupo49 } 91912b9053Slupo49 } 92912b9053Slupo49 9364829c37SGerrit Uitslag list($ns, $refine) = array_pad(explode(' ', $match, 2), 2, ''); 94f0fda08aSwikidesign 9564829c37SGerrit Uitslag if ($ns == '*' || $ns == ':') { 9664829c37SGerrit Uitslag $ns = ''; 9764829c37SGerrit Uitslag } elseif ($ns == '.') { 9864829c37SGerrit Uitslag $ns = getNS($ID); 9964829c37SGerrit Uitslag } else { 10064829c37SGerrit Uitslag $ns = cleanID($ns); 10164829c37SGerrit Uitslag } 102f0fda08aSwikidesign 10364829c37SGerrit Uitslag return [$ns, $flags, $refine, $customFlags]; 104f5b180ccSwikidesign } 105f5b180ccSwikidesign 106e7ac9adaSGerrit Uitslag /** 107e7ac9adaSGerrit Uitslag * Handles the actual output creation. 108e7ac9adaSGerrit Uitslag * 10964829c37SGerrit Uitslag * @param string $format output format being rendered 11064829c37SGerrit Uitslag * @param Doku_Renderer $renderer the current renderer object 11164829c37SGerrit Uitslag * @param array $data data created by handler() 112e7ac9adaSGerrit Uitslag * @return boolean rendered correctly? 113e7ac9adaSGerrit Uitslag */ 114dfc5d08bSGerrit Uitslag public function render($format, Doku_Renderer $renderer, $data) 115dfc5d08bSGerrit Uitslag { 1165644a1afSlupo49 list($ns, $flags, $refine, $customFlags) = $data; 1175644a1afSlupo49 $count = $customFlags['count']; 1185644a1afSlupo49 $skipEmpty = $customFlags['skipempty']; 119c2a7577fSLarsGit223 $noNewThreadForm = $customFlags['nonewthreadform']; 120912b9053Slupo49 $i = 0; 1210e0effa1Swikidesign 12264829c37SGerrit Uitslag $pages = []; 12364829c37SGerrit Uitslag /** @var helper_plugin_discussion $helper */ 12464829c37SGerrit Uitslag if ($helper = $this->loadHelper('discussion')) { 12564829c37SGerrit Uitslag $pages = $helper->getThreads($ns, null, $skipEmpty); 12664829c37SGerrit Uitslag } 127e2c227dfSwikidesign 128e2c227dfSwikidesign // use tag refinements? 129e2c227dfSwikidesign if ($refine) { 130e7ac9adaSGerrit Uitslag /** @var helper_plugin_tag $tag */ 13164829c37SGerrit Uitslag if (!$tag = $this->loadHelper('tag', false)) { 132e2c227dfSwikidesign msg('The Tag Plugin must be installed to use tag refinements.', -1); 133e2c227dfSwikidesign } else { 134e2c227dfSwikidesign $pages = $tag->tagRefine($pages, $refine); 135e2c227dfSwikidesign } 136e2c227dfSwikidesign } 137e2c227dfSwikidesign 13881cc6d2cSwikidesign if (!$pages) { 13964829c37SGerrit Uitslag if (auth_quickaclcheck($ns . ':*') >= AUTH_CREATE && $format == 'xhtml') { 140c2e2c575Slpaulsen93 $renderer->nocache(); 141c2a7577fSLarsGit223 if ($noNewThreadForm !== true) { 14264829c37SGerrit Uitslag $renderer->doc .= $this->newThreadForm($ns); 14377f39d56Swikidesign } 144c2a7577fSLarsGit223 } 14581cc6d2cSwikidesign return true; // nothing to display 14681cc6d2cSwikidesign } 147f0fda08aSwikidesign 14864829c37SGerrit Uitslag if ($format == 'xhtml') { 14964829c37SGerrit Uitslag /** @var Doku_Renderer_xhtml $renderer */ 150f0fda08aSwikidesign // prevent caching to ensure content is always fresh 151c2e2c575Slpaulsen93 $renderer->nocache(); 152f0fda08aSwikidesign 153cc497149Swikidesign // show form to start a new discussion thread? 154c2a7577fSLarsGit223 if ($noNewThreadForm !== true) { 15564829c37SGerrit Uitslag $hasCreatePermission = auth_quickaclcheck($ns . ':*') >= AUTH_CREATE; 15664829c37SGerrit Uitslag if ($hasCreatePermission && $this->getConf('threads_formposition') == 'top') { 15764829c37SGerrit Uitslag $renderer->doc .= $this->newThreadForm($ns); 158c2a7577fSLarsGit223 } 159c2a7577fSLarsGit223 } 160cc497149Swikidesign 1615fc512fbSwikidesign // let Pagelist Plugin do the work for us 16264829c37SGerrit Uitslag /** @var helper_plugin_pagelist $pagelist */ 16364829c37SGerrit Uitslag if (!$pagelist = $this->loadHelper('pagelist', false)) { 1645fc512fbSwikidesign msg('The Pagelist Plugin must be installed for threads lists to work.', -1); 1655fc512fbSwikidesign return false; 1665fc512fbSwikidesign } 16764829c37SGerrit Uitslag $pagelist->addColumn('discussion', 'comments'); 1680e0effa1Swikidesign $pagelist->setFlags($flags); 1695fc512fbSwikidesign $pagelist->startList(); 170e7ac9adaSGerrit Uitslag foreach ($pages as $page) { 171c5b0470aSMichael Klier $page['class'] = 'discussion_status' . $page['status']; 1725fc512fbSwikidesign $pagelist->addPage($page); 173912b9053Slupo49 174912b9053Slupo49 $i++; 17564829c37SGerrit Uitslag if ($count > 0 && $i >= $count) { 17664829c37SGerrit Uitslag // Only display the n discussion threads specified by the count flag 17764829c37SGerrit Uitslag break; 17864829c37SGerrit Uitslag } 1797a292a0dSwikidesign } 1805fc512fbSwikidesign $renderer->doc .= $pagelist->finishList(); 181f0fda08aSwikidesign 182f0fda08aSwikidesign // show form to start a new discussion thread? 183c2a7577fSLarsGit223 if ($noNewThreadForm !== true) { 18464829c37SGerrit Uitslag if ($hasCreatePermission && $this->getConf('threads_formposition') == 'bottom') { 18564829c37SGerrit Uitslag $renderer->doc .= $this->newThreadForm($ns); 186c2a7577fSLarsGit223 } 187c2a7577fSLarsGit223 } 188f0fda08aSwikidesign 189f0fda08aSwikidesign return true; 190f0fda08aSwikidesign 191f0fda08aSwikidesign // for metadata renderer 19264829c37SGerrit Uitslag } elseif ($format == 'metadata') { 19364829c37SGerrit Uitslag /** @var Doku_Renderer_metadata $renderer */ 194f0fda08aSwikidesign foreach ($pages as $page) { 1955fc512fbSwikidesign $renderer->meta['relation']['references'][$page['id']] = true; 196f0fda08aSwikidesign } 197f0fda08aSwikidesign 198f0fda08aSwikidesign return true; 199f0fda08aSwikidesign } 200f0fda08aSwikidesign return false; 201f0fda08aSwikidesign } 202f0fda08aSwikidesign 2035fc512fbSwikidesign /* ---------- (X)HTML Output Functions ---------- */ 204f0fda08aSwikidesign 205f0fda08aSwikidesign /** 206f0fda08aSwikidesign * Show the form to start a new discussion thread 207e7ac9adaSGerrit Uitslag * 208e7ac9adaSGerrit Uitslag * @param string $ns 20964829c37SGerrit Uitslag * @return string html 210f0fda08aSwikidesign */ 211dfc5d08bSGerrit Uitslag protected function newThreadForm($ns) 212dfc5d08bSGerrit Uitslag { 213f0fda08aSwikidesign global $ID; 214f0fda08aSwikidesign global $lang; 215f0fda08aSwikidesign 21664829c37SGerrit Uitslag return '<div class="newthread_form">' 21764829c37SGerrit Uitslag . '<form id="discussion__newthread_form" method="post" action="' . script() . '" accept-charset="' . $lang['encoding'] . '">' 21864829c37SGerrit Uitslag . '<fieldset>' 21964829c37SGerrit Uitslag . '<legend> ' . $this->getLang('newthread') . ': </legend>' 22064829c37SGerrit Uitslag . '<input type="hidden" name="id" value="' . $ID . '" />' 22164829c37SGerrit Uitslag . '<input type="hidden" name="do" value="newthread" />' 22264829c37SGerrit Uitslag . '<input type="hidden" name="ns" value="' . $ns . '" />' 22364829c37SGerrit Uitslag . '<input class="edit" type="text" name="title" id="discussion__newthread_title" size="40" tabindex="1" />' 22464829c37SGerrit Uitslag . '<input class="button" type="submit" value="' . $lang['btn_create'] . '" tabindex="2" />' 22564829c37SGerrit Uitslag . '</fieldset>' 22664829c37SGerrit Uitslag . '</form>' 22764829c37SGerrit Uitslag . '</div>'; 228f0fda08aSwikidesign } 229f0fda08aSwikidesign} 230