This function will also sort the resulting list, if requested.
public static listTasks ( array $options = [] ) : Nag_Task | ||
$options | array | Options array: - altsortby: (string) The secondary sort field. Same values as sortdir. DEFAULT: altsortby pref is used. - completed: (integer) Which task to retrieve. A Nag::VIEW_* constant. DEFAULT: show_completed pref is used. - external: (boolean) Whether to include tasks from other applications too. DEFAULT: true. - include_history: (boolean) Autoload created/modified data from Horde_History. DEFAULT: true (Automatically load history data). - include_tags: (boolean) Autoload all tags. DEFAULT: false (Tags are lazy loaded as needed.) - sortby: (string) A Nag::SORT_* constant for the field to sort by. DEFAULT: sortby pref is used. - sortdir: (string) Direction of sort. NAG::SORT_ASCEND or NAG::SORT_DESCEND. DEFAULT: sortdir pref is used. - tasklists: (array) An array of tasklists to include. DEFAULT: Use $GLOBALS['display_tasklists']; |
return | Nag_Task | A list of the requested tasks. |
/** * Purge completed tasks that were completed before the configured date. * * @return boolean Whether any messages were purged from the mailbox. */ public function execute() { global $injector, $prefs; /* Get the current UNIX timestamp minus the number of days specified * in 'purge_completed_keep'. If a task has a timestamp prior to * this value, it will be deleted. */ $del_time = new Horde_Date($_SERVER['REQUEST_TIME'] - $prefs->getValue('purge_completed_keep') * 86400); $del_time = $del_time->timestamp(); $tasklists = Nag::listTasklists(true, Horde_Perms::DELETE, false); $tasks = Nag::listTasks(array('completed' => Nag::VIEW_COMPLETE, 'tasklists' => array_keys($tasklists))); $factory = $GLOBALS['injector']->getInstance('Nag_Factory_Driver'); $count = 0; $tasks->reset(); while ($task = $tasks->each()) { if ($task->completed_date && $task->completed_date < $del_time || !$task->completed_date && $task->modified && $task->modified->timestamp() < $del_time) { try { $factory->create($task->tasklist)->delete($task->id); ++$count; } catch (Nag_Exception $e) { Horde::log($e->getMessage(), 'ERR'); } } } $GLOBALS['notification']->push(sprintf(ngettext("Purging %d completed task.", "Purging %d completed tasks.", $count), $count), 'horde.message'); return true; }
/** * AJAX action: Return a task list. * * @return stdClass An object containing a tasklist in the tasks property. */ public function listTasks() { $options = array('include_history' => false); if ($this->vars->tasklist) { $options['tasklists'] = array($this->vars->tasklist); } $tasks = Nag::listTasks($options); $list = array(); $tasks->reset(); while ($task = $tasks->each()) { $list[] = $task->toJson(true); } $results = new stdClass(); $results->tasks = $list; return $results; }
/** * Const'r * * @param Horde_Form_Variables $vars The form variables. * @param string $title The form title. * * @return Nag_Form_Task */ public function __construct($vars, $title = '') { global $injector, $nag_shares, $prefs, $registry; parent::__construct($vars, $title); $user = $registry->getAuth(); $tasklist_enums = array(); foreach (Nag::listTasklists(false, Horde_Perms::SHOW, false) as $tl_id => $tl) { if (!$tl->hasPermission($user, Horde_Perms::EDIT)) { continue; } $tasklist_enums[$tl_id] = Nag::getLabel($tl); } $tasklist = $vars->get('tasklist_id'); if (empty($tasklist)) { reset($tasklist_enums); $tasklist = key($tasklist_enums); } $priorities = array(1 => '1 ' . _("(highest)"), 2 => 2, 3 => 3, 4 => 4, 5 => '5 ' . _("(lowest)")); $this->addHidden('', 'mobile', 'boolean', false); $this->addHidden('', 'task_id', 'text', false); $this->addHidden('', 'old_tasklist', 'text', false); $this->addHidden('', 'url', 'text', false); $this->addHidden('', 'uid', 'text', false); $this->addHidden('', 'owner', 'text', false); $this->addHidden('', 'list', 'text', false); $this->addHidden('', 'tab_name', 'text', false); $this->setSection(self::SECTION_GENERAL, _("General")); $this->addVariable(_("Name"), 'name', 'text', true); if (!$prefs->isLocked('default_tasklist') && count($tasklist_enums) > 1) { $v = $this->addVariable(_("Task List"), 'tasklist_id', 'enum', true, false, false, array($tasklist_enums)); if (!$vars->get('mobile')) { $v->setAction(Horde_Form_Action::factory('reload')); } } if (!$vars->get('mobile')) { $tasks = Nag::listTasks(array('tasklists' => array($tasklist), 'complete' => Nag::VIEW_FUTURE_INCOMPLETE, 'include_history' => false)); $task_enums = array('' => _("No parent task")); $tasks->reset(); while ($task = $tasks->each()) { if ($vars->get('task_id') == $task->id) { continue; } $task_enums[htmlspecialchars($task->id)] = str_repeat(' ', $task->indent * 4) . htmlspecialchars($task->name); } $v = $this->addVariable(_("Parent task"), 'parent', 'enum', false, false, false, array($task_enums)); $v->setOption('htmlchars', true); } $this->addVariable(_("Tags"), 'tags', 'Nag:NagTags', false); // Only display the delete button if this is an existing task and the // user has HORDE_PERMS::DELETE $share = $nag_shares->getShare($tasklist); $delete = $share->hasPermission($registry->getAuth(), Horde_Perms::DELETE) && $vars->get('task_id'); if (!$vars->get('mobile')) { $users = $share->listUsers(Horde_Perms::READ); $groups = $share->listGroups(Horde_Perms::READ); if (count($groups)) { $horde_group = $injector->getInstance('Horde_Group'); foreach ($groups as $group) { $users = array_merge($users, $horde_group->listUsers($group)); } } if (empty($GLOBALS['conf']['assignees']['allow_external'])) { $users = array_flip($users); if (count($users)) { foreach (array_keys($users) as $user) { $identity = $injector->getInstance('Horde_Core_Factory_Identity')->create($user); $fullname = $identity->getValue('fullname'); $users[$user] = strlen($fullname) ? $fullname : $user; } } $this->addVariable(_("Assignee"), 'assignee', 'enum', false, false, null, array($users, _("None"))); } else { $this->addVariable(_("Assignee"), 'assignee', 'Nag:NagContact', false); } } $this->addVariable(_("Private?"), 'private', 'boolean', false); $this->addVariable(_("Due By"), 'due', 'Nag:NagDue', false); if (!$vars->get('mobile')) { $this->addVariable(_("Delay Start Until"), 'start', 'Nag:NagStart', false); } $this->addVariable(_("Alarm"), 'alarm', 'Nag:NagAlarm', false); if (!$vars->get('mobile')) { $v = $this->addVariable(_("Notification"), 'methods', 'Nag:NagMethod', false); $v->setAction(Horde_Form_Action::factory('reload')); $v = $this->addVariable(_("Priority"), 'priority', 'enum', false, false, false, array($priorities)); $v->setDefault(3); $this->addVariable(_("Estimated Time"), 'estimate', 'number', false); $this->addVariable(_("Actual Time"), 'actual', 'number', false); $this->_completedVar = $this->addVariable(_("Completed?"), 'completed', 'boolean', false); $this->setSection(self::SECTION_RECUR, _("Recurrence")); $this->addVariable(_("Recurrence"), 'recurrence', 'Nag:NagRecurrence', false); } $this->setSection(self::SECTION_DESC, _("Description")); try { $description = Horde::callHook('description_help', array(), 'nag'); } catch (Horde_Exception_HookNotSet $e) { $description = ''; } $this->addVariable(_("Description"), 'desc', 'longtext', false, false, $description); $buttons = array(array('value' => _("Save"))); if ($delete) { $buttons[] = array('value' => _("Delete"), 'name' => 'deletebutton', 'class' => 'horde-delete'); } if (!$vars->get('task_id')) { $buttons[] = array('value' => _("Save and New"), 'name' => 'savenewbutton', 'class' => 'horde-create'); } if (Horde_Util::getFormData('have_search')) { $buttons[] = array('value' => _("Return to Search Results"), 'name' => 'search_return', 'class' => 'horde-button'); } $this->setButtons($buttons); }
/** */ protected function _content() { global $conf, $prefs, $registry; $html = ''; if (!empty($this->_params['show_alarms'])) { $messages = array(); try { $alarmList = Nag::listAlarms($_SERVER['REQUEST_TIME']); } catch (Nag_Exception $e) { return '<em>' . htmlspecialchars($e->getMessage()) . '</em>'; } foreach ($alarmList as $task) { $differential = $task->getNextDue()->timestamp() - $_SERVER['REQUEST_TIME']; $key = $differential; while (isset($messages[$key])) { $key++; } $viewurl = Horde::url('view.php', true)->add(array('task' => $task->id, 'tasklist' => $task->tasklist)); $link = $viewurl->link() . (!empty($task->name) ? htmlspecialchars($task->name) : _("[none]")) . '</a>'; if ($differential >= -60 && $differential < 60) { $messages[$key] = sprintf(_("%s is due now."), $link); } elseif ($differential >= 60) { $messages[$key] = sprintf(_("%s is due in %s"), $link, Nag::secondsToString($differential)); } } ksort($messages); foreach ($messages as $message) { $html .= '<tr><td class="control">' . Horde::img('alarm_small.png') . ' <strong>' . $message . '</strong></td></tr>'; } if (!empty($messages)) { $html .= '</table><br /><table cellspacing="0" width="100%" class="linedRow">'; } } $i = 0; try { $tasks = Nag::listTasks(array('tasklists' => isset($this->_params['show_tasklists']) ? $this->_params['show_tasklists'] : array_keys(Nag::listTasklists(false, Horde_Perms::READ)), 'completed' => empty($this->_params['show_completed']) ? Nag::VIEW_INCOMPLETE : Nag::VIEW_ALL, 'include_history' => false)); } catch (Nag_Exception $e) { return '<em>' . htmlspecialchars($e->getMessage()) . '</em>'; } $tasks->reset(); while ($task = $tasks->each()) { $due = $task->due ? $task->getNextDue() : null; // Only print tasks due in the past if the show_overdue flag is on. if ($due && $due->before($_SERVER['REQUEST_TIME']) && empty($this->_params['show_overdue'])) { continue; } if ($task->completed) { $class = 'closed'; } elseif ($due && $due->before($_SERVER['REQUEST_TIME'])) { $class = 'overdue'; } else { $class = ''; } $style = ' style="background-color:' . $task->backgroundColor() . ';color:' . $task->foregroundColor() . '"'; $html .= '<tr class="' . $class . '">'; if (!empty($this->_params['show_actions'])) { $taskurl = Horde::url('task.php', true)->add(array('task' => $task->id, 'tasklist' => $task->tasklist, 'url' => Horde::selfUrl(true))); $label = sprintf(_("Edit \"%s\""), $task->name); $html .= '<td width="1%"' . $style . '>' . $taskurl->copy()->add('actionID', 'modify_task')->link() . Horde::img('edit-sidebar-' . substr($task->foregroundColor(), 1) . '.png', $label) . '</a></td>'; if ($task->completed) { $html .= '<td width="1%">' . $style . '' . Horde::img('checked.png', _("Completed")) . '</td>'; } else { $label = sprintf(_("Complete \"%s\""), $task->name); $html .= '<td width="1%"' . $style . '>' . Horde::url($conf['urls']['pretty'] == 'rewrite' ? 't/complete' : 'task/complete.php')->add(array('task' => $task->id, 'tasklist' => $task->tasklist, 'url' => Horde::selfUrl(true)))->link() . Horde::img('unchecked.png', $label) . '</a></td>'; } } if (!empty($this->_params['show_pri'])) { $html .= '<td align="center"' . $style . '> ' . Nag::formatPriority($task->priority) . ' </td>'; } if (!empty($this->_params['show_tasklist'])) { $html .= '<td width="1%" class="nowrap"' . $style . '>' . htmlspecialchars(Nag::getLabel($GLOBALS['injector']->getInstance('Horde_Core_Factory_Share')->create()->getShare($task->tasklist))) . ' </td>'; } $html .= '<td' . $style . '>'; $viewurl = Horde::url('view.php', true)->add(array('task' => $task->id, 'tasklist' => $task->tasklist)); $html .= $task->treeIcons() . $viewurl->link(array('title' => $task->desc, 'style' => 'color:' . $task->foregroundColor())) . (!empty($task->name) ? htmlspecialchars($task->name) : _("[none]")) . '</a>'; if ($due && empty($task->completed) && !empty($this->_params['show_due'])) { $html .= ' (' . $due->strftime($prefs->getValue('date_format')) . ')'; } $html .= '</td>'; $html .= "</tr>\n"; } if (empty($html)) { return '<em>' . _("No tasks to display") . '</em>'; } return '<table cellspacing="0" width="100%" class="linedRow">' . $html . '</table>'; }
/** * @throws Nag_Exception */ public function download(Horde_Variables $vars) { global $display_tasklists, $injector, $registry; switch ($vars->actionID) { case 'export': $tasklists = $vars->get('exportList', $display_tasklists); if (!is_array($tasklists)) { $tasklists = array($tasklists); } /* Get the full, sorted task list. */ $tasks = Nag::listTasks(array('tasklists' => $tasklists, 'completed' => $vars->exportTasks, 'include_tags' => true, 'include_history' => false)); $tasks->reset(); switch ($vars->exportID) { case Horde_Data::EXPORT_CSV: $data = array(); while ($task = $tasks->each()) { $task = $task->toHash(); $task['desc'] = str_replace(',', '', $task['desc']); $task['tags'] = implode(',', $task['tags']); unset($task['complete_link'], $task['delete_link'], $task['edit_link'], $task['parent'], $task['task_id'], $task['tasklist_id'], $task['view_link'], $task['recurrence'], $task['methods']); foreach (array('start', 'due', 'completed_date') as $field) { if (!empty($task[$field])) { $date = new Horde_Date($task[$field]); $task[$field] = $date->format('c'); } } $data[] = $task; } $injector->getInstance('Horde_Core_Factory_Data')->create('Csv', array('cleanup' => array($this, 'cleanupData')))->exportFile(_("tasks.csv"), $data, true); exit; case Horde_Data::EXPORT_ICALENDAR: $iCal = new Horde_Icalendar(); $iCal->setAttribute('PRODID', '-//The Horde Project//Nag ' . $registry->getVersion() . '//EN'); while ($task = $tasks->each()) { $iCal->addComponent($task->toiCalendar($iCal)); } return array('data' => $iCal->exportvCalendar(), 'name' => _("tasks.ics"), 'type' => 'text/calendar'); } } }
/** * Lists active tasks as time objects. * * @param array $categories The time categories (from * listTimeObjectCategories) to list. * @param mixed $start The start date of the period. * @param mixed $end The end date of the period. */ public function listTimeObjects($categories, $start, $end) { $allowed_tasklists = Nag::listTasklists(false, Horde_Perms::READ); foreach ($categories as $tasklist) { if (!isset($allowed_tasklists[$tasklist])) { throw new Horde_Exception_PermissionDenied(); } } $timeobjects = array(); $start = new Horde_Date($start); $start_ts = $start->timestamp(); $end = new Horde_Date($end); $end_ts = $end->timestamp(); // List incomplete tasks. $tasks = Nag::listTasks(array('tasklists' => $categories, 'completed' => Nag::VIEW_INCOMPLETE, 'include_history' => false)); $tasks->reset(); while ($task = $tasks->each()) { // If there's no due date, it's not a time object. if (!$task->due || $task->due > $end_ts || !$task->recurs() && $task->due + 1 < $start_ts || $task->recurs() && $task->recurrence->getRecurEnd() && $task->recurrence->getRecurEnd()->timestamp() + 1 < $start_ts) { continue; } $due_date = date('Y-m-d\\TH:i:s', $task->due); $recurrence = null; if ($task->recurs()) { $recurrence = array('type' => $task->recurrence->getRecurType(), 'interval' => $task->recurrence->getRecurInterval(), 'end' => $task->recurrence->getRecurEnd(), 'count' => $task->recurrence->getRecurCount(), 'days' => $task->recurrence->getRecurOnDays(), 'exceptions' => $task->recurrence->getExceptions(), 'completions' => $task->recurrence->getCompletions()); } $timeobjects[$task->id] = array('id' => $task->id, 'title' => $task->name, 'description' => $task->desc, 'start' => $due_date, 'end' => $due_date, 'recurrence' => $recurrence, 'color' => $allowed_tasklists[$task->tasklist]->get('color'), 'owner' => $allowed_tasklists[$task->tasklist]->get('owner'), 'permissions' => $GLOBALS['nag_shares']->getPermissions($task->tasklist, $GLOBALS['registry']->getAuth()), 'variable_length' => false, 'params' => array('task' => $task->id, 'tasklist' => $task->tasklist), 'link' => Horde::url('view.php', true)->add(array('tasklist' => $task->tasklist, 'task' => $task->id)), 'edit_link' => Horde::url('task.php', true)->add(array('tasklist' => $task->tasklist, 'task' => $task->id, 'actionID' => 'modify_task')), 'delete_link' => Horde::url('task.php', true)->add(array('tasklist' => $task->tasklist, 'task' => $task->id, 'actionID' => 'delete_task')), 'ajax_link' => 'task:' . $task->tasklist . ':' . $task->id); } return $timeobjects; }
/** * Perform the search * * @param integer $page The page number * @param integer $perpage The number of results per page. * * @return Nag_Task */ protected function _search($page, $perpage) { global $injector, $prefs; if (!empty($this->_due)) { $parser = Horde_Date_Parser::factory(array('locale' => $GLOBALS['prefs']->getValue('language'))); $date = $parser->parse($this->_due[1]); $date->mday += $this->_due[0]; $date = $date->timestamp(); } else { $date = false; } // Get the full, sorted task list. $tasks = Nag::listTasks(array('tasklists' => $this->_tasklists, 'completed' => $this->_completed, 'include_history' => false)); if (!empty($this->_search)) { $pattern = '/' . preg_quote($this->_search, '/') . '/i'; } $search_results = new Nag_Task(); if (!empty($this->_tags)) { $tagged_tasks = $injector->getInstance('Nag_Tagger')->search($this->_tags, array('list' => $GLOBALS['display_tasklists'])); } $tasks->reset(); while ($task = $tasks->each()) { if (!empty($date)) { if (empty($task->due) || $task->due > $date) { continue; } } // If we have a search string and it doesn't match name|desc continue if (!empty($this->_search) && !($this->_mask & self::MASK_NAME && preg_match($pattern, $task->name)) && !($this->_mask & self::MASK_DESC && preg_match($pattern, $task->desc))) { continue; } // No tags to search? Add it to results. Otherwise, make sure it // has the requested tags. if (empty($this->_tags) || in_array($task->uid, $tagged_tasks)) { $search_results->add($task); } } // Now that we have filtered results, load all tags at once. $search_results->loadTags(); return $search_results; }
/** * Convert this tasklist to a hash. * * @return array A hash of tasklist properties. */ public function toHash() { $tasks = Nag::listTasks(array('tasklists' => $this->_share->getName(), 'include_history' => false)); $hash = array('name' => Nag::getLabel($this->_share), 'desc' => $this->_share->get('desc'), 'color' => $this->_share->get('color'), 'owner' => $this->_share->get('owner'), 'id' => $this->_share->getName(), 'count' => $tasks->count(), 'smart' => $this->_share->get('issmart') ? true : false, 'overdue' => $tasks->childrenOverdue()); return $hash; }
/** * Load the full, sorted task list. */ protected function _loadTasks($lists = null) { try { $this->_tasks = Nag::listTasks(array('tasklists' => $lists, 'include_tags' => true, 'completed' => $this->_vars->show_completed, 'include_history' => false)); } catch (Nag_Exception $e) { $GLOBALS['notification']->push($e, 'horde.error'); $this->_tasks = new Nag_Task(); } }