public function execute() { if ($this->_vars->get('submitbutton') == _("Cancel")) { Horde::url('list.php', true)->redirect(); } Nag::deleteTasklist($this->_tasklist); }
/** * 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; }
/** * Add base javascript variables to the page. */ protected function _addBaseVars() { global $page_output, $prefs; // Nag::VIEW_* constant switch ($prefs->getValue('show_completed')) { case Nag::VIEW_INCOMPLETE: $show_completed = 'incomplete'; break; case Nag::VIEW_ALL: $show_completed = 'all'; break; case Nag::VIEW_COMPLETE: $show_completed = 'complete'; break; case Nag::VIEW_FUTURE: $show_completed = 'future'; break; case Nag::VIEW_FUTURE_INCOMPLETE: $show_completed = 'future-incomplete'; break; } // Tasklists. Needed in case we deep link to an existing list. $lists = Nag::listTasklists(); $tasklists = array(); foreach ($lists as $name => $list) { $task = new Nag_Tasklist($list); $tasklists[$name] = $task->toHash(); } $code = array('conf' => array('showCompleted' => $show_completed, 'icons' => array('completed' => strval(Horde_Themes::img('checked.png')), 'uncompleted' => strval(Horde_Themes::img('unchecked.png')), 'smartlist' => strval(Horde_Themes::img('smart.png')), 'tasklist' => strval(Horde_Themes::img('tasklists.png')))), 'strings' => array('all' => _("All Tasks"), 'newTask' => _("New Task")), 'tasklists' => $tasklists); $page_output->addInlineJsVars(array('var Nag' => $code), array('top' => true)); }
/** * Copyright 2001-2016 Horde LLC (http://www.horde.org/) * * See the enclosed file COPYING for license information (GPL). If you * did not receive this file, see http://www.horde.org/licenses/gpl. * * @author Jon Parise <*****@*****.**> * @author Jan Schneider <*****@*****.**> */ function _delete($task_id, $tasklist_id) { global $injector, $nag_shares, $notification, $registry; if (!empty($task_id)) { try { $task = Nag::getTask($tasklist_id, $task_id); $task->loadChildren(); try { $share = $nag_shares->getShare($tasklist_id); } catch (Horde_Share_Exception $e) { throw new Nag_Exception($e); } if (!$share->hasPermission($registry->getAuth(), Horde_Perms::DELETE)) { $notification->push(_("Access denied deleting task."), 'horde.error'); } else { $storage = $injector->getInstance('Nag_Factory_Driver')->create($tasklist_id); try { $storage->delete($task_id); } catch (Nag_Exception $e) { $notification->push(sprintf(_("There was a problem deleting %s: %s"), $task->name, $e->getMessage()), 'horde.error'); } $notification->push(sprintf(_("Deleted %s."), $task->name), 'horde.success'); } } catch (Nag_Exception $e) { $notification->push(sprintf(_("Error deleting task: %s"), $e->getMessage()), 'horde.error'); } } /* Return to the last page or to the task list. */ if ($url = Horde_Util::getFormData('url')) { header('Location: ' . $url); exit; } Horde::url('list.php', true)->redirect(); }
/** */ public function result($task, $tasklist) { global $nag_shares, $notification, $registry; try { $share = $nag_shares->getShare($tasklist); $task = Nag::getTask($tasklist, $task); if (!$share->hasPermission($registry->getAuth(), Horde_Perms::EDIT)) { $result = array('error' => 'permission denied'); $notification->push(_("Access denied completing this task."), 'horde.error'); } else { $wasCompleted = $task->completed; $task->toggleComplete(); $task->save(); if ($task->completed) { $result = array('data' => 'complete'); $notification->push(sprintf(_("Completed %s."), $task->name), 'horde.success'); } elseif (!$wasCompleted) { $result = array('data' => 'incomplete'); $notification->push(sprintf(_("%s is still incomplete."), $task->name), 'horde.success'); } else { $result = array('data' => 'incomplete'); $notification->push(sprintf(_("%s is now incomplete."), $task->name), 'horde.success'); } } } catch (Exception $e) { $result = array('error' => $e->getMessage()); $notification->push(sprintf(_("There was a problem completing %s: %s"), $task->name, $e->getMessage()), 'horde.error'); } return $result; }
public function execute() { $info = array(); foreach (array('name', 'color', 'description', 'system') as $key) { $info[$key] = $this->_vars->get($key); } return Nag::addTasklist($info); }
/** * Ensure the share system has a default tasklist share for the current user * if the default share feature is activated. * * @return string|NULL The id of the new default share or NULL if no share * was created. */ public function ensureDefaultShare() { /* If the user doesn't own a task list, create one. */ if (!empty($this->_params['auto_create']) && $this->_user && !count(Nag::listTasklists(true))) { $share = $this->_shares->newShare($this->_user, strval(new Horde_Support_Randomid()), $this->_getDefaultShareName()); $share->set('color', Nag::randomColor()); $this->_prepareDefaultShare($share); $this->_shares->addShare($share); return $share->getName(); } }
public function getInfo(&$vars, &$var, &$info) { $due_type = $vars->get('due_type'); $due = $vars->get('due'); if (is_array($due)) { $due_date = !empty($due['date']) ? $due['date'] : null; $due_time = !empty($due['time']) ? $due['time'] : null; $due_dt = Nag::parseDate("{$due_date} {$due_time}"); $due = $due_dt->timestamp(); } $info = strcasecmp($due_type, 'none') ? $due : 0; }
public function getInfo(&$vars, &$var, &$info) { $start_type = $vars->get('start_date'); $start = $vars->get('start'); if (is_array($start)) { if (empty($start['date'])) { $start = null; } else { $start_dt = Nag::parseDate($start['date'], false); $start = $start_dt->timestamp(); } } $info = strcasecmp($start_type, 'none') ? $start : 0; }
public function execute() { switch ($this->_vars->submitbutton) { case _("Save"): $info = array(); foreach (array('name', 'color', 'description', 'system') as $key) { $info[$key] = $this->_vars->get($key); } Nag::updateTasklist($this->_tasklist, $info); break; case _("Delete"): Horde::url('tasklists/delete.php')->add('t', $this->_vars->t)->redirect(); break; case _("Cancel"): Horde::url('list.php', true)->redirect(); break; } }
public function processRequest(Horde_Controller_Request $request, Horde_Controller_Response $response) { global $nag_shares, $prefs; $vars = Horde_Variables::getDefaultVariables(); $registry = $this->getInjector()->getInstance('Horde_Registry'); $notification = $this->getInjector()->getInstance('Horde_Notification'); $form = new Nag_Form_Task($vars, $vars->get('task_id') ? sprintf(_("Edit: %s"), $vars->get('name')) : _("New Task")); if (!$form->validate($vars)) { // Hideous $_REQUEST['actionID'] = 'task_form'; require NAG_BASE . '/task.php'; exit; } $form->getInfo($vars, $info); // Check if we are here due to a search_return push. if ($vars->search_return) { Horde::url('list.php', true)->add(array('actionID' => 'search_return', 'list' => $vars->list, 'tab_name' => $vars->tab_name))->redirect(); } // Check if we are here due to a deletebutton push if ($vars->deletebutton) { try { $share = $nag_shares->getShare($info['old_tasklist']); } catch (Horde_Share_Exception $e) { $notification->push(sprintf(_("Access denied deleting task: %s"), $e->getMessage()), 'horde.error'); Horde::url('list.php', true)->redirect(); } if (!$share->hasPermission($registry->getAuth(), Horde_Perms::DELETE)) { $notification->push(_("Access denied deleting task"), 'horde.error'); Horde::url('list.php', true)->redirect(); } $storage = $this->getInjector()->getInstance('Nag_Factory_Driver')->create($info['old_tasklist']); try { $storage->delete($info['task_id']); } catch (Nag_Exception $e) { $notification->push(sprintf(_("Error deleting task: %s"), $e->getMessage()), 'horde.error'); Horde::url('list.php', true)->redirect(); } $notification->push(_("Task successfully deleted"), 'horde.success'); Horde::url('list.php', true)->redirect(); } if ($prefs->isLocked('default_tasklist') || count(Nag::listTasklists(false, Horde_Perms::EDIT, false)) <= 1) { $info['tasklist_id'] = $info['old_tasklist'] = Nag::getDefaultTasklist(Horde_Perms::EDIT); } try { $share = $nag_shares->getShare($info['tasklist_id']); } catch (Horde_Share_Exception $e) { $notification->push(sprintf(_("Access denied saving task: %s"), $e->getMessage()), 'horde.error'); Horde::url('list.php', true)->redirect(); } if (!$share->hasPermission($registry->getAuth(), Horde_Perms::EDIT)) { $notification->push(_("Access denied saving task to this task list."), 'horde.error'); Horde::url('list.php', true)->redirect(); } /* If a task id is set, we're modifying an existing task. Otherwise, * we're adding a new task with the provided attributes. */ if (!empty($info['task_id']) && !empty($info['old_tasklist'])) { $storage = $this->getInjector()->getInstance('Nag_Factory_Driver')->create($info['old_tasklist']); $info['tasklist'] = $info['tasklist_id']; $result = $storage->modify($info['task_id'], $info); } else { /* Check permissions. */ $perms = $this->getInjector()->getInstance('Horde_Core_Perms'); if ($perms->hasAppPermission('max_tasks') !== true && $perms->hasAppPermission('max_tasks') <= Nag::countTasks()) { Horde::url('list.php', true)->redirect(); } /* Creating a new task. */ $storage = $this->getInjector()->getInstance('Nag_Factory_Driver')->create($info['tasklist_id']); // These must be unset since the form sets them to NULL unset($info['owner']); unset($info['uid']); try { $newid = $storage->add($info); } catch (Nag_Exception $e) { $notification->push(sprintf(_("There was a problem saving the task: %s."), $e->getMessage()), 'horde.error'); Horde::url('list.php', true)->redirect(); } } $notification->push(sprintf(_("Saved %s."), $info['name']), 'horde.success'); /* Return to the last page or to the task list. */ if ($vars->savenewbutton) { $url = Horde::url('task.php', true)->add(array('actionID' => 'add_task', 'tasklist_id' => $info['tasklist_id'], 'parent' => $info['parent'])); } else { $url = Horde_Util::getFormData('url', (string) Horde::url('list.php', true)); $url = Horde::url($url, true); } $response->setRedirectUrl($url); }
/** * Sends out iTip task notification to the assignee. * * Can be used to send task invitations, updates, and cancellations. * * @param Nag_Task $task The task in question. * @param Horde_Notification_Handler $notification * A notification object used to show result status. * @param integer $action * The type of notification to send. One of the Nag::ITIP_* values. * @param Horde_Date $instance * If cancelling a single instance of a recurring task, the date of * this instance. * @param string $range The range parameter if this is a recurring event. * Possible values are self::RANGE_THISANDFUTURE */ public static function sendITipNotifications(Nag_Task $task, Horde_Notification_Handler $notification, $action, Horde_Date $instance = null, $range = null) { global $injector, $registry, $nag_shares; if (!$task->assignee) { return; } $ident = $injector->getInstance('Horde_Core_Factory_Identity')->create($task->creator); if (!$ident->getValue('from_addr')) { $notification->push(sprintf(_("You do not have an email address configured in your Personal Information Preferences. You must set one %shere%s before event notifications can be sent."), $registry->getServiceLink('prefs', 'kronolith')->add(array('app' => 'horde', 'group' => 'identities'))->link(), '</a>'), 'horde.error', array('content.raw')); return; } // Generate image mime part first and only once, because we // need the Content-ID. $image = self::getImagePart('big_invitation.png'); $share = $nag_shares->getShare($task->tasklist); $view = new Horde_View(array('templatePath' => NAG_TEMPLATES . '/itip')); new Horde_View_Helper_Text($view); $view->identity = $ident; $view->task = $task; $view->imageId = $image->getContentId(); $email = Nag::getUserEmail($task->assignee); if (strpos($email, '@') === false) { continue; } /* Determine all notification-specific strings. */ $method = 'REQUEST'; switch ($action) { case self::ITIP_CANCEL: /* Cancellation. */ $method = 'CANCEL'; $filename = 'task-cancellation.ics'; $view->subject = sprintf(_("Cancelled: %s"), $task->name); if (empty($instance)) { $view->header = sprintf(_("%s has cancelled \"%s\"."), $ident->getName(), $task->name); } else { $view->header = sprintf(_("%s has cancelled an instance of the recurring \"%s\"."), $ident->getName(), $task->name); } break; case self::ITIP_UPDATE: if (!empty($task->organizer) && $task->organizer != Nag::getUserEmail($task->creator)) { // Sending a progress update. $method = 'REPLY'; } else { $method = 'UPDATE'; } case self::ITIP_REQUEST: default: if (empty($task->status) || $task->status == self::RESPONSE_NONE) { /* Invitation. */ $filename = 'task-invitation.ics'; $view->subject = $task->name; $view->header = sprintf(_("%s wishes to make you aware of \"%s\"."), $ident->getName(), $task->name); } else { $filename = 'task-update.ics'; $view->subject = sprintf(_("Updated: %s."), $task->name); $view->header = sprintf(_("%s wants to notify you about changes of \"%s\"."), $ident->getName(), $task->name); } break; } $view->attendees = $email; $view->organizer = empty($task->organizer) ? $registry->convertUserName($task->creator, false) : $task->organizer; /* Build the iCalendar data */ $iCal = new Horde_Icalendar(); $iCal->setAttribute('METHOD', $method); $vevent = $task->toiCalendar($iCal); $iCal->addComponent($vevent); /* text/calendar part */ $ics = new Horde_Mime_Part(); $ics->setType('text/calendar'); $ics->setContents($iCal->exportvCalendar()); $ics->setName($filename); $ics->setContentTypeParameter('METHOD', $method); $ics->setCharset('UTF-8'); $ics->setEOL("\r\n"); /* application/ics part */ $ics2 = clone $ics; $ics2->setType('application/ics'); /* multipart/mixed part */ $multipart = new Horde_Mime_Part(); $multipart->setType('multipart/mixed'); $inner = self::buildMimeMessage($view, 'notification', $image); $inner->addPart($ics); $multipart->addPart($inner); $multipart->addPart($ics2); $recipient = $method != 'REPLY' ? new Horde_Mail_Rfc822_Address($email) : new Horde_Mail_Rfc822_Address($task->organizer); $mail = new Horde_Mime_Mail(array('Subject' => $view->subject, 'To' => $recipient, 'From' => $ident->getDefaultFromAddress(true), 'User-Agent' => 'Nag ' . $registry->getVersion())); $mail->setBasePart($multipart); try { $mail->send($injector->getInstance('Horde_Mail')); $notification->push(sprintf(_("The task request notification to %s was successfully sent."), $recipient), 'horde.success'); } catch (Horde_Mime_Exception $e) { $notification->push(sprintf(_("There was an error sending a task request notification to %s: %s"), $recipient, $e->getMessage(), $e->getCode()), 'horde.error'); } }
/** * Returns an alarm hash of this task suitable for Horde_Alarm. * * @param string $user The user to return alarms for. * @param Prefs $prefs A Prefs instance. * * @return array Alarm hash or null. */ public function toAlarm($user = null, $prefs = null) { if (empty($this->alarm) || $this->completed) { return; } if (empty($user)) { $user = $GLOBALS['registry']->getAuth(); } if (empty($prefs)) { $prefs = $GLOBALS['prefs']; } $methods = !empty($this->methods) ? $this->methods : @unserialize($prefs->getValue('task_alarms')); if (!$methods) { $methods = array(); } if (isset($methods['notify'])) { $methods['notify']['show'] = array('__app' => $GLOBALS['registry']->getApp(), 'task' => $this->id, 'tasklist' => $this->tasklist); $methods['notify']['ajax'] = 'task:' . $this->tasklist . ':' . $this->id; if (!empty($methods['notify']['sound'])) { if ($methods['notify']['sound'] == 'on') { // Handle boolean sound preferences; $methods['notify']['sound'] = (string) Horde_Themes::sound('theetone.wav'); } else { // Else we know we have a sound name that can be // served from Horde. $methods['notify']['sound'] = (string) Horde_Themes::sound($methods['notify']['sound']); } } } if (isset($methods['mail'])) { $image = Nag::getImagePart('big_alarm.png'); $view = new Horde_View(array('templatePath' => NAG_TEMPLATES . '/alarm', 'encoding' => 'UTF-8')); new Horde_View_Helper_Text($view); $view->task = $this; $view->imageId = $image->getContentId(); $view->due = new Horde_Date($this->due); $view->dateFormat = $prefs->getValue('date_format'); $view->timeFormat = $prefs->getValue('twentyFour') ? 'H:i' : 'h:ia'; if (!$prefs->isLocked('task_alarms')) { $view->prefsUrl = Horde::url($GLOBALS['registry']->getServiceLink('prefs', 'nag'), true)->remove(session_name()); } $methods['mail']['mimepart'] = Nag::buildMimeMessage($view, 'mail', $image); } if (isset($methods['desktop'])) { $methods['desktop']['url'] = Horde::url('view.php', true)->add('tasklist', $this->tasklist)->add('task', $this->id)->toString(true, true); } return array('id' => $this->uid, 'user' => $user, 'start' => new Horde_Date($this->due - $this->alarm * 60), 'methods' => array_keys($methods), 'params' => $methods, 'title' => $this->name, 'text' => $this->desc); }
/** * Deletes a task and handles notification. * * @param string $taskId The task to delete. */ public function delete($taskId) { /* Get the task's details for use later. */ $task = $this->get($taskId); $delete = $this->_delete($taskId); /* Log the deletion of this item in the history log. */ if (!empty($task->uid)) { try { $GLOBALS['injector']->getInstance('Horde_History')->log('nag:' . $this->_tasklist . ':' . $task->uid, array('action' => 'delete'), true); } catch (Exception $e) { Horde::log($e, 'ERR'); } } /* Notify users about the deleted event. */ try { $result = Nag::sendNotification('delete', $task); } catch (Nag_Exception $e) { Horde::log($e, 'ERR'); } /* Delete alarm if necessary. */ if (!empty($task->alarm)) { $GLOBALS['injector']->getInstance('Horde_Alarm')->delete($task->uid); } /* Remove any CalDAV mappings. */ try { $GLOBALS['injector']->getInstance('Horde_Dav_Storage')->deleteInternalObjectId($task->id, $task->tasklist); } catch (Horde_Exception $e) { Horde::log($e); } }
/** * 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; }
/** */ 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>'; }
/** * Retrieves one or multiple tasks from the database by UID. * * @param string|array $uid The UID(s) of the task to retrieve. * @param array $tasklists An optional array of tasklists to search. * @param boolean $getall If true, return all instances of the task, * otherwise only one. Attempts to find the * instance owned by the current user. * * @return Nag_Task A Nag_Task object. * @throws Horde_Exception_NotFound * @throws Nag_Exception */ public function getByUID($uids, array $tasklists = null, $getall = true) { if (!is_array($tasklists)) { $tasklists = array_keys(Nag::listTasklists(false, Horde_Perms::READ, false)); } $results = array(); foreach ($tasklists as $tasklist) { $this->_tasklist = $tasklist; try { $results[] = $this->get(Horde_Url::uriB64Encode($uid)); } catch (Horde_Exception_NotFound $e) { } } if ($getall && count($results) == 1) { return $results[0]; } elseif ($getall) { $task = new Nag_Task(); foreach ($results as $row) { $task->add($row); } } else { $ownerlists = Nag::listTasklists(true); $task = null; foreach ($results as $row) { if (isset($ownerlists[$row->tasklist])) { $task = $row; break; } } if (empty($task)) { $readablelists = Nag::listTasklists(); foreach ($results as $row) { if (isset($readablelists[$row->tasklist])) { $task = $row; break; } } } } if (empty($task)) { throw new Horde_Exception_NotFound(); } return $task; }
/** * Return an array describing this task from the provided backend data. * * @param array $row The backend data * @param boolean $include_history Include history data. * * @return array The task data. */ protected function _buildTask($row, $include_history = true) { // Make sure tasks always have a UID. if (empty($row['task_uid'])) { $row['task_uid'] = strval(new Horde_Support_Guid()); $query = 'UPDATE ' . $this->_params['table'] . ' SET task_uid = ?' . ' WHERE task_owner = ? AND task_id = ?'; $values = array($row['task_uid'], $row['task_owner'], $row['task_id']); try { $this->_db->update($query, $values); } catch (Horde_Db_Exception $e) { } } if (!$row['task_due'] || !$row['task_recurtype']) { $recurrence = null; } else { $recurrence = new Horde_Date_Recurrence($row['task_due']); $recurrence->setRecurType((int) $row['task_recurtype']); $recurrence->setRecurInterval((int) $row['task_recurinterval']); if (isset($row['task_recurenddate']) && $row['task_recurenddate'] != '9999-12-31 23:59:59') { $recur_end = new Horde_Date($row['task_recurenddate'], 'UTC'); $recur_end->setTimezone(date_default_timezone_get()); $recurrence->setRecurEnd($recur_end); } if (isset($row['task_recurcount'])) { $recurrence->setRecurCount((int) $row['task_recurcount']); } if (isset($row['task_recurdays'])) { $recurrence->recurData = (int) $row['task_recurdays']; } if (!empty($row['task_exceptions'])) { $recurrence->exceptions = explode(',', $row['task_exceptions']); } if (!empty($row['task_completions'])) { $recurrence->completions = explode(',', $row['task_completions']); } } /* Create a new task based on $row's values. */ $task = array('tasklist_id' => $row['task_owner'], 'task_id' => $row['task_id'], 'uid' => Horde_String::convertCharset($row['task_uid'], $this->_params['charset'], 'UTF-8'), 'parent' => $row['task_parent'], 'owner' => $row['task_creator'], 'assignee' => $row['task_assignee'], 'name' => Horde_String::convertCharset($row['task_name'], $this->_params['charset'], 'UTF-8'), 'desc' => Horde_String::convertCharset($row['task_desc'], $this->_params['charset'], 'UTF-8'), 'start' => $row['task_start'], 'due' => $row['task_due'], 'priority' => $row['task_priority'], 'estimate' => (double) $row['task_estimate'], 'completed' => $row['task_completed'], 'completed_date' => isset($row['task_completed_date']) ? $row['task_completed_date'] : null, 'alarm' => $row['task_alarm'], 'methods' => Horde_String::convertCharset(@unserialize($row['task_alarm_methods']), $this->_params['charset'], 'UTF-8'), 'private' => $row['task_private'], 'recurrence' => $recurrence); if ($include_history) { try { $userId = $GLOBALS['registry']->getAuth(); $log = $GLOBALS['injector']->getInstance('Horde_History')->getHistory('nag:' . $row['task_owner'] . ':' . $row['task_uid']); foreach ($log as $entry) { switch ($entry['action']) { case 'add': $task['created'] = new Horde_Date($entry['ts']); if ($userId != $entry['who']) { $task['createdby'] = sprintf(_("by %s"), Nag::getUserName($entry['who'])); } else { $task['createdby'] = _("by me"); } break; case 'modify': $task['modified'] = new Horde_Date($entry['ts']); if ($userId != $entry['who']) { $task['modifiedby'] = sprintf(_("by %s"), Nag::getUserName($entry['who'])); } else { $task['modifiedby'] = _("by me"); } break; } } } catch (Horde_Exception $e) { } } return $task; }
$_prefs['sync_lists'] = array('value' => 'a:0:{}', 'type' => 'multienum', 'enum' => array(), 'desc' => _("Select the task lists that, in addition to the default, should be used for synchronization with external devices:"), 'on_init' => function ($ui) { $enum = array(); $sync = @unserialize($GLOBALS['prefs']->getValue('sync_lists')); if (empty($sync)) { $GLOBALS['prefs']->setValue('sync_lists', serialize(array(Nag::getDefaultTasklist()))); } foreach (Nag::listTasklists(false, Horde_Perms::EDIT, false) as $key => $list) { if ($list->getName() != Nag::getDefaultTasklist(Horde_Perms::EDIT)) { $enum[$key] = Nag::getLabel($list); } } $ui->prefs['sync_lists']['enum'] = $enum; }, 'on_change' => function () { $sync = @unserialize($GLOBALS['prefs']->getValue('sync_lists')); $haveDefault = false; $default = Nag::getDefaultTasklist(Horde_Perms::EDIT); foreach ($sync as $cid) { if ($cid == $default) { $haveDefault = true; break; } } if (!$haveDefault) { $sync[] = $default; $GLOBALS['prefs']->setValue('sync_lists', serialize($sync)); } if ($GLOBALS['conf']['activesync']['enabled'] && !$GLOBALS['prefs']->getValue('activesync_no_multiplex')) { try { $sm = $GLOBALS['injector']->getInstance('Horde_ActiveSyncState'); $sm->setLogger($GLOBALS['injector']->getInstance('Horde_Log_Logger')); $devices = $sm->listDevices($GLOBALS['registry']->getAuth());
/** */ public function davDeleteObject($collection, $object) { $dav = $GLOBALS['injector']->getInstance('Horde_Dav_Storage'); $internal = $dav->getInternalCollectionId($collection, 'tasks') ?: $collection; if (!Nag::hasPermission($internal, Horde_Perms::DELETE)) { throw new Nag_Exception("Task List does not exist or no permission to delete"); } try { $object = $dav->getInternalObjectId($object, $internal) ?: preg_replace('/\\.ics$/', '', $object); } catch (Horde_Dav_Exception $e) { } $GLOBALS['injector']->getInstance('Nag_Factory_Driver')->create($internal)->delete($object); try { $dav->deleteExternalObjectId($object, $internal); } catch (Horde_Dav_Exception $e) { } }
public function getInfo(&$vars, &$var, &$info) { $recur = $vars->recurrence; if (!$recur) { return; } $recurrence = new Horde_Date_Recurrence($this->_getDue($var, $vars)); if ($vars->recur_end_type == 'date') { $recurEnd = Nag::parseDate($vars->recur_end, false); $recurEnd->hour = 23; $recurEnd->min = $recurEnd->sec = 59; $recurrence->setRecurEnd($recurEnd); } elseif ($vars->recur_end_type == 'count') { $recurrence->setRecurCount($vars->recur_count); } elseif ($vars->recur_end_type == 'none') { $recurrence->setRecurCount(0); $recurrence->setRecurEnd(null); } $recurrence->setRecurType($recur); switch ($recur) { case Horde_Date_Recurrence::RECUR_DAILY: $recurrence->setRecurInterval($vars->get('recur_daily_interval', 1)); break; case Horde_Date_Recurrence::RECUR_WEEKLY: $weekly = $vars->weekly; $weekdays = 0; if (is_array($weekly)) { foreach ($weekly as $day) { $weekdays |= $day; } } if ($weekdays == 0) { // Sunday starts at 0. switch ($recurrence->start->dayOfWeek()) { case 0: $weekdays |= Horde_Date::MASK_SUNDAY; break; case 1: $weekdays |= Horde_Date::MASK_MONDAY; break; case 2: $weekdays |= Horde_Date::MASK_TUESDAY; break; case 3: $weekdays |= Horde_Date::MASK_WEDNESDAY; break; case 4: $weekdays |= Horde_Date::MASK_THURSDAY; break; case 5: $weekdays |= Horde_Date::MASK_FRIDAY; break; case 6: $weekdays |= Horde_Date::MASK_SATURDAY; break; } } $recurrence->setRecurInterval($vars->get('recur_weekly_interval', 1)); $recurrence->setRecurOnDay($weekdays); break; case Horde_Date_Recurrence::RECUR_MONTHLY_DATE: switch ($vars->recur_monthly_scheme) { case Horde_Date_Recurrence::RECUR_MONTHLY_WEEKDAY: $recurrence->setRecurType(Horde_Date_Recurrence::RECUR_MONTHLY_WEEKDAY); case Horde_Date_Recurrence::RECUR_MONTHLY_DATE: $recurrence->setRecurInterval($vars->recur_monthly ? 1 : $vars->get('recur_monthly_interval', 1)); break; default: $recurrence->setRecurInterval($vars->get('recur_day_of_month_interval', 1)); break; } break; case Horde_Date_Recurrence::RECUR_MONTHLY_WEEKDAY: $recurrence->setRecurInterval($vars->get('recur_week_of_month_interval', 1)); break; case Horde_Date_Recurrence::RECUR_YEARLY_DATE: switch ($vars->recur_yearly_scheme) { case Horde_Date_Recurrence::RECUR_YEARLY_WEEKDAY: case Horde_Date_Recurrence::RECUR_YEARLY_DAY: $recurrence->setRecurType($vars->recur_yearly_scheme); case Horde_Date_Recurrence::RECUR_YEARLY_DATE: $recurrence->setRecurInterval($vars->recur_yearly ? 1 : $vars->get('recur_yearly_interval', 1)); break; default: $recurrence->setRecurInterval($vars->get('recur_yearly_interval', 1)); break; } break; case Horde_Date_Recurrence::RECUR_YEARLY_DAY: $recurrence->setRecurInterval($vars->get('recur_yearly_day_interval', $yearly_interval)); break; case Horde_Date_Recurrence::RECUR_YEARLY_WEEKDAY: $recurrence->setRecurInterval($vars->get('recur_yearly_weekday_interval', $yearly_interval)); break; } if ($vars->exceptions) { foreach ($vars->exceptions as $exception) { $recurrence->addException((int) substr($exception, 0, 4), (int) substr($exception, 4, 2), (int) substr($exception, 6, 2)); } } $info = $recurrence; }
/** * Retrieve the UID for the current user's default tasklist. * * @return string UID. * @since 4.2.0 */ public function getDefaultShare() { return Nag::getDefaultTasklist(Horde_Perms::EDIT); }
/** * Exports this task in iCalendar format. * * @param Horde_Icalendar $calendar A Horde_Icalendar object that acts as * the container. * * @return Horde_Icalendar_Vtodo A vtodo component of this task. */ public function toiCalendar(Horde_Icalendar $calendar) { $vTodo = Horde_Icalendar::newComponent('vtodo', $calendar); $v1 = $calendar->getAttribute('VERSION') == '1.0'; $vTodo->setAttribute('UID', $this->uid); if (!empty($this->assignee)) { $vTodo->setAttribute('ATTENDEE', Nag::getUserEmail($this->assignee), array('ROLE' => 'REQ-PARTICIPANT')); } $vTodo->setAttribute('ORGANIZER', !empty($this->organizer) ? Nag::getUserEmail($this->organizer) : Nag::getUserEmail($this->owner)); if (!empty($this->name)) { $vTodo->setAttribute('SUMMARY', $this->name); } if (!empty($this->desc)) { $vTodo->setAttribute('DESCRIPTION', $this->desc); } if (isset($this->priority)) { $vTodo->setAttribute('PRIORITY', $this->priority); } if (!empty($this->parent_id) && !empty($this->parent)) { $vTodo->setAttribute('RELATED-TO', $this->parent->uid); } if ($this->private) { $vTodo->setAttribute('CLASS', 'PRIVATE'); } if (!empty($this->start)) { $vTodo->setAttribute('DTSTART', $this->start); } if ($this->due) { $vTodo->setAttribute('DUE', $this->due); if ($this->alarm) { if ($v1) { $vTodo->setAttribute('AALARM', $this->due - $this->alarm * 60); } else { $vAlarm = Horde_Icalendar::newComponent('valarm', $vTodo); $vAlarm->setAttribute('ACTION', 'DISPLAY'); $vAlarm->setAttribute('TRIGGER;VALUE=DURATION', '-PT' . $this->alarm . 'M'); $vTodo->addComponent($vAlarm); } } } if ($this->completed) { $vTodo->setAttribute('STATUS', 'COMPLETED'); $vTodo->setAttribute('COMPLETED', $this->completed_date ? $this->completed_date : $_SERVER['REQUEST_TIME']); $vTodo->setAttribute('PERCENT-COMPLETE', '100'); } else { if (!empty($this->estimate)) { $vTodo->setAttribute('PERCENT-COMPLETE', $this->actual / $this->estimate * 100); } if ($v1) { $vTodo->setAttribute('STATUS', 'NEEDS ACTION'); } else { $vTodo->setAttribute('STATUS', 'NEEDS-ACTION'); } } // Recurrence. // We may have to implicitely set DTSTART if not set explicitely, may // some clients choke on missing DTSTART attributes while RRULE exists. if ($this->recurs()) { if ($v1) { $rrule = $this->recurrence->toRRule10($calendar); } else { $rrule = $this->recurrence->toRRule20($calendar); } if (!empty($rrule)) { $vTodo->setAttribute('RRULE', $rrule); } /* The completions represent deleted recurrences */ foreach ($this->recurrence->getCompletions() as $exception) { if (!empty($exception)) { // Use multiple EXDATE attributes instead of EXDATE // attributes with multiple values to make Apple iCal // happy. list($year, $month, $mday) = sscanf($exception, '%04d%02d%02d'); $vTodo->setAttribute('EXDATE', array(new Horde_Date($year, $month, $mday)), array('VALUE' => 'DATE')); } } } if ($this->tags) { $vTodo->setAttribute('CATEGORIES', implode(', ', $this->tags)); } /* Get the task's history. */ $created = $modified = null; try { $log = $GLOBALS['injector']->getInstance('Horde_History')->getHistory('nag:' . $this->tasklist . ':' . $this->uid); foreach ($log as $entry) { switch ($entry['action']) { case 'add': $created = $entry['ts']; break; case 'modify': $modified = $entry['ts']; break; } } } catch (Exception $e) { } if (!empty($created)) { $vTodo->setAttribute($v1 ? 'DCREATED' : 'CREATED', $created); if (empty($modified)) { $modified = $created; } } if (!empty($modified)) { $vTodo->setAttribute('LAST-MODIFIED', $modified); } return $vTodo; }
$_prefs['sync_lists'] = array('value' => 'a:0:{}', 'type' => 'multienum', 'enum' => array(), 'desc' => _("Select the task lists that, in addition to the default, should be used for synchronization with external devices:"), 'on_init' => function ($ui) { $enum = array(); $sync = @unserialize($GLOBALS['prefs']->getValue('sync_lists')); if (empty($sync)) { $GLOBALS['prefs']->setValue('sync_lists', serialize(array(Nag::getDefaultTasklist(Horde_Perms::DELETE)))); } foreach (Nag::listTasklists(false, Horde_Perms::DELETE, false) as $key => $list) { if ($list->getName() != Nag::getDefaultTasklist(Horde_Perms::DELETE)) { $enum[$key] = Nag::getLabel($list); } } $ui->prefs['sync_lists']['enum'] = $enum; }, 'on_change' => function () { $sync = @unserialize($GLOBALS['prefs']->getValue('sync_lists')); $haveDefault = false; $default = Nag::getDefaultTasklist(Horde_Perms::DELETE); foreach ($sync as $cid) { if ($cid == $default) { $haveDefault = true; break; } } if (!$haveDefault) { $sync[] = $default; $GLOBALS['prefs']->setValue('sync_lists', serialize($sync)); } if ($GLOBALS['conf']['activesync']['enabled'] && !$GLOBALS['prefs']->getValue('activesync_no_multiplex')) { try { $sm = $GLOBALS['injector']->getInstance('Horde_ActiveSyncState'); $sm->setLogger($GLOBALS['injector']->getInstance('Horde_Log_Logger')); $devices = $sm->listDevices($GLOBALS['registry']->getAuth());
/** * Sends email notifications that a task has been added, edited, or * deleted to users that want such notifications. * * @param string $action The event action. One of "add", "edit", or * "delete". * @param Nag_Task $task The changed task. * @param Nag_Task $old_task The original task if $action is "edit". * * @throws Nag_Exception */ public static function sendNotification($action, $task, $old_task = null) { if (!in_array($action, array('add', 'edit', 'delete'))) { throw new Nag_Exception('Unknown event action: ' . $action); } try { $share = $GLOBALS['nag_shares']->getShare($task->tasklist); } catch (Horde_Share_Exception $e) { Horde::log($e->getMessage(), 'ERR'); throw new Nag_Exception($e); } $groups = $GLOBALS['injector']->getInstance('Horde_Group'); $recipients = array(); $identity = $GLOBALS['injector']->getInstance('Horde_Core_Factory_Identity')->create(); $from = $identity->getDefaultFromAddress(true); $owner = $share->get('owner'); if (strlen($owner)) { $recipients[$owner] = self::_notificationPref($owner, 'owner'); } foreach ($share->listUsers(Horde_Perms::READ) as $user) { if (empty($recipients[$user])) { $recipients[$user] = self::_notificationPref($user, 'read', $task->tasklist); } } foreach ($share->listGroups(Horde_Perms::READ) as $group) { try { $group_users = $groups->listUsers($group); } catch (Horde_Group_Exception $e) { Horde::log($e, 'ERR'); continue; } foreach ($group_users as $user) { if (empty($recipients[$user])) { $recipients[$user] = self::_notificationPref($user, 'read', $task->tasklist); } } } $addresses = array(); foreach ($recipients as $user => $vals) { if (!$vals) { continue; } $identity = $GLOBALS['injector']->getInstance('Horde_Core_Factory_Identity')->create($user); $email = $identity->getValue('from_addr'); if (strpos($email, '@') === false) { continue; } if (!isset($addresses[$vals['lang']][$vals['tf']][$vals['df']])) { $addresses[$vals['lang']][$vals['tf']][$vals['df']] = array(); } $tmp = new Horde_Mail_Rfc822_Address($email); $tmp->personal = $identity->getValue('fullname'); $addresses[$vals['lang']][$vals['tf']][$vals['df']][] = strval($tmp); } if (!$addresses) { return; } $mail = new Horde_Mime_Mail(array('User-Agent' => 'Nag ' . $GLOBALS['registry']->getVersion(), 'Precedence' => 'bulk', 'Auto-Submitted' => 'auto-generated', 'From' => $from)); foreach ($addresses as $lang => $twentyFour) { $GLOBALS['registry']->setLanguageEnvironment($lang); $view_link = Horde::url('view.php', true)->add(array('tasklist' => $task->tasklist, 'task' => $task->id))->setRaw(true); switch ($action) { case 'add': $subject = _("Task added:"); $notification_message = _("You requested to be notified when tasks are added to your task lists.") . "\n\n" . ($task->due ? _("The task \"%s\" has been added to task list \"%s\", with a due date of: %s.") : _("The task \"%s\" has been added to task list \"%s\".")) . "\n" . str_replace('%', '%%', $view_link); break; case 'edit': $subject = _("Task modified:"); $notification_message = _("You requested to be notified when tasks are edited on your task lists.") . "\n\n" . _("The task \"%s\" has been edited on task list \"%s\".") . "\n" . str_replace('%', '%%', $view_link) . "\n\n" . _("Changes made for this task:"); if ($old_task->name != $task->name) { $notification_message .= "\n - " . sprintf(_("Changed name from \"%s\" to \"%s\""), $old_task->name, $task->name); } if ($old_task->tasklist != $task->tasklist) { $old_share = $GLOBALS['nag_shares']->getShare($old_task->tasklist); $notification_message .= "\n - " . sprintf(_("Changed task list from \"%s\" to \"%s\""), Nag::getLabel($old_share), Nag::getLabel($share)); } if ($old_task->parent_id != $task->parent_id) { $old_parent = $old_task->getParent(); try { $parent = $task->getParent(); $notification_message .= "\n - " . sprintf(_("Changed parent task from \"%s\" to \"%s\""), $old_parent ? $old_parent->name : _("no parent"), $parent ? $parent->name : _("no parent")); } catch (Nag_Exception $e) { } } if ($old_task->assignee != $task->assignee) { $identity = $GLOBALS['injector']->getInstance('Horde_Core_Factory_Identity')->create($old_task->assignee); $old_name = $identity->getValue('fullname'); if (!strlen($old_name)) { $old_name = $old_task->assignee; } $identity = $GLOBALS['injector']->getInstance('Horde_Core_Factory_Identity')->create($task->assignee); $new_name = $identity->getValue('fullname'); if (!strlen($new_name)) { $new_name = $new_task->assignee; } $notification_message .= "\n - " . sprintf(_("Changed assignee from \"%s\" to \"%s\""), $old_name, $new_name); } if ($old_task->private != $task->private) { $notification_message .= "\n - " . ($task->private ? _("Turned privacy on") : _("Turned privacy off")); } if ($old_task->due != $task->due) { $notification_message .= "\n - " . sprintf(_("Changed due date from %s to %s"), $old_task->due ? self::formatDate($old_task->due) : _("no due date"), $task->due ? self::formatDate($task->due) : _("no due date")); } if ($old_task->start != $task->start) { $notification_message .= "\n - " . sprintf(_("Changed start date from %s to %s"), $old_task->start ? self::formatDate($old_task->start) : _("no start date"), $task->start ? self::formatDate($task->start) : _("no start date")); } if ($old_task->alarm != $task->alarm) { $notification_message .= "\n - " . sprintf(_("Changed alarm from %s to %s"), self::formatAlarm($old_task->alarm), self::formatAlarm($task->alarm)); } if ($old_task->priority != $task->priority) { $notification_message .= "\n - " . sprintf(_("Changed priority from %s to %s"), $old_task->priority, $task->priority); } if ($old_task->estimate != $task->estimate) { $notification_message .= "\n - " . sprintf(_("Changed estimate from %s to %s"), $old_task->estimate, $task->estimate); } if ($old_task->completed != $task->completed) { $notification_message .= "\n - " . sprintf(_("Changed completion from %s to %s"), $old_task->completed ? _("completed") : _("not completed"), $task->completed ? _("completed") : _("not completed")); } if ($old_task->desc != $task->desc) { $notification_message .= "\n - " . _("Changed description"); } break; case 'delete': $subject = _("Task deleted:"); $notification_message = _("You requested to be notified when tasks are deleted from your task lists.") . "\n\n" . _("The task \"%s\" has been deleted from task list \"%s\"."); break; } $mail->addHeader('Subject', $subject . ' ' . $task->name); foreach ($twentyFour as $tf => $dateFormat) { foreach ($dateFormat as $df => $df_recipients) { $message = sprintf($notification_message, $task->name, Nag::getLabel($share), $task->due ? strftime($df, $task->due) . ' ' . date($tf ? 'H:i' : 'h:ia', $task->due) : ''); if (strlen(trim($task->desc))) { $message .= "\n\n" . _("Task description:") . "\n\n" . $task->desc; } $mail->setBody($message); $mail->clearRecipients(); $mail->addRecipients($df_recipients); Horde::log(sprintf('Sending event notifications for %s to %s', $task->name, implode(', ', $df_recipients)), 'INFO'); $mail->send($GLOBALS['injector']->getInstance('Horde_Mail')); } } } }
$notification->push(_("Task not found"), 'horde.error'); Horde::url('list.php', true)->redirect(); } } /* Load child tasks */ $task->loadChildren(false); /* Check permissions on $tasklist_id. */ $share = $GLOBALS['nag_shares']->getShare($tasklist_id); if (!$share->hasPermission($GLOBALS['registry']->getAuth(), Horde_Perms::READ)) { $notification->push(_("You do not have permission to view this task list."), 'horde.error'); Horde::url('list.php', true)->redirect(); } $links = array(); $page_output->addScriptFile('stripe.js', 'horde'); $taskurl = Horde::url('task.php')->add(array('task' => $task_id, 'tasklist' => $tasklist_id)); try { $share = $GLOBALS['nag_shares']->getShare($tasklist_id); } catch (Horde_Share_Exception $e) { Horde::log($e->getMessage(), 'ERR'); throw new Nag_Exception($e); } /* Set up alarm units and value. */ $task_alarm = $task->alarm; if (!$task->due) { $task_alarm = 0; } $alarm_text = Nag::formatAlarm($task_alarm); $page_output->header(array('title' => $task->name)); Nag::status(); require NAG_TEMPLATES . '/view/task.inc'; $page_output->footer();
public function getTask() { $out = new StdClass(); if (!isset($this->vars->task) || !isset($this->vars->tasklist)) { $out->error = 'Missing Parameters'; } else { $task = Nag::getTask($this->vars->tasklist, $this->vars->task); $out->task = $task->toJson(true); } return $out; }
while ($task = $this->tasks->each()) { $due = $task->due ? $task->getNextDue() : null; if (!empty($task->completed)) { $style = 'linedRow closed'; } elseif ($due && $due->before($_SERVER['REQUEST_TIME'])) { $style = 'linedRow overdue'; } else { $style = ''; } if ($task->tasklist == '**EXTERNAL**') { $share = $GLOBALS['nag_shares']->newShare($GLOBALS['registry']->getAuth(), '**EXTERNAL**', $task->tasklist_name); $owner = $task->tasklist_name; } else { try { $share = $GLOBALS['nag_shares']->getShare($task->tasklist); $owner = Nag::getLabel($share); } catch (Horde_Share_Exception $e) { $owner = $task->tasklist; } } $locals = array('style' => $style, 'have_read' => $share->hasPermission($GLOBALS['registry']->getAuth(), Horde_Perms::READ), 'have_edit' => $share->hasPermission($GLOBALS['registry']->getAuth(), Horde_Perms::EDIT), 'owner' => $owner, 'task' => $task, 'due' => $due, 'columns' => $this->columns, 'dynamic_sort' => $this->dynamic_sort &= !$task->hasSubTasks(), 'dateFormat' => $GLOBALS['prefs']->getValue('date_format')); ?> <?php echo $this->renderPartial('list/task', array('locals' => $locals)); ?> <?php } ?> </tbody> </table> <?php
/** * 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); }
/** * 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; }