15fc512fbSwikidesign<?php 25fc512fbSwikidesign/** 35fc512fbSwikidesign * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) 45fc512fbSwikidesign * @author Esther Brunner <wikidesign@gmail.com> 55fc512fbSwikidesign */ 65fc512fbSwikidesign 75fc512fbSwikidesign// must be run within Dokuwiki 85fc512fbSwikidesignif (!defined('DOKU_INC')) die(); 95fc512fbSwikidesign 10e7ac9adaSGerrit Uitslag/** 11e7ac9adaSGerrit Uitslag * Class helper_plugin_discussion 12e7ac9adaSGerrit Uitslag */ 135fc512fbSwikidesignclass helper_plugin_discussion extends DokuWiki_Plugin { 145fc512fbSwikidesign 15e7ac9adaSGerrit Uitslag /** 16e7ac9adaSGerrit Uitslag * @return array 17e7ac9adaSGerrit Uitslag */ 185fc512fbSwikidesign function getMethods() { 195fc512fbSwikidesign $result = array(); 205fc512fbSwikidesign $result[] = array( 215fc512fbSwikidesign 'name' => 'th', 225fc512fbSwikidesign 'desc' => 'returns the header of the comments column for pagelist', 235fc512fbSwikidesign 'return' => array('header' => 'string'), 245fc512fbSwikidesign ); 255fc512fbSwikidesign $result[] = array( 265fc512fbSwikidesign 'name' => 'td', 275fc512fbSwikidesign 'desc' => 'returns the link to the discussion section with number of comments', 285fc512fbSwikidesign 'params' => array( 295fc512fbSwikidesign 'id' => 'string', 305fc512fbSwikidesign 'number of comments (optional)' => 'integer'), 315fc512fbSwikidesign 'return' => array('link' => 'string'), 325fc512fbSwikidesign ); 335fc512fbSwikidesign $result[] = array( 345fc512fbSwikidesign 'name' => 'getThreads', 355fc512fbSwikidesign 'desc' => 'returns pages with discussion sections, sorted by recent comments', 365fc512fbSwikidesign 'params' => array( 375fc512fbSwikidesign 'namespace' => 'string', 385fc512fbSwikidesign 'number (optional)' => 'integer'), 395fc512fbSwikidesign 'return' => array('pages' => 'array'), 405fc512fbSwikidesign ); 415fc512fbSwikidesign $result[] = array( 425fc512fbSwikidesign 'name' => 'getComments', 435fc512fbSwikidesign 'desc' => 'returns recently added or edited comments individually', 445fc512fbSwikidesign 'params' => array( 455fc512fbSwikidesign 'namespace' => 'string', 465fc512fbSwikidesign 'number (optional)' => 'integer'), 475fc512fbSwikidesign 'return' => array('pages' => 'array'), 485fc512fbSwikidesign ); 495fc512fbSwikidesign return $result; 505fc512fbSwikidesign } 515fc512fbSwikidesign 525fc512fbSwikidesign /** 535fc512fbSwikidesign * Returns the column header for the Pagelist Plugin 54e7ac9adaSGerrit Uitslag * 55e7ac9adaSGerrit Uitslag * @return string 565fc512fbSwikidesign */ 575fc512fbSwikidesign function th() { 585fc512fbSwikidesign return $this->getLang('discussion'); 595fc512fbSwikidesign } 605fc512fbSwikidesign 615fc512fbSwikidesign /** 625fc512fbSwikidesign * Returns the link to the discussion section of a page 63e7ac9adaSGerrit Uitslag * 64e7ac9adaSGerrit Uitslag * @param string $id 65e7ac9adaSGerrit Uitslag * @param null|int $num 66e7ac9adaSGerrit Uitslag * @return string 675fc512fbSwikidesign */ 68e7ac9adaSGerrit Uitslag function td($id, $num = null) { 69479dd10fSwikidesign $section = '#discussion__section'; 705fc512fbSwikidesign 715fc512fbSwikidesign if (!isset($num)) { 725fc512fbSwikidesign $cfile = metaFN($id, '.comments'); 735fc512fbSwikidesign $comments = unserialize(io_readFile($cfile, false)); 745fc512fbSwikidesign 755fc512fbSwikidesign $num = $comments['number']; 765fc512fbSwikidesign if ((!$comments['status']) || (($comments['status'] == 2) && (!$num))) return ''; 775fc512fbSwikidesign } 785fc512fbSwikidesign 794cded5e1SGerrit Uitslag if ($num == 0) { 804cded5e1SGerrit Uitslag $comment = '0 '.$this->getLang('nocomments'); 814cded5e1SGerrit Uitslag } elseif ($num == 1) { 824cded5e1SGerrit Uitslag $comment = '1 '.$this->getLang('comment'); 834cded5e1SGerrit Uitslag } else { 844cded5e1SGerrit Uitslag $comment = $num.' '.$this->getLang('comments'); 854cded5e1SGerrit Uitslag } 865fc512fbSwikidesign 87479dd10fSwikidesign return '<a href="'.wl($id).$section.'" class="wikilink1" title="'.$id.$section.'">'. 885fc512fbSwikidesign $comment.'</a>'; 895fc512fbSwikidesign } 905fc512fbSwikidesign 915fc512fbSwikidesign /** 925fc512fbSwikidesign * Returns an array of pages with discussion sections, sorted by recent comments 934cded5e1SGerrit Uitslag * Note: also used for content by Feed Plugin 94e7ac9adaSGerrit Uitslag * 95e7ac9adaSGerrit Uitslag * @param string $ns 96e7ac9adaSGerrit Uitslag * @param null|int $num 97e7ac9adaSGerrit Uitslag * @param string|bool $skipEmpty 98e7ac9adaSGerrit Uitslag * @return array 995fc512fbSwikidesign */ 100e7ac9adaSGerrit Uitslag function getThreads($ns, $num = null, $skipEmpty = false) { 1015fc512fbSwikidesign global $conf; 1025fc512fbSwikidesign 1035fc512fbSwikidesign require_once(DOKU_INC.'inc/search.php'); 1045fc512fbSwikidesign 1057d4c577fSGerrit Uitslag $dir = utf8_encodeFN($conf['datadir'].($ns ? '/'.str_replace(':', '/', $ns): '')); 1065fc512fbSwikidesign 1075fc512fbSwikidesign // returns the list of pages in the given namespace and it's subspaces 1085fc512fbSwikidesign $items = array(); 1095d76f934SMichael Hamann search($items, $dir, 'search_allpages', array()); 1105fc512fbSwikidesign 1115fc512fbSwikidesign // add pages with comments to result 1125fc512fbSwikidesign $result = array(); 1135fc512fbSwikidesign foreach ($items as $item) { 1145fc512fbSwikidesign $id = ($ns ? $ns.':' : '').$item['id']; 1155fc512fbSwikidesign 1165fc512fbSwikidesign // some checks 1175fc512fbSwikidesign $perm = auth_quickaclcheck($id); 1185fc512fbSwikidesign if ($perm < AUTH_READ) continue; // skip if no permission 1195fc512fbSwikidesign $file = metaFN($id, '.comments'); 1205fc512fbSwikidesign if (!@file_exists($file)) continue; // skip if no comments file 1215fc512fbSwikidesign $data = unserialize(io_readFile($file, false)); 122264b7327Swikidesign $status = $data['status']; 1235644a1afSlupo49 $number = $data['number']; 1245644a1afSlupo49 1255644a1afSlupo49 if (!$status || (($status == 2) && (!$number))) continue; // skip if comments are off or closed without comments 1265644a1afSlupo49 if($skipEmpty == 'y' && $number == 0) continue; // skip if discussion is empty and flag is set 1275fc512fbSwikidesign 1285fc512fbSwikidesign $date = filemtime($file); 1295fc512fbSwikidesign $meta = p_get_metadata($id); 130ae836b78SMichael Hamann $result[$date.'_'.$id] = array( 1315fc512fbSwikidesign 'id' => $id, 132264b7327Swikidesign 'file' => $file, 1335fc512fbSwikidesign 'title' => $meta['title'], 1345fc512fbSwikidesign 'date' => $date, 1355fc512fbSwikidesign 'user' => $meta['creator'], 1365fc512fbSwikidesign 'desc' => $meta['description']['abstract'], 137fcb1bc77Swikidesign 'num' => $number, 138fcb1bc77Swikidesign 'comments' => $this->td($id, $number), 139264b7327Swikidesign 'status' => $status, 1405fc512fbSwikidesign 'perm' => $perm, 1415fc512fbSwikidesign 'exists' => true, 14273f66a3cSwikidesign 'anchor' => 'discussion__section', 1435fc512fbSwikidesign ); 1445fc512fbSwikidesign } 1455fc512fbSwikidesign 1465fc512fbSwikidesign // finally sort by time of last comment 1475fc512fbSwikidesign krsort($result); 1485fc512fbSwikidesign 1495fc512fbSwikidesign if (is_numeric($num)) $result = array_slice($result, 0, $num); 1505fc512fbSwikidesign 1515fc512fbSwikidesign return $result; 1525fc512fbSwikidesign } 1535fc512fbSwikidesign 1545fc512fbSwikidesign /** 1555fc512fbSwikidesign * Returns an array of recently added comments to a given page or namespace 1564cded5e1SGerrit Uitslag * Note: also used for content by Feed Plugin 157e7ac9adaSGerrit Uitslag * 158e7ac9adaSGerrit Uitslag * @param string $ns 159e7ac9adaSGerrit Uitslag * @param int|null $num 160e7ac9adaSGerrit Uitslag * @return array 1615fc512fbSwikidesign */ 1625fc512fbSwikidesign function getComments($ns, $num = NULL) { 1635fc512fbSwikidesign global $conf; 1645fc512fbSwikidesign 1655fc512fbSwikidesign $first = $_REQUEST['first']; 1665fc512fbSwikidesign if (!is_numeric($first)) $first = 0; 1675fc512fbSwikidesign 1685fc512fbSwikidesign if ((!$num) || (!is_numeric($num))) $num = $conf['recent']; 1695fc512fbSwikidesign 1705fc512fbSwikidesign $result = array(); 1715fc512fbSwikidesign $count = 0; 1725fc512fbSwikidesign 1735fc512fbSwikidesign if (!@file_exists($conf['metadir'].'/_comments.changes')) return $result; 1745fc512fbSwikidesign 1755fc512fbSwikidesign // read all recent changes. (kept short) 1765fc512fbSwikidesign $lines = file($conf['metadir'].'/_comments.changes'); 1775fc512fbSwikidesign 17855e1d144SMichael Hamann $seen = array(); //caches seen pages in order to skip them 1795fc512fbSwikidesign // handle lines 18055e1d144SMichael Hamann $line_num = count($lines); 18155e1d144SMichael Hamann for ($i = ($line_num - 1); $i >= 0; $i--) { 18255e1d144SMichael Hamann $rec = $this->_handleRecentComment($lines[$i], $ns, $seen); 1835fc512fbSwikidesign if ($rec !== false) { 1845fc512fbSwikidesign if (--$first >= 0) continue; // skip first entries 1855fc512fbSwikidesign $result[$rec['date']] = $rec; 1865fc512fbSwikidesign $count++; 1875fc512fbSwikidesign // break when we have enough entries 1885fc512fbSwikidesign if ($count >= $num) break; 1895fc512fbSwikidesign } 1905fc512fbSwikidesign } 1915fc512fbSwikidesign 1925fc512fbSwikidesign // finally sort by time of last comment 1935fc512fbSwikidesign krsort($result); 1945fc512fbSwikidesign 1955fc512fbSwikidesign return $result; 1965fc512fbSwikidesign } 1975fc512fbSwikidesign 1985fc512fbSwikidesign /* ---------- Changelog function adapted for the Discussion Plugin ---------- */ 1995fc512fbSwikidesign 2005fc512fbSwikidesign /** 2015fc512fbSwikidesign * Internal function used by $this->getComments() 2025fc512fbSwikidesign * 2035fc512fbSwikidesign * don't call directly 2045fc512fbSwikidesign * 2055fc512fbSwikidesign * @see getRecentComments() 2065fc512fbSwikidesign * @author Andreas Gohr <andi@splitbrain.org> 2075fc512fbSwikidesign * @author Ben Coburn <btcoburn@silicodon.net> 2085fc512fbSwikidesign * @author Esther Brunner <wikidesign@gmail.com> 209e7ac9adaSGerrit Uitslag * 210e7ac9adaSGerrit Uitslag * @param string $line 211e7ac9adaSGerrit Uitslag * @param string $ns 212e7ac9adaSGerrit Uitslag * @param array $seen 213e7ac9adaSGerrit Uitslag * @return array|bool 2145fc512fbSwikidesign */ 21555e1d144SMichael Hamann function _handleRecentComment($line, $ns, &$seen) { 2165fc512fbSwikidesign if (empty($line)) return false; //skip empty lines 2175fc512fbSwikidesign 2185fc512fbSwikidesign // split the line into parts 2195fc512fbSwikidesign $recent = parseChangelogLine($line); 2205fc512fbSwikidesign if ($recent === false) return false; 2215fc512fbSwikidesign 2225fc512fbSwikidesign $cid = $recent['extra']; 2235fc512fbSwikidesign $fullcid = $recent['id'].'#'.$recent['extra']; 2245fc512fbSwikidesign 2255fc512fbSwikidesign // skip seen ones 2265fc512fbSwikidesign if (isset($seen[$fullcid])) return false; 2275fc512fbSwikidesign 2285fc512fbSwikidesign // skip 'show comment' log entries 2295fc512fbSwikidesign if ($recent['type'] === 'sc') return false; 2305fc512fbSwikidesign 2315fc512fbSwikidesign // remember in seen to skip additional sights 2325fc512fbSwikidesign $seen[$fullcid] = 1; 2335fc512fbSwikidesign 2345fc512fbSwikidesign // check if it's a hidden page or comment 2355fc512fbSwikidesign if (isHiddenPage($recent['id'])) return false; 2365fc512fbSwikidesign if ($recent['type'] === 'hc') return false; 2375fc512fbSwikidesign 2385fc512fbSwikidesign // filter namespace or id 2395fc512fbSwikidesign if (($ns) && (strpos($recent['id'].':', $ns.':') !== 0)) return false; 2405fc512fbSwikidesign 2415fc512fbSwikidesign // check ACL 2425fc512fbSwikidesign $recent['perm'] = auth_quickaclcheck($recent['id']); 2435fc512fbSwikidesign if ($recent['perm'] < AUTH_READ) return false; 2445fc512fbSwikidesign 2455fc512fbSwikidesign // check existance 2465fc512fbSwikidesign $recent['file'] = wikiFN($recent['id']); 2475fc512fbSwikidesign $recent['exists'] = @file_exists($recent['file']); 2485fc512fbSwikidesign if (!$recent['exists']) return false; 2495fc512fbSwikidesign if ($recent['type'] === 'dc') return false; 2505fc512fbSwikidesign 2515fc512fbSwikidesign // get discussion meta file name 2522cbdac2eSwikidesign $data = unserialize(io_readFile(metaFN($recent['id'], '.comments'), false)); 2535fc512fbSwikidesign 2545fc512fbSwikidesign // check if discussion is turned off 2555fc512fbSwikidesign if ($data['status'] === 0) return false; 2565fc512fbSwikidesign 257*4dd9b9e2SMichael Hamann $parent_id = $cid; 258*4dd9b9e2SMichael Hamann // Check for the comment and all parents if they exist and are visible. 259*4dd9b9e2SMichael Hamann do { 260*4dd9b9e2SMichael Hamann $tcid = $parent_id; 261*4dd9b9e2SMichael Hamann 26255e1d144SMichael Hamann // check if the comment still exists 263*4dd9b9e2SMichael Hamann if (!isset($data['comments'][$tcid])) return false; 264*4dd9b9e2SMichael Hamann // check if the comment is visible 265*4dd9b9e2SMichael Hamann if ($data['comments'][$tcid]['show'] != 1) return false; 266*4dd9b9e2SMichael Hamann 267*4dd9b9e2SMichael Hamann $parent_id = $data['comments'][$tcid]['parent']; 268*4dd9b9e2SMichael Hamann } while ($parent_id && $parent_id != $tcid); 26955e1d144SMichael Hamann 2705fc512fbSwikidesign // okay, then add some additional info 2714cded5e1SGerrit Uitslag if (is_array($data['comments'][$cid]['user'])) { 2726046f25cSwikidesign $recent['name'] = $data['comments'][$cid]['user']['name']; 2734cded5e1SGerrit Uitslag } else { 2744cded5e1SGerrit Uitslag $recent['name'] = $data['comments'][$cid]['name']; 2754cded5e1SGerrit Uitslag } 2765fc512fbSwikidesign $recent['desc'] = strip_tags($data['comments'][$cid]['xhtml']); 277d8092064SMichael Hamann $recent['anchor'] = 'comment_'.$cid; 2785fc512fbSwikidesign 2795fc512fbSwikidesign return $recent; 2805fc512fbSwikidesign } 281e6b2f142Slupo49 282e7ac9adaSGerrit Uitslag /** 283e7ac9adaSGerrit Uitslag * @return bool 284e7ac9adaSGerrit Uitslag */ 285e6b2f142Slupo49 function isDiscussionMod() { 286e6b2f142Slupo49 global $USERINFO; 287e6b2f142Slupo49 $groups = trim($this->getConf('moderatorgroups')); 288e6b2f142Slupo49 289e6b2f142Slupo49 if(auth_ismanager()) return true; 290e6b2f142Slupo49 // Check if user is member of the moderator groups 291e6b2f142Slupo49 if(!empty($groups) && auth_isMember($groups, $_SERVER['REMOTE_USER'], (array)$USERINFO['grps'])) return true; 292e6b2f142Slupo49 293e6b2f142Slupo49 return false; 294e6b2f142Slupo49 } 2955fc512fbSwikidesign} 296530693fbSMichael Klier// vim:ts=4:sw=4:et:enc=utf-8: 297