/** * Helper method for getting only a slice of the total tasks in this list. * * @param integer $page The starting page. * @param integer $perpage The count of tasks per page. * * @return Nag_Task The resulting task list. */ public function getSlice($page = 0, $perpage = null) { $this->reset(); // Position at start task $start = $page * (empty($perpage) ? 0 : $perpage); $count = 0; while ($count < $start) { if (!$this->each()) { return new Nag_Task(); } ++$count; } $count = 0; $results = new Nag_Task(); $max = empty($perpage) ? $this->count() - $start : $perpage; while ($count < $max) { if ($next = $this->each()) { $results->add($next); ++$count; } else { $count = $max; } } $results->process(); return $results; }
/** * Retrieves the current user's task list from storage. * * This function will also sort the resulting list, if requested. * * @param arary $options 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. */ public static function listTasks(array $options = array()) { global $prefs, $registry; // Prevent null tasklists value from obscuring the default value. if (array_key_exists('tasklists', $options) && empty($options['tasklists'])) { unset($options['tasklists']); } $options = array_merge(array('sortby' => $prefs->getValue('sortby'), 'sortdir' => $prefs->getValue('sortdir'), 'altsortby' => $prefs->getValue('altsortby'), 'tasklists' => $GLOBALS['display_tasklists'], 'completed' => $prefs->getValue('show_completed'), 'include_tags' => false, 'external' => true, 'include_history' => true), $options); if (!is_array($options['tasklists'])) { $options['tasklists'] = array($options['tasklists']); } $tasks = new Nag_Task(); foreach ($options['tasklists'] as $tasklist) { $storage = $GLOBALS['injector']->getInstance('Nag_Factory_Driver')->create($tasklist); // Retrieve the tasklist from storage. $storage->retrieve($options['completed'], $options['include_history']); $tasks->mergeChildren($storage->tasks->children); } // Process all tasks. $tasks->process(); if ($options['external'] && ($apps = @unserialize($prefs->getValue('show_external'))) && is_array($apps)) { foreach ($apps as $app) { // We look for registered apis that support listAs(taskHash). if ($app == 'nag' || !$registry->hasMethod('getListTypes', $app)) { continue; } try { $types = $registry->callByPackage($app, 'getListTypes'); } catch (Horde_Exception $e) { continue; } if (empty($types['taskHash'])) { continue; } try { $newtasks = $registry->callByPackage($app, 'listAs', array('taskHash')); foreach ($newtasks as $task) { if (!isset($task['priority'])) { $task['priority'] = 3; } $task['tasklist_id'] = '**EXTERNAL**'; $task['tasklist_name'] = $registry->get('name', $app); $task = new Nag_Task(null, $task); if ($options['completed'] == Nag::VIEW_INCOMPLETE && ($task->completed || $task->start > $_SERVER['REQUEST_TIME']) || $options['completed'] == Nag::VIEW_COMPLETE && !$task->completed || $options['completed'] == Nag::VIEW_FUTURE && ($task->completed || !$task->start || $task->start < $_SERVER['REQUEST_TIME']) || $options['completed'] == Nag::VIEW_FUTURE_INCOMPLETE && $task->completed) { continue; } $tasks->add($task); } } catch (Horde_Exception $e) { Horde::log($e); } } } // Sort the array. $tasks->sort($options['sortby'], $options['sortdir'], $options['altsortby']); // Preload tags if requested. if ($options['include_tags']) { $tasks->loadTags(); } return $tasks; }
/** * 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()) { // Need to empty the children since they might not be in the results $task = clone $task; $task->orphan(); 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 try to maintain parent/child relationships when they are both // in the result set. $search_results->reset(); $search_results_copy = clone $search_results; $processed_results = new Nag_Task(); while ($result = $search_results_copy->each()) { if ($result->parent_id && ($parent_task = $search_results->hasTask($result->parent_id))) { $parent_task->add($result, true); $processed_results->add($parent_task, true); } else { $result->parent_id = ''; $processed_results->add($result); } } // Now that we have filtered results, load all tags at once. $processed_results->loadTags(); $processed_results->process(); return $processed_results; }