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