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 (jon@horde.org)
Author: Chuck Hagenbuch (chuck@horde.org)
Author: Jan Schneider (jan@horde.org)
Beispiel #1
0
 public function execute()
 {
     if ($this->_vars->get('submitbutton') == _("Cancel")) {
         Horde::url('list.php', true)->redirect();
     }
     Nag::deleteTasklist($this->_tasklist);
 }
Beispiel #2
0
 /**
  * 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;
 }
Beispiel #3
0
 /**
  * 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));
 }
Beispiel #4
0
/**
 * 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();
}
Beispiel #5
0
 /**
  */
 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;
 }
Beispiel #6
0
 public function execute()
 {
     $info = array();
     foreach (array('name', 'color', 'description', 'system') as $key) {
         $info[$key] = $this->_vars->get($key);
     }
     return Nag::addTasklist($info);
 }
Beispiel #7
0
 /**
  * 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();
     }
 }
Beispiel #8
0
 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;
 }
Beispiel #9
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;
 }
Beispiel #10
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;
     }
 }
Beispiel #11
0
 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);
 }
Beispiel #12
0
 /**
  * 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');
     }
 }
Beispiel #13
0
 /**
  * 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);
 }
Beispiel #14
0
 /**
  * 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);
     }
 }
Beispiel #15
0
 /**
  * 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;
 }
Beispiel #16
0
 /**
  */
 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') . '&nbsp;&nbsp;<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 . '>&nbsp;' . Nag::formatPriority($task->priority) . '&nbsp;</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))) . '&nbsp;</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>';
 }
Beispiel #17
0
 /**
  * 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;
 }
Beispiel #18
0
 /**
  * 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;
 }
Beispiel #19
0
$_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());
Beispiel #20
0
 /**
  */
 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) {
     }
 }
Beispiel #21
0
 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;
 }
Beispiel #22
0
 /**
  * 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);
 }
Beispiel #23
0
 /**
  * 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;
 }
Beispiel #24
0
$_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());
Beispiel #25
0
 /**
  * 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'));
             }
         }
     }
 }
Beispiel #26
0
        $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();
Beispiel #27
0
 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;
 }
Beispiel #28
0
 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 
Beispiel #29
0
 /**
  * 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('&nbsp;', $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);
 }
Beispiel #30
0
 /**
  * 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;
 }