1<?php 2/** 3 * Task Plugin, tasks component: lists tasks of a given namespace 4 * 5 * @license GPL 2 (http://www.gnu.org/licenses/gpl.html) 6 * @author Esther Brunner <wikidesign@gmail.com> 7 */ 8 9class syntax_plugin_task_tasks extends DokuWiki_Syntax_Plugin { 10 protected $helper = NULL; 11 12 /** 13 * Constructor. Loads helper plugin. 14 */ 15 public function __construct() { 16 $this->helper = plugin_load('helper', 'task'); 17 } 18 19 function getType() { return 'substition'; } 20 function getPType() { return 'block'; } 21 function getSort() { return 306; } 22 23 function connectTo($mode) { 24 $this->Lexer->addSpecialPattern('\{\{tasks>.+?\}\}', $mode, 'plugin_task_tasks'); 25 } 26 27 function handle($match, $state, $pos, Doku_Handler $handler) { 28 global $ID; 29 30 $match = substr($match, 8, -2); // strip {{topic> from start and }} from end 31 list($match, $flags) = explode('&', $match, 2); 32 $flags = explode('&', $flags); 33 list($match, $refine) = explode(' ', $match, 2); 34 list($ns, $filter) = explode('?', $match, 2); 35 36 if (($ns == '*') || ($ns == ':')) $ns = ''; 37 elseif ($ns == '.') $ns = getNS($ID); 38 else $ns = cleanID($ns); 39 40 return array($ns, $filter, $flags, $refine); 41 } 42 43 function render($mode, Doku_Renderer $renderer, $data) { 44 global $conf; 45 46 list($ns, $filter, $flags, $refine) = $data; 47 48 if (!$filter || ($filter == 'select')) { 49 $select = true; 50 $filter = trim($_REQUEST['filter']); 51 } 52 $filter = strtolower($filter); 53 $filters = $this->_viewFilters(); 54 if (!in_array($filter, $filters)) $filter = 'open'; 55 if(isset($_REQUEST['view_user'])) $user = $_REQUEST['view_user']; 56 57 if ($this->helper) $pages = $this->helper->getTasks($ns, NULL, $filter, $user); 58 59 // use tag refinements? 60 if ($refine) { 61 if (plugin_isdisabled('tag') || (!$tag = plugin_load('helper', 'tag'))) { 62 msg('The Tag Plugin must be installed to use tag refinements.', -1); 63 } else { 64 $pages = $tag->tagRefine($pages, $refine); 65 } 66 } 67 68 if(!$pages) { 69 if($mode != 'xhtml') return true; 70 $renderer->nocache(); 71 if($select) $renderer->doc .= $this->_viewMenu($filter); 72 if(auth_quickaclcheck($ns.':*') >= AUTH_CREATE) { 73 if(!in_array('noform', $flags)) { 74 if ($this->helper) $renderer->doc .= $this->helper->_newTaskForm($ns); 75 } 76 } 77 return true; // nothing to display 78 } 79 80 // prepare pagination 81 $c = count($pages); 82 $perpage = ($conf['recent'] != 0) ? $conf['recent'] : 20; // prevent division by zero 83 if ($c > $perpage) { 84 $numOfPages = ceil($c / $perpage); 85 $first = $_REQUEST['first']; 86 if (!is_numeric($first)) $first = 0; 87 $currentPage = round($first / $perpage) + 1; 88 $pages = array_slice($pages, $first, $perpage); 89 } 90 91 if ($mode == 'xhtml') { 92 93 // prevent caching to ensure content is always fresh 94 $renderer->nocache(); 95 96 // show form to create a new task? 97 $perm_create = (auth_quickaclcheck($ns.':*') >= AUTH_CREATE); 98 if($perm_create && ($this->getConf('tasks_formposition') == 'top')) { 99 if(!in_array('noform', $flags)) { 100 if ($this->helper) $renderer->doc .= $this->helper->_newTaskForm($ns); 101 } 102 } 103 104 // let Pagelist Plugin do the work for us 105 if (plugin_isdisabled('pagelist') 106 || (!$pagelist = plugin_load('helper', 'pagelist'))) { 107 msg('The Pagelist Plugin must be installed for task lists.', -1); 108 return false; 109 } 110 111 // show view filter popup if not 112 if ($select) $renderer->doc .= $this->_viewMenu($filter); 113 114 // prepare pagelist columns 115 $pagelist->header['page'] = $this->getLang('task'); 116 $pagelist->header['date'] = str_replace(' ', ' ', $this->getLang('date')); 117 $pagelist->header['user'] = str_replace(' ', ' ', $this->getLang('user')); 118 $pagelist->column['date'] = $this->getConf('datefield'); 119 $pagelist->column['user'] = true; 120 $pagelist->setFlags($flags); 121 $pagelist->addColumn('task', 'status'); 122 123 // output list 124 $pagelist->startList(); 125 if($this->getConf('tasks_newestfirst')) { 126 $pages = array_reverse($pages); 127 } 128 foreach ($pages as $page) { 129 $pagelist->addPage($page); 130 } 131 $renderer->doc .= $pagelist->finishList(); 132 $renderer->doc .= $this->_paginationLinks($numOfPages, $currentPage, $filter); 133 134 // show form to create a new task? 135 if($perm_create && ($this->getConf('tasks_formposition') == 'bottom')) { 136 if(!in_array('noform', $flags)) { 137 if ($this->helper) $renderer->doc .= $this->helper->_newTaskForm($ns); 138 } 139 } 140 141 return true; 142 143 // for metadata renderer 144 } elseif ($mode == 'metadata') { 145 foreach ($pages as $page) { 146 $renderer->meta['relation']['references'][$page['id']] = true; 147 } 148 149 return true; 150 } 151 return false; 152 } 153 154/* ---------- (X)HTML Output Functions ---------- */ 155 156 /** 157 * Show a popup to select the task view filter. 158 * Just forwards call to the old or new function. 159 */ 160 function _viewMenu($filter) { 161 if (class_exists('dokuwiki\Form\Form')) { 162 return $this->_viewMenuNew($filter); 163 } else { 164 return $this->_viewMenuOld($filter); 165 } 166 } 167 168 /** 169 * Show a popup to select the task view filter. 170 * This is the new version using class dokuwiki\Form\Form. 171 * 172 * @see _viewMenu 173 */ 174 function _viewMenuNew($filter) { 175 global $ID, $lang; 176 177 $options = $this->_viewFilters(); 178 179 $form = new dokuwiki\Form\Form(array('id' => 'task__changeview_form')); 180 $pos = 1; 181 182 $form->addHTML('<label class="simple">', $pos++); 183 $form->addHTML('<span>'.$this->getLang('view').'</span>', $pos++); 184 185 // Set hidden fields 186 $form->setHiddenField ('id', $ID); 187 $form->setHiddenField ('do', 'show'); 188 189 // Select status from drop down list 190 $dropDownOptions = array(); 191 $selected = NULL; 192 $value = 0; 193 foreach ($options as $option) { 194 if ($filter == $option) { 195 $selected = $option.' '; 196 } 197 $dropDownOptions [$option.' '] = $this->getLang('view_'.$option); 198 } 199 $input = $form->addDropdown('filter', $dropDownOptions, NULL, $pos++); 200 $input->val($selected); 201 202 $form->addHTML('</label>', $pos++); 203 204 if(isset($_SERVER['REMOTE_USER'])) { 205 $form->addHTML('<label class="simple"><span>'.$this->getLang('view_user').':</span>', $pos++); 206 $input = $form->addCheckbox('view_user', NULL, $pos++); 207 $input->attr('value', $_SERVER['REMOTE_USER']); 208 if ($_REQUEST['view_user']) { 209 $input->attr('checked', 'checked'); 210 } 211 $form->addHTML('</label>', $pos++); 212 } 213 214 // Add button 215 $form->addButton(NULL, $this->getLang('btn_refresh'), $pos++); 216 217 $ret = '<div class="task_viewmenu">'; 218 $ret .= $form->toHTML(); 219 $ret .= '</div>'; 220 221 return $ret; 222 } 223 224 /** 225 * Show a popup to select the task view filter. 226 * Old function generating all HTML on its own. 227 * 228 * @see _viewMenu 229 */ 230 function _viewMenuOld($filter) { 231 global $ID, $lang; 232 233 $options = $this->_viewFilters(); 234 235 $ret = '<div class="task_viewmenu">'; 236 $ret .= '<form id="task__changeview_form" method="post" action="'.script().'" accept-charset="'.$lang['encoding'].'">'; 237 $ret .= '<label class="simple">'; 238 $ret .= '<span>'.$this->getLang('view').'</span>'; 239 $ret .= '<input type="hidden" name="id" value="'.$ID.'" />'; 240 $ret .= '<input type="hidden" name="do" value="show" />'; 241 $ret .= '<select name="filter" size="1" class="edit">'; 242 243 foreach ($options as $option) { 244 $ret .= '<option value="'.$option.'"'; 245 if ($filter == $option) $ret .= ' selected="selected"'; 246 $ret .= '>'.$this->getLang('view_'.$option).'</option>'; 247 } 248 249 $ret .= '</select>'; 250 $ret .= '</label>'; 251 252 if(isset($_SERVER['REMOTE_USER'])) { 253 $ret .= '<label class="simple"><span>'.$this->getLang('view_user').':</span>'; 254 $ret .= '<input type="checkbox" name="view_user" value="' . $_SERVER['REMOTE_USER'] . '"'; 255 $ret .= ($_REQUEST['view_user']) ? ' checked="checked"' : ''; 256 $ret .= '/></label>'; 257 } 258 259 $ret .= '<input class="button" type="submit" value="'.$this->getLang('btn_refresh').'" />'; 260 $ret .= '</form></div>'; 261 262 return $ret; 263 } 264 265 /** 266 * Returns an array of available view filters for the task list 267 */ 268 function _viewFilters() { 269 if (!$_SERVER['REMOTE_USER']) $filters = array('all', 'open', 'done'); 270 else $filters = array('all', 'open', 'new', 'done', 'my', 'rejected', 'started', 'accepted', 'verified'); 271 if ($this->getConf('datefield')) { 272 $filters[] = 'due'; 273 $filters[] = 'overdue'; 274 } 275 return $filters; 276 } 277 278 /** 279 * Returns pagination links if more than one page 280 */ 281 function _paginationLinks($num, $cur, $filter) { 282 global $ID, $conf; 283 284 if (!is_numeric($num) || ($num < 2)) return ''; 285 $perpage = ($conf['recent'] != 0) ? $conf['recent'] : 20; // prevent division by zero 286 287 $ret = array(); 288 for ($i = 1; $i <= $num; $i++) { 289 if ($i == $cur) { 290 $ret[] = '<strong>'.$i.'</strong>'; 291 } else { 292 $opt = array(); 293 $opt['first'] = $perpage * ($i - 1); 294 $opt['filter'] = $filer; 295 if(isset($_REQUEST['view_user'])) { 296 $user = array(); 297 $user['id'] = $_REQUEST['view_user']; 298 if($this->helper->_isResponsible($user)) { 299 $opt['view_user'] = $_REQUEST['view_user']; 300 } 301 } 302 $ret[] = '<a href="'.wl($ID, $opt).'" class="wikilink1" title="'.$i.'">'.$i.'</a>'; 303 } 304 } 305 return '<div class="centeralign">'.DOKU_LF. 306 join(' | ', $ret).DOKU_LF. 307 '</div>'.DOKU_LF; 308 } 309} 310// vim:et:ts=4:sw=4:enc=utf-8: 311