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