1*f0fda08aSwikidesign<?php 2*f0fda08aSwikidesign/** 3*f0fda08aSwikidesign * Discussion Plugin, threads component: displays a list of recently active discussions 4*f0fda08aSwikidesign * 5*f0fda08aSwikidesign * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) 6*f0fda08aSwikidesign * @author Esther Brunner <wikidesign@gmail.com> 7*f0fda08aSwikidesign */ 8*f0fda08aSwikidesign 9*f0fda08aSwikidesign// must be run within Dokuwiki 10*f0fda08aSwikidesignif(!defined('DOKU_INC')) die(); 11*f0fda08aSwikidesign 12*f0fda08aSwikidesignif(!defined('DOKU_PLUGIN')) define('DOKU_PLUGIN',DOKU_INC.'lib/plugins/'); 13*f0fda08aSwikidesignrequire_once(DOKU_PLUGIN.'syntax.php'); 14*f0fda08aSwikidesign 15*f0fda08aSwikidesign/** 16*f0fda08aSwikidesign * All DokuWiki plugins to extend the parser/rendering mechanism 17*f0fda08aSwikidesign * need to inherit from this class 18*f0fda08aSwikidesign */ 19*f0fda08aSwikidesignclass syntax_plugin_discussion_threads extends DokuWiki_Syntax_Plugin { 20*f0fda08aSwikidesign 21*f0fda08aSwikidesign /** 22*f0fda08aSwikidesign * return some info 23*f0fda08aSwikidesign */ 24*f0fda08aSwikidesign function getInfo(){ 25*f0fda08aSwikidesign return array( 26*f0fda08aSwikidesign 'author' => 'Esther Brunner', 27*f0fda08aSwikidesign 'email' => 'wikidesign@gmail.com', 28*f0fda08aSwikidesign 'date' => '2006-10-05', 29*f0fda08aSwikidesign 'name' => 'Discussion Plugin (threads component)', 30*f0fda08aSwikidesign 'desc' => 'Displays a list of recently active discussions', 31*f0fda08aSwikidesign 'url' => 'http://wiki.splitbrain.org/plugin:discussion', 32*f0fda08aSwikidesign ); 33*f0fda08aSwikidesign } 34*f0fda08aSwikidesign 35*f0fda08aSwikidesign function getType(){ return 'substition'; } 36*f0fda08aSwikidesign function getPType(){ return 'block'; } 37*f0fda08aSwikidesign function getSort(){ return 306; } 38*f0fda08aSwikidesign function connectTo($mode) { $this->Lexer->addSpecialPattern('\{\{threads>.+?\}\}',$mode,'plugin_discussion_threads'); } 39*f0fda08aSwikidesign 40*f0fda08aSwikidesign /** 41*f0fda08aSwikidesign * Handle the match 42*f0fda08aSwikidesign */ 43*f0fda08aSwikidesign function handle($match, $state, $pos, &$handler){ 44*f0fda08aSwikidesign $match = substr($match, 10, -2); // strip {{threads> from start and }} from end 45*f0fda08aSwikidesign return cleanID($match); 46*f0fda08aSwikidesign } 47*f0fda08aSwikidesign 48*f0fda08aSwikidesign /** 49*f0fda08aSwikidesign * Create output 50*f0fda08aSwikidesign */ 51*f0fda08aSwikidesign function render($mode, &$renderer, $ns) { 52*f0fda08aSwikidesign global $ID; 53*f0fda08aSwikidesign global $conf; 54*f0fda08aSwikidesign 55*f0fda08aSwikidesign if ($ns == ':') $ns = ''; 56*f0fda08aSwikidesign elseif ($ns == '.') $ns = getNS($ID); 57*f0fda08aSwikidesign 58*f0fda08aSwikidesign $pages = $this->_threadList($ns); 59*f0fda08aSwikidesign 60*f0fda08aSwikidesign if (!count($pages)) return true; // nothing to display 61*f0fda08aSwikidesign 62*f0fda08aSwikidesign if ($mode == 'xhtml'){ 63*f0fda08aSwikidesign 64*f0fda08aSwikidesign // prevent caching to ensure content is always fresh 65*f0fda08aSwikidesign $renderer->info['cache'] = false; 66*f0fda08aSwikidesign 67*f0fda08aSwikidesign // main table 68*f0fda08aSwikidesign $renderer->doc .= '<table class="threads">'; 69*f0fda08aSwikidesign foreach ($pages as $page){ 70*f0fda08aSwikidesign $renderer->doc .= '<tr><td class="page">'; 71*f0fda08aSwikidesign 72*f0fda08aSwikidesign // page title 73*f0fda08aSwikidesign $id = $page['id']; 74*f0fda08aSwikidesign $title = $page['title']; 75*f0fda08aSwikidesign if (!$title) $title = str_replace('_', ' ', noNS($id)); 76*f0fda08aSwikidesign $renderer->doc .= $renderer->internallink(':'.$id, $title).'</td>'; 77*f0fda08aSwikidesign 78*f0fda08aSwikidesign // topic starter 79*f0fda08aSwikidesign if ($this->getConf('threads_showuser')){ 80*f0fda08aSwikidesign if ($page['user']) $renderer->doc .= '<td class="user">'.$page['user'].'</td>'; 81*f0fda08aSwikidesign else $renderer->doc .= '<td class="user"> </td>'; 82*f0fda08aSwikidesign } 83*f0fda08aSwikidesign 84*f0fda08aSwikidesign // number of replies 85*f0fda08aSwikidesign if ($page['num'] == 0) $repl = ''; 86*f0fda08aSwikidesign elseif ($page['num'] == 1) $repl = '1 '.$this->getLang('reply'); 87*f0fda08aSwikidesign else $repl = $page['num'].' '.$this->getLang('replies'); 88*f0fda08aSwikidesign $renderer->doc .= '<td class="num">'.$repl.'</td>'; 89*f0fda08aSwikidesign 90*f0fda08aSwikidesign // last comment date 91*f0fda08aSwikidesign if ($this->getConf('threads_showdate')){ 92*f0fda08aSwikidesign $renderer->doc .= '<td class="date">'.date($conf['dformat'], $page['date']). 93*f0fda08aSwikidesign '</td>'; 94*f0fda08aSwikidesign } 95*f0fda08aSwikidesign $renderer->doc .= '</tr>'; 96*f0fda08aSwikidesign } 97*f0fda08aSwikidesign $renderer->doc .= '</table>'; 98*f0fda08aSwikidesign 99*f0fda08aSwikidesign // show form to start a new discussion thread? 100*f0fda08aSwikidesign if (auth_quickaclcheck($ns.':*') >= AUTH_CREATE) 101*f0fda08aSwikidesign $renderer->doc .= $this->_newthreadForm($ns); 102*f0fda08aSwikidesign 103*f0fda08aSwikidesign return true; 104*f0fda08aSwikidesign 105*f0fda08aSwikidesign // for metadata renderer 106*f0fda08aSwikidesign } elseif ($mode == 'metadata'){ 107*f0fda08aSwikidesign foreach ($pages as $page){ 108*f0fda08aSwikidesign $id = $page['id']; 109*f0fda08aSwikidesign $renderer->meta['relation']['references'][$id] = true; 110*f0fda08aSwikidesign } 111*f0fda08aSwikidesign 112*f0fda08aSwikidesign return true; 113*f0fda08aSwikidesign } 114*f0fda08aSwikidesign return false; 115*f0fda08aSwikidesign } 116*f0fda08aSwikidesign 117*f0fda08aSwikidesign /** 118*f0fda08aSwikidesign * Returns an array of files with discussion sections, sorted by recent comments 119*f0fda08aSwikidesign */ 120*f0fda08aSwikidesign function _threadList($ns){ 121*f0fda08aSwikidesign global $conf; 122*f0fda08aSwikidesign 123*f0fda08aSwikidesign require_once(DOKU_INC.'inc/search.php'); 124*f0fda08aSwikidesign 125*f0fda08aSwikidesign $dir = $conf['datadir'].($ns ? '/'.str_replace(':', '/', $ns): ''); 126*f0fda08aSwikidesign 127*f0fda08aSwikidesign // returns the list of pages in the given namespace, acl checked 128*f0fda08aSwikidesign $items = array(); 129*f0fda08aSwikidesign search($items, $dir, 'search_list', ''); 130*f0fda08aSwikidesign 131*f0fda08aSwikidesign // add pages with comments to result 132*f0fda08aSwikidesign $result = array(); 133*f0fda08aSwikidesign foreach ($items as $item){ 134*f0fda08aSwikidesign $id = ($ns ? $ns.':' : '').$item['id']; 135*f0fda08aSwikidesign $file = metaFN($id, '.comments'); 136*f0fda08aSwikidesign if (!@file_exists($file)) continue; // skip if no comments file 137*f0fda08aSwikidesign $data = unserialize(io_readFile($file, false)); 138*f0fda08aSwikidesign if ($data['status'] == 0) continue; // skip if comments are off 139*f0fda08aSwikidesign $date = filemtime($file); 140*f0fda08aSwikidesign $meta = p_get_metadata($id); 141*f0fda08aSwikidesign $result[$date] = array( 142*f0fda08aSwikidesign 'id' => $id, 143*f0fda08aSwikidesign 'title' => $meta['title'], 144*f0fda08aSwikidesign 'user' => $meta['creator'], 145*f0fda08aSwikidesign 'num' => $data['number'], 146*f0fda08aSwikidesign 'date' => $date, 147*f0fda08aSwikidesign ); 148*f0fda08aSwikidesign } 149*f0fda08aSwikidesign 150*f0fda08aSwikidesign // finally sort by time of last comment 151*f0fda08aSwikidesign krsort($result); 152*f0fda08aSwikidesign 153*f0fda08aSwikidesign return $result; 154*f0fda08aSwikidesign } 155*f0fda08aSwikidesign 156*f0fda08aSwikidesign /** 157*f0fda08aSwikidesign * Show the form to start a new discussion thread 158*f0fda08aSwikidesign */ 159*f0fda08aSwikidesign function _newthreadForm($ns){ 160*f0fda08aSwikidesign global $ID; 161*f0fda08aSwikidesign global $lang; 162*f0fda08aSwikidesign 163*f0fda08aSwikidesign return '<div class="newthread_form">'. 164*f0fda08aSwikidesign '<form id="discussion__newthread_form" method="post" action="'.script().'" accept-charset="'.$lang['encoding'].'">'. 165*f0fda08aSwikidesign '<div class="no">'. 166*f0fda08aSwikidesign '<input type="hidden" name="id" value="'.$ID.'" />'. 167*f0fda08aSwikidesign '<input type="hidden" name="do" value="newthread" />'. 168*f0fda08aSwikidesign '<input type="hidden" name="ns" value="'.$ns.'" />'. 169*f0fda08aSwikidesign '<label class="block" for="discussion__newthread_title">'. 170*f0fda08aSwikidesign '<span>'.$this->getLang('newthread').':</span> '. 171*f0fda08aSwikidesign '<input class="edit" type="text" name="title" id="discussion__newthread_title" size="40" tabindex="1" />'. 172*f0fda08aSwikidesign '</label>'. 173*f0fda08aSwikidesign '<input class="button" type="submit" value="'.$lang['btn_create'].'" tabindex="2" />'. 174*f0fda08aSwikidesign '</div>'. 175*f0fda08aSwikidesign '</form>'. 176*f0fda08aSwikidesign '</div>'; 177*f0fda08aSwikidesign } 178*f0fda08aSwikidesign 179*f0fda08aSwikidesign} 180*f0fda08aSwikidesign 181*f0fda08aSwikidesign//Setup VIM: ex: et ts=4 enc=utf-8 : 182