Sets the value of an attribute.
public setAttribute ( string $name, string $value, array $params = [], boolean $append = true, array $values = false ) | ||
$name | string | The name of the attribute. |
$value | string | The value of the attribute. |
$params | array | Array containing any addition parameters for this attribute. |
$append | boolean | True to append the attribute, False to replace the first matching attribute found. |
$values | array | Array representation of $value. For comma/semicolon seperated lists of values. If not set use $value as single array element. |
/** */ protected function _create($mbox, $subject, $body) { global $notification, $registry; $list = str_replace(self::TASKLIST_EDIT, '', $mbox); /* Create a new iCalendar. */ $vCal = new Horde_Icalendar(); $vCal->setAttribute('PRODID', '-//The Horde Project//IMP ' . $registry->getVersion() . '//EN'); $vCal->setAttribute('METHOD', 'PUBLISH'); /* Create a new vTodo object using this message's contents. */ $vTodo = Horde_Icalendar::newComponent('vtodo', $vCal); $vTodo->setAttribute('SUMMARY', $subject); $vTodo->setAttribute('DESCRIPTION', $body); $vTodo->setAttribute('PRIORITY', '3'); /* Get the list of editable tasklists. */ $lists = $this->getTasklists(true); /* Attempt to add the new vTodo item to the requested tasklist. */ try { $res = $registry->call('tasks/import', array($vTodo, 'text/calendar', $list)); } catch (Horde_Exception $e) { $notification->push($e); return; } if (!$res) { $notification->push(_("An unknown error occured while creating the new task."), 'horde.error'); } elseif (!empty($lists)) { $name = '"' . htmlspecialchars($subject) . '"'; /* Attempt to convert the object name into a hyperlink. */ if ($registry->hasLink('tasks/show')) { $name = sprintf('<a href="%s">%s</a>', Horde::url($registry->link('tasks/show', array('uid' => $res))), $name); } $notification->push(sprintf(_("%s was successfully added to \"%s\"."), $name, htmlspecialchars($lists[$list]->get('name'))), 'horde.success', array('content.raw')); } }
/** * @param mixed Kronolith_Event|string $event The event object or error * string to display. */ public function __construct($event) { if (!$event) { echo '<h3>' . _("Event not found") . '</h3>'; exit; } if (is_string($event)) { echo '<h3>' . $event . '</h3>'; exit; } $iCal = new Horde_Icalendar('2.0'); if ($event->calendarType == 'internal') { try { $share = $GLOBALS['injector']->getInstance('Kronolith_Shares')->getShare($event->calendar); $iCal->setAttribute('X-WR-CALNAME', $share->get('name')); } catch (Exception $e) { } } $iCal->addComponent($event->toiCalendar($iCal)); $content = $iCal->exportvCalendar(); $GLOBALS['browser']->downloadHeaders($event->getTitle() . '.ics', 'text/calendar; charset=UTF-8', true, strlen($content)); echo $content; exit; }
private function _getMinimalInvitation() { $start = new Horde_Date('20080926T110000'); $end = new Horde_Date('20080926T120000'); $vCal = new Horde_Icalendar(); $vCal->setAttribute('METHOD', 'REQUEST'); $inv = Horde_Icalendar::newComponent('VEVENT', $vCal); $inv->setAttribute('UID', '1001'); $inv->setAttribute('ORGANIZER', 'mailto:orga@example.org', array('cn' => 'Mr. Orga')); $inv->setAttribute('DTSTART', $start->timestamp()); $inv->setAttribute('DTEND', $end->timestamp()); return $inv; }
/** * 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'); } }
/** */ public function davGetObject($collection, $object) { $dav = $GLOBALS['injector']->getInstance('Horde_Dav_Storage'); $internal = $dav->getInternalCollectionId($collection, 'calendar') ?: $collection; if (!Kronolith::hasPermission($internal, Horde_Perms::SHOW)) { throw new Kronolith_Exception(_("Calendar does not exist or no permission to edit")); } $kronolith_driver = Kronolith::getDriver(null, $internal); try { $object = $dav->getInternalObjectId($object, $internal) ?: preg_replace('/\\.ics$/', '', $object); } catch (Horde_Dav_Exception $e) { } $event = $kronolith_driver->getEvent($object); $id = $event->id; try { $id = $dav->getExternalObjectId($id, $internal) ?: $id . '.ics'; } catch (Horde_Dav_Exception $e) { } $event->loadHistory(); $modified = $event->modified ?: $event->created; $share = $GLOBALS['injector']->getInstance('Kronolith_Shares')->getShare($event->calendar); $ical = new Horde_Icalendar('2.0'); $ical->setAttribute('X-WR-CALNAME', $share->get('name')); $ical->addComponent($event->toiCalendar($ical)); $data = $ical->exportvCalendar(); return array('id' => $id, 'calendardata' => $data, 'uri' => $id, 'lastmodified' => $modified, 'etag' => '"' . md5($event->id . '|' . $modified) . '"', 'calendarid' => $collection, 'size' => strlen($data)); }
/** * Prepare the iCalendar part of the response object. * * @param Horde_Icalendar $ical The iCalendar response object. * * @return NULL */ public function prepareIcalendar(Horde_Icalendar $ical) { $ical->setAttribute('PRODID', $this->getProductId()); }
/** * Generate an iTip from embedded TNEF MEETING data. * */ protected function _checkiTip(&$out) { // Meeting requests will have 'type' set to a non-empty value. if (!empty($this->_iTip[0]) && !empty($this->_iTip[0]['method'])) { $iCal = new Horde_Icalendar(); // METHOD if (!empty($this->_iTip[0]['type'])) { switch ($this->_iTip[0]['type']) { case self::MAPI_MEETING_INITIAL: case self::MAPI_MEETING_FULL_UPDATE: $method = 'REQUEST'; break; case self::MAPI_MEETING_INFO: $method = 'PUBLISH'; break; } } else { $method = $this->_iTip[0]['method']; } $iCal->setAttribute('METHOD', $method); // VEVENT $vEvent = Horde_Icalendar::newComponent('vevent', $iCal); if (empty($this->_iTip[0]['end_utc'])) { return; } $end = clone $this->_iTip[0]['end_utc']; $end->sec++; if ($this->_iTip[0]['allday']) { $vEvent->setAttribute('DTSTART', $this->_iTip[0]['start_utc'], array('VALUE' => 'DATE')); $vEvent->setAttribute('DTEND', $end, array('VALUE' => 'DATE')); } else { $vEvent->setAttribute('DTSTART', $this->_iTip[0]['start_utc']); $vEvent->setAttribute('DTEND', $end); } $vEvent->setAttribute('DTSTAMP', $_SERVER['REQUEST_TIME']); $vEvent->setAttribute('UID', $this->_iTip[0]['uid']); if (!empty($this->_iTip[0]['created'])) { $vEvent->setAttribute('CREATED', $this->_iTip[0]['created']); } if (!empty($this->_iTip[0]['modified'])) { $vEvent->setAttribute('LAST-MODIFIED', $this->_iTip[0]['modified']); } $vEvent->setAttribute('SUMMARY', $this->_conversation_topic); if (empty($this->_iTip[0]['organizer']) && !empty($this->_lastModifier)) { $email = $this->_lastModifier; } else { if (!empty($this->_iTip[0]['organizer'])) { $email = $this->_iTip[0]['organizer']; } } if (!empty($email)) { $vEvent->setAttribute('ORGANIZER', 'mailto:' . $email); } if (!empty($this->_iTip[0]['url'])) { $vEvent->setAttribute('URL', $this->_iTip[0]['url']); } if (!empty($this->_iTip[0]['recurrence']['recur'])) { $rrule = $this->_iTip[0]['recurrence']['recur']->toRRule20($iCal); $vEvent->setAttribute('RRULE', $rrule); } $iCal->addComponent($vEvent); array_unshift($out, array('type' => 'text', 'subtype' => 'calendar', 'name' => $this->_conversation_topic, 'stream' => $iCal->exportvCalendar())); } }
public function sif2vtodo($sif) { $a = Horde_SyncMl_Device_sync4j::sif2array($sif); $iCal = new Horde_Icalendar(); $iCal->setAttribute('PRODID', '-//The Horde Project//SyncML//EN'); $iCal->setAttribute('METHOD', 'PUBLISH'); $vtodo = Horde_Icalendar::newComponent('vtodo', $iCal); $vtodo->setAttribute('SUMMARY', $a['Subject']); $vtodo->setAttribute('DESCRIPTION', $a['Body']); if ($a['Importance'] == 0) { $vtodo->setAttribute('PRIORITY', 5); } elseif ($a['Importance'] == 2) { $vtodo->setAttribute('PRIORITY', 1); } else { $vtodo->setAttribute('PRIORITY', 3); } if (!empty($a['StartDate']) && $a['StartDate'] != '45001231T230000Z') { $vtodo->setAttribute('DTSTART', $iCal->_parseDateTime($a['StartDate'])); } $dueSet = false; if (!empty($a['DueDate']) && $a['DueDate'] != '45001231T230000Z') { $vtodo->setAttribute('DUE', $iCal->_parseDateTime($a['DueDate'])); $dueSet = true; } if (!empty($a['ReminderSet'])) { if (!$dueSet) { $vtodo->setAttribute('DUE', $iCal->_parseDateTime($a['ReminderTime'])); } $vtodo->setAttribute('AALARM', $iCal->_parseDateTime($a['ReminderTime'])); } if (!empty($a['Complete'])) { $vtodo->setAttribute('STATUS', 'COMPLETED'); } $vtodo->setAttribute('CATEGORIES', isset($a['Categories']) ? $a['Categories'] : ''); if (isset($a['Sensitivity'])) { switch ($a['Sensitivity']) { case 0: /* olNormal */ $vtodo->setAttribute('CLASS', 'PUBLIC'); break; case 1: /* olPersonal */ /* olPersonal */ case 2: /* olPrivate */ $vtodo->setAttribute('CLASS', 'PRIVATE'); break; case 3: /* olConfidential */ $vtodo->setAttribute('CLASS', 'CONFIDENTIAL'); break; } } return $vtodo->exportvCalendar(); }
/** * Generates the free/busy text for $calendars. * * @param string|array $calendars The calendar to view free/busy slots for. * @param integer $startstamp The start of the time period to retrieve. * @param integer $endstamp The end of the time period to retrieve. * @param boolean $returnObj Default false. Return a vFreebusy object * instead of text. * @param string $user Set organizer to this user. * * @return string The free/busy text. * @throws Horde_Exception, Kronolith_Exception */ public static function generate($calendars, $startstamp = null, $endstamp = null, $returnObj = false, $user = null) { if (!is_array($calendars)) { $calendars = array($calendars); } if (!$user) { $kronolith_shares = $GLOBALS['injector']->getInstance('Kronolith_Shares'); /* Find a share and retrieve owner. */ foreach ($calendars as $calendar) { if (strpos($calendar, 'internal_') !== 0) { continue; } $calendar = substr($calendar, 9); try { $share = $kronolith_shares->getShare($calendar); $user = $share->get('owner'); break; } catch (Horde_Exception $e) { } } } /* Default the start date to today. */ if (is_null($startstamp)) { $startstamp = mktime(0, 0, 0); } /* Default the end date to the start date + freebusy_days. */ if (is_null($endstamp) || $endstamp < $startstamp) { $enddate = new Horde_Date($startstamp); $enddate->mday += $GLOBALS['prefs']->getValue('freebusy_days'); $endstamp = $enddate->timestamp(); } else { $enddate = new Horde_Date($endstamp); } /* Get the Identity for the owner of the share. */ $identity = $GLOBALS['injector']->getInstance('Horde_Core_Factory_Identity')->create($user); $email = $identity->getValue('from_addr'); $cn = $identity->getValue('fullname'); if (empty($email) && empty($cn)) { $cn = $user; } /* Fetch events. */ $busy = array(); foreach ($calendars as $calendar) { if (strpos($calendar, '_')) { @(list($type, $calendar) = explode('_', $calendar, 2)); } else { $type = 'internal'; } try { $GLOBALS['injector']->getInstance('Kronolith_Shares')->getShare($calendar); } catch (Horde_Exception $e) { throw new Kronolith_Exception('Share not found.'); } try { $driver = Kronolith::getDriver($type, $calendar); $events = $driver->listEvents(new Horde_Date($startstamp), $enddate, array('show_recurrence' => true)); Kronolith::mergeEvents($busy, $events); } catch (Exception $e) { } } /* Create the new iCalendar. */ $vCal = new Horde_Icalendar(); $vCal->setAttribute('PRODID', '-//The Horde Project//Kronolith ' . $GLOBALS['registry']->getVersion() . '//EN'); $vCal->setAttribute('METHOD', 'PUBLISH'); /* Create new vFreebusy. */ $vFb = Horde_Icalendar::newComponent('vfreebusy', $vCal); $params = array(); if (!empty($cn)) { $params['CN'] = $cn; } if (!empty($email)) { $vFb->setAttribute('ORGANIZER', 'mailto:' . $email, $params); } else { $vFb->setAttribute('ORGANIZER', '', $params); } $vFb->setAttribute('DTSTAMP', $_SERVER['REQUEST_TIME']); $vFb->setAttribute('DTSTART', $startstamp); $vFb->setAttribute('DTEND', $endstamp); $vFb->setAttribute('URL', Horde::url('fb.php?u=' . $user, true, -1)); /* Add all the busy periods. */ foreach ($busy as $events) { foreach ($events as $event) { if ($event->status == Kronolith::STATUS_FREE) { continue; } if ($event->status == Kronolith::STATUS_CANCELLED) { continue; } /* Horde_Icalendar_Vfreebusy only supports timestamps at the * moment. */ $vFb->addBusyPeriod('BUSY', $event->start->timestamp(), null, $event->end->timestamp() - $event->start->timestamp()); } } /* Remove the overlaps. */ $vFb->simplify(); $vCal->addComponent($vFb); /* Return the vFreebusy object if requested. */ if ($returnObj) { return $vFb; } /* Generate the vCal file. */ return $vCal->exportvCalendar(); }
/** * Sends out iTip event notifications to all attendees of a specific * event. * * Can be used to send event invitations, event updates as well as event * cancellations. * * @param Kronolith_Event $event * The event 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 Kronolith::ITIP_* * values. * @param Horde_Date $instance * If cancelling a single instance of a recurring event, the date of * this instance. * @param string $range The range parameter if this is a recurring event. * Possible values are self::RANGE_THISANDFUTURE * @param array $cancellations If $action is 'CANCEL', but it is due to * removing attendees and not canceling the * entire event, these are the email addresses * of the uninvited attendees and are the ONLY * people that will receive the CANCEL iTIP. * @since 4.2.10 * */ public static function sendITipNotifications(Kronolith_Event $event, Horde_Notification_Handler $notification, $action, Horde_Date $instance = null, $range = null, array $cancellations = array()) { global $injector, $registry; if (!$event->attendees) { return; } $ident = $injector->getInstance('Horde_Core_Factory_Identity')->create($event->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 = $injector->getInstance('Kronolith_Shares')->getShare($event->calendar); $view = new Horde_View(array('templatePath' => KRONOLITH_TEMPLATES . '/itip')); new Horde_View_Helper_Text($view); $view->identity = $ident; $view->event = $event; $view->imageId = $image->getContentId(); if ($action == self::ITIP_CANCEL && !empty($cancellations)) { $mail_attendees = $cancellations; } else { $mail_attendees = $event->attendees; } foreach ($mail_attendees as $email => $status) { /* Don't bother sending an invitation/update if the recipient does * not need to participate, or has declined participating, or * doesn't have an email address. */ if (strpos($email, '@') === false || $status['response'] == self::RESPONSE_DECLINED) { continue; } /* Determine all notification-specific strings. */ switch ($action) { case self::ITIP_CANCEL: /* Cancellation. */ $method = 'CANCEL'; $filename = 'event-cancellation.ics'; $view->subject = sprintf(_("Cancelled: %s"), $event->getTitle()); if (empty($instance)) { $view->header = sprintf(_("%s has cancelled \"%s\"."), $ident->getName(), $event->getTitle()); } else { $view->header = sprintf(_("%s has cancelled an instance of the recurring \"%s\"."), $ident->getName(), $event->getTitle()); } break; case self::ITIP_REQUEST: default: $method = 'REQUEST'; if ($status['response'] == self::RESPONSE_NONE) { /* Invitation. */ $filename = 'event-invitation.ics'; $view->subject = $event->getTitle(); $view->header = sprintf(_("%s wishes to make you aware of \"%s\"."), $ident->getName(), $event->getTitle()); } else { /* Update. */ $filename = 'event-update.ics'; $view->subject = sprintf(_("Updated: %s."), $event->getTitle()); $view->header = sprintf(_("%s wants to notify you about changes of \"%s\"."), $ident->getName(), $event->getTitle()); } break; } $view->attendees = strval(self::getAttendeeEmailList($event->attendees)); $view->organizer = $registry->convertUserName($event->creator, false); if ($action == self::ITIP_REQUEST) { $attend_link = Horde::url('attend.php', true, -1)->add(array('c' => $event->calendar, 'e' => $event->id, 'u' => $email)); $view->linkAccept = (string) $attend_link->add('a', 'accept'); $view->linkTentative = (string) $attend_link->add('a', 'tentative'); $view->linkDecline = (string) $attend_link->add('a', 'decline'); } /* Build the iCalendar data */ $iCal = new Horde_Icalendar(); $iCal->setAttribute('METHOD', $method); $iCal->setAttribute('X-WR-CALNAME', $share->get('name')); $vevent = $event->toiCalendar($iCal); if ($action == self::ITIP_CANCEL && !empty($instance)) { // Recurring event instance deletion, need to specify the // RECURRENCE-ID but NOT the EXDATE. foreach ($vevent as &$ve) { try { $uid = $ve->getAttribute('UID'); } catch (Horde_Icalendar_Exception $e) { continue; } if ($event->uid == $uid) { $ve->setAttribute('RECURRENCE-ID', $instance); if (!empty($range)) { $ve->setParameter('RECURRENCE-ID', array('RANGE' => $range)); } $ve->setAttribute('DTSTART', $instance, array(), false); $diff = $event->end->timestamp() - $event->start->timestamp(); $end = clone $instance; $end->sec += $diff; $ve->setAttribute('DTEND', $end, array(), false); $ve->removeAttribute('EXDATE'); break; } } } $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 = new Horde_Mail_Rfc822_Address($email); if (!empty($status['name'])) { $recipient->personal = $status['name']; } $mail = new Horde_Mime_Mail(array('Subject' => $view->subject, 'To' => $recipient, 'From' => $ident->getDefaultFromAddress(true), 'User-Agent' => 'Kronolith ' . $registry->getVersion())); $mail->setBasePart($multipart); try { $mail->send($injector->getInstance('Horde_Mail')); $notification->push(sprintf(_("The event notification to %s was successfully sent."), $recipient), 'horde.success'); } catch (Horde_Mime_Exception $e) { $notification->push(sprintf(_("There was an error sending an event notification to %s: %s"), $recipient, $e->getMessage(), $e->getCode()), 'horde.error'); } } }
/** * Generate an iTip from embedded TNEF MEETING data. * * @return array see @self::toArray(). */ protected function _toItip() { $iCal = new Horde_Icalendar(); // METHOD if ($this->_type) { switch ($this->_type) { case Horde_Compress_Tnef::MAPI_MEETING_INITIAL: case Horde_Compress_Tnef::MAPI_MEETING_FULL_UPDATE: $this->_method = 'REQUEST'; break; case Horde_Compress_Tnef::MAPI_MEETING_INFO: $this->_method = 'PUBLISH'; break; } } $iCal->setAttribute('METHOD', $this->_method); // VEVENT $vEvent = Horde_Icalendar::newComponent('vevent', $iCal); if (empty($this->_endUtc)) { return; } $end = clone $this->_endUtc; $end->sec++; if ($this->_allday) { $vEvent->setAttribute('DTSTART', $this->_startUtc, array('VALUE' => 'DATE')); $vEvent->setAttribute('DTEND', $end, array('VALUE' => 'DATE')); } else { $vEvent->setAttribute('DTSTART', $this->_startUtc); $vEvent->setAttribute('DTEND', $end); } $vEvent->setAttribute('DTSTAMP', $_SERVER['REQUEST_TIME']); $vEvent->setAttribute('UID', $this->_uid); if ($this->_created) { $vEvent->setAttribute('CREATED', $this->_created); } if ($this->_modified) { $vEvent->setAttribute('LAST-MODIFIED', $this->_modified); } // SUMMARY and DESCRIPTION $vEvent->setAttribute('SUMMARY', $this->_summary); if ($this->_description) { $vEvent->setAttribute('DESCRIPTION', trim($this->_description)); } // ORGANIZER if (!$this->_organizer && $this->_lastModifier) { $email = $this->_lastModifier; } else { if ($this->_organizer) { $email = $this->_organizer; } } if (!empty($email)) { $vEvent->setAttribute('ORGANIZER', 'mailto:' . $email); } // ATTENDEE if (empty($this->_requiredAttendees) && $this->_method == 'REPLY') { $this->_requiredAttendees = $this->_from; } if (!empty($this->_requiredAttendees)) { $list = new Horde_Mail_Rfc822_List($this->_requiredAttendees); foreach ($list as $email) { $params = array('ROLE' => 'REQ-PARTICIPANT'); if (!empty($this->_partStat)) { $params['PARTSTAT'] = $this->_partStat; } if ($this->_rsvp) { $params['RSVP'] = 'TRUE'; } $vEvent->setAttribute('ATTENDEE', $email->bare_address, $params); } } // LOCATION if ($this->_location) { $vEvent->setAttribute('LOCATION', $this->_location); } // URL if ($this->_url) { $vEvent->setAttribute('URL', $this->_url); } // RECUR if (!empty($this->_recurrence['recur'])) { $rrule = $this->_recurrence['recur']->toRRule20($iCal); $vEvent->setAttribute('RRULE', $rrule); } $iCal->addComponent($vEvent); $this->_content = $iCal->exportvCalendar(); return array('type' => 'text', 'subtype' => 'calendar', 'name' => $this->_summary, 'stream' => $this->_content); }
/** */ public function davGetObject($collection, $object) { $dav = $GLOBALS['injector']->getInstance('Horde_Dav_Storage'); $internal = $dav->getInternalCollectionId($collection, 'tasks') ?: $collection; if (!Nag::hasPermission($internal, Horde_Perms::READ)) { throw new Nag_Exception("Task List does not exist or no permission to edit"); } try { $object = $dav->getInternalObjectId($object, $internal) ?: preg_replace('/\\.ics$/', '', $object); } catch (Horde_Dav_Exception $e) { } $task = Nag::getTask($internal, $object); $id = $task->id; $modified = $this->_modified($internal, $task->uid); try { $id = $dav->getExternalObjectId($id, $internal) ?: $id . '.ics'; } catch (Horde_Dav_Exception $e) { } $share = $GLOBALS['nag_shares']->getShare($internal); $ical = new Horde_Icalendar('2.0'); $ical->setAttribute('X-WR-CALNAME', $share->get('name')); $ical->addComponent($task->toiCalendar($ical)); $data = $ical->exportvCalendar(); return array('id' => $id, 'calendardata' => $data, 'uri' => $id, 'lastmodified' => $modified, 'etag' => '"' . md5($task->id . '|' . $modified) . '"', 'calendarid' => $collection, 'size' => strlen($data)); }
/** * Exports a tasklist in the requested content type. * * @param string $tasklist The tasklist to export. * @param string $contentType What format should the data be in? * A string with one of: * <pre> * text/calendar (VCALENDAR 2.0. Recommended as * this is specified in rfc2445) * text/x-vcalendar (old VCALENDAR 1.0 format. * Still in wide use) * </pre> * * @return string The iCalendar representation of the tasklist. */ public function exportTasklist($tasklist, $contentType) { if (!Nag::hasPermission($tasklist, Horde_Perms::READ)) { throw new Horde_Exception_PermissionDenied(); } $tasks = Nag::listTasks(array('tasklists' => array($tasklist), 'completed' => Nag::VIEW_ALL, 'external' => false, 'include_tags' => true)); $version = '2.0'; switch ($contentType) { case 'text/x-vcalendar': $version = '1.0'; case 'text/calendar': $share = $GLOBALS['nag_shares']->getShare($tasklist); $iCal = new Horde_Icalendar($version); $iCal->setAttribute('X-WR-CALNAME', $share->get('name')); $tasks->reset(); while ($task = $tasks->each()) { $iCal->addComponent($task->toiCalendar($iCal)); } return $iCal->exportvCalendar(); } throw new Nag_Exception(sprintf(_("Unsupported Content-Type: %s"), $contentType)); }
/** * Fetch the free/busy data. * * @params array $params Additional options. * * @return array The free/busy data. */ public function fetch($params = array()) { $this->logger->debug(sprintf("Free/busy data of owner %s requested by user %s (remote: %s).", $this->callee, $this->user, $this->remote)); if (!empty($this->remote)) { /* Try to fetch the data if it is stored on a remote server */ //@todo: How to determine which hook/processor to run? return $this->fetchRemote($params); // if (is_a($result, 'PEAR_Error')) { // $error = array('type' => FREEBUSY_ERROR_UNAUTHORIZED, 'error' => $result); } global $conf; /* Which files will we access? */ if (!empty($conf['fb']['use_acls'])) { $aclcache =& Horde_Kolab_FreeBusy_Cache_DB_acl::singleton('acl', $this->_cache_dir); $files = $aclcache->get($access->owner); if (is_a($files, 'PEAR_Error')) { return $files; } } else { $file_uid = str_replace("", '', str_replace(".", "^", $access->owner)); $files = array(); $this->findAll_readdir($file_uid, $conf['fb']['cache_dir'] . '/' . $file_uid, $files); } $owner = $access->owner; if (ereg('(.*)@(.*)', $owner, $regs)) { $owner = $regs[2] . '/' . $regs[1]; } $user = $access->user; if (ereg('(.*)@(.*)', $user, $regs)) { $user = $regs[2] . '/' . $regs[1]; } $c_file = str_replace("", '', str_replace('.', '^', $user . '/' . $owner)); $c_vcal = new Horde_Kolab_FreeBusy_Cache_File_vcal($this->_cache_dir, $c_file, $extended); /* If the current vCal cache did not expire, we can deliver it */ if (!$this->cache->expired($files)) { return $this->cache->loadVcal(); } // Create the new iCalendar. $vCal = new Horde_Icalendar(); $vCal->setAttribute('PRODID', '-//kolab.org//NONSGML Kolab Server 2//EN'); $vCal->setAttribute('METHOD', 'PUBLISH'); // Create new vFreebusy. $vFb = Horde_Icalendar::newComponent('vfreebusy', $vCal); $params = array(); $cn = $access->owner_object->get(Horde_Kolab_Server_Object_Kolab_User::ATTRIBUTE_CN); if (!empty($cn) || is_a($cn, 'PEAR_Error')) { $params['cn'] = $access->owner_object->get(Horde_Kolab_Server_Object_Kolab_User::ATTRIBUTE_CN); } $vFb->setAttribute('ORGANIZER', 'MAILTO:' . $access->owner, $params); $vFb->setAttribute('DTSTAMP', time()); if (isset($_SERVER['SERVER_NAME'])) { $host = $_SERVER['SERVER_NAME']; } else { $host = 'localhost'; } if (isset($_SERVER['REQUEST_URI'])) { $uri = $_SERVER['REQUEST_URI']; } else { $uri = '/'; } $vFb->setAttribute('URL', 'http://' . $host . $uri); $mtimes = array(); foreach ($files as $file) { if ($extended && !empty($conf['fb']['use_acls'])) { $extended_pvc = $this->_allowExtended($file, $access); } else { $extended_pvc = $extended; } $c_pvcal = new Horde_Kolab_FreeBusy_Cache_File_pvcal($this->_cache_dir, $file); $pvCal = $c_pvcal->loadPVcal($extended_pvc); if (is_a($pvCal, 'PEAR_Error')) { Horde::log(sprintf("Ignoring partial free/busy file %s: %s)", $file, $pvCal->getMessage()), 'INFO'); continue; } $pvFb =& $pvCal->findComponent('vfreebusy'); if (!$pvFb) { Horde::log(sprintf("Could not find free/busy info in file %s.)", $file), 'INFO'); continue; } if ($ets = $pvFb->getAttributeDefault('DTEND', false) !== false) { // PENDING(steffen): Make value configurable if ($ets < time()) { Horde::log(sprintf("Free/busy info in file %s is too old.)", $file), 'INFO'); $c_pvcal->purge(); continue; } } $vFb->merge($pvFb); /* Store last modification time */ $mtimes[$file] = array($c_pvcal->getFile(), $c_pvcal->getMtime()); } if (!empty($conf['fb']['remote_servers'])) { $remote_vfb = $this->_fetchRemote($conf['fb']['remote_servers'], $access); if (is_a($remote_vfb, 'PEAR_Error')) { Horde::log(sprintf("Ignoring remote free/busy files: %s)", $remote_vfb->getMessage()), 'INFO'); } else { $vFb->merge($remote_vfb); } } if (!(bool) $vFb->getBusyPeriods()) { /* No busy periods in fb list. We have to add a * dummy one to be standards compliant */ $vFb->setAttribute('COMMENT', 'This is a dummy vfreebusy that indicates an empty calendar'); $vFb->addBusyPeriod('BUSY', 0, 0, null); } $vCal->addComponent($vFb); $c_vcal->storeVcal($vCal, $mtimes); return $vCal; $result = $this->app->getCache->load($access, $extended); // if (is_a($result, 'PEAR_Error')) { // $error = array('type' => FREEBUSY_ERROR_NOTFOUND, 'error' => $result); //$data = array('fb' => $result, 'name' => $access->owner . '.vfb'); //$view = &new Horde_Kolab_FreeBusy_View_vfb($data); }
/** * Export a memo, identified by UID, in the requested contentType. * * @param string $uid Identify the memo to export. * @param string $contentType What format should the data be in? * A string with one of: * <pre> * 'text/plain' * 'text/x-vnote' * 'activesync' * </pre> * @param array $options Any additional options to be passed to the * exporter. * * @return mixed The requested data * @throws Mnemo_Exception * @throws Horde_Exception_PermissionDenied */ public function export($uid, $contentType, array $options = array()) { $storage = $GLOBALS['injector']->getInstance('Mnemo_Factory_Driver')->create(); $memo = $storage->getByUID($uid); if (!array_key_exists($memo['memolist_id'], Mnemo::listNotepads(false, Horde_Perms::READ))) { throw new Horde_Exception_PermissionDenied(); } switch ($contentType) { case 'text/plain': return $memo['body']; case 'text/x-vnote': // Create the new iCalendar container. $iCal = new Horde_Icalendar('1.1'); $iCal->setAttribute('VERSION', '1.1'); $iCal->setAttribute('PRODID', '-//The Horde Project//Mnemo ' . $GLOBALS['registry']->getVersion() . '//EN'); $iCal->setAttribute('METHOD', 'PUBLISH'); // Create a new vNote. $vNote = $storage->toiCalendar($memo, $iCal); return $vNote->exportvCalendar(); case 'activesync': return $storage->toASNote($memo, $options); } throw new Mnemo_Exception(sprintf(_("Unsupported Content-Type: %s"), $contentType)); }
/** * Exports a calendar in the requested content type. * * @param string $calendar The calendar to export. * @param string $contentType What format should the data be in? * A string with one of: * <pre> * text/calendar (VCALENDAR 2.0. Recommended as * this is specified in rfc2445) * text/x-vcalendar (old VCALENDAR 1.0 format. * Still in wide use) * </pre> * * @return string The iCalendar representation of the calendar. * @throws Kronolith_Exception */ public function exportCalendar($calendar, $contentType) { if (!Kronolith::hasPermission($calendar, Horde_Perms::READ)) { throw new Horde_Exception_PermissionDenied(); } $kronolith_driver = Kronolith::getDriver(null, $calendar); $events = $kronolith_driver->listEvents(null, null, array('cover_dates' => false, 'hide_exceptions' => true)); $version = '2.0'; switch ($contentType) { case 'text/x-vcalendar': $version = '1.0'; case 'text/calendar': $share = $GLOBALS['injector']->getInstance('Kronolith_Shares')->getShare($calendar); $iCal = new Horde_Icalendar($version); $iCal->setAttribute('X-WR-CALNAME', $share->get('name')); if (strlen($share->get('desc'))) { $iCal->setAttribute('X-WR-CALDESC', $share->get('desc')); } foreach ($events as $dayevents) { foreach ($dayevents as $event) { $iCal->addComponent($event->toiCalendar($iCal)); } } return $iCal->exportvCalendar(); } throw new Kronolith_Exception(sprintf(_("Unsupported Content-Type: %s"), $contentType)); }
protected function _tovTodo() { $iCal = new Horde_Icalendar(); $iCal->setAttribute('METHOD', $this->_method); $vtodo = Horde_Icalendar::newComponent('vtodo', $iCal); $vtodo->setAttribute('UID', $this->_guid); // For REQUESTS, we MUST have the ORGANIZER and an ATTENDEE. if ($this->_state == self::STATE_ASSIGNERS_COPY || $this->_ownership == self::OWNERSHIP_ASSIGNERS_COPY) { // When sending a REQUEST the lastUser to edit it should be the // ORGANIZER. I can't find any of the other properties that work // consistently. $vtodo->setAttribute('ORGANIZER', 'mailto: ' . $this->_lastUser); $list = new Horde_Mail_Rfc822_List($this->_owner); foreach ($list as $email) { $vtodo->setAttribute('ATTENDEE', $email, array('ROLE' => 'REQ-PARTICIPANT')); } } if ($this->_due) { $vtodo->setAttribute('DUE', $this->_due); } if ($this->_start) { $vtodo->setAttribute('DTSTART', $this->_start); } if ($this->_completed) { $vtodo->setAttribute('COMPLETED', $this->_completed); } if (isset($this->_percentComplete)) { $vtodo->setAttribute('PERCENT-COMPLETE', $this->_percentComplete); } // Summary is stored in the message data. $msg = $this->_options['parent']->getMsgInfo(); if ($msg->subject) { $vtodo->setAttribute('SUMMARY', $msg->subject); } // Figure out the body. if ($this->_bodyPlain) { $vtodo->setAttribute('DESCRIPTION', $this->_bodyPlain); } elseif ($this->_bodyHtml) { $vtodo->setAttribute('DESCRIPTION', Horde_Text_Filter::filter($this->_bodyHtml, 'html2text')); } $iCal->addComponent($vtodo); return array('type' => 'text', 'subtype' => 'calendar', 'name' => $msg->subject ? $msg->subject . '.vtodo' : 'Untitled.vtodo', 'stream' => $iCal->exportvCalendar()); }
/** * Variables required in form input: * - identity (TODO: ? Code uses it, but it is never set anywhere) * - imple_submit: itip_action(s) * - mime_id * - muid * * @return boolean True on success. */ protected function _handle(Horde_Variables $vars) { global $injector, $notification, $registry; $actions = (array) $vars->imple_submit; $result = false; $vCal = new Horde_Icalendar(); /* Retrieve the calendar data from the message. */ try { $contents = $injector->getInstance('IMP_Factory_Contents')->create(new IMP_Indices_Mailbox($vars)); $mime_part = $contents->getMIMEPart($vars->mime_id); if (empty($mime_part)) { throw new IMP_Exception(_("Cannot retrieve calendar data from message.")); } elseif (!$vCal->parsevCalendar($mime_part->getContents(), 'VCALENDAR', $mime_part->getCharset())) { throw new IMP_Exception(_("The calendar data is invalid")); } $components = $vCal->getComponents(); } catch (Exception $e) { $notification->push($e, 'horde.error'); $actions = array(); } foreach ($actions as $key => $action) { $pos = strpos($key, '['); $key = substr($key, $pos + 1, strlen($key) - $pos - 2); switch ($action) { case 'delete': // vEvent cancellation. if ($registry->hasMethod('calendar/delete')) { $guid = $components[$key]->getAttribute('UID'); $recurrenceId = null; try { // This is a cancellation of a recurring event instance. $recurrenceId = $components[$key]->getAttribute('RECURRENCE-ID'); $atts = $components[$key]->getAttribute('RECURRENCE-ID', true); $range = null; foreach ($atts as $att) { if (array_key_exists('RANGE', $att)) { $range = $att['RANGE']; } } } catch (Horde_Icalendar_Exception $e) { } try { $registry->call('calendar/delete', array($guid, $recurrenceId, $range)); $notification->push(_("Event successfully deleted."), 'horde.success'); $result = true; } catch (Horde_Exception $e) { $notification->push(sprintf(_("There was an error deleting the event: %s"), $e->getMessage()), 'horde.error'); } } else { $notification->push(_("This action is not supported."), 'horde.warning'); } break; case 'update': // vEvent reply. if ($registry->hasMethod('calendar/updateAttendee')) { try { $from = $contents->getHeader()->getOb('from'); $registry->call('calendar/updateAttendee', array($components[$key], $from[0]->bare_address)); $notification->push(_("Respondent Status Updated."), 'horde.success'); $result = true; } catch (Horde_Exception $e) { $notification->push(sprintf(_("There was an error updating the event: %s"), $e->getMessage()), 'horde.error'); } } else { $notification->push(_("This action is not supported."), 'horde.warning'); } break; case 'import': case 'accept-import': // vFreebusy reply. // vFreebusy publish. // vEvent request. // vEvent publish. // vTodo publish. // vJournal publish. switch ($components[$key]->getType()) { case 'vEvent': $result = $this->_handlevEvent($key, $components, $mime_part); // Must check for exceptions. foreach ($components as $k => $component) { try { if ($component->getType() == 'vEvent' && $component->getAttribute('RECURRENCE-ID')) { $uid = $component->getAttribute('UID'); if ($uid == $components[$key]->getAttribute('UID')) { $this->_handlevEvent($k, $components, $mime_part); } } } catch (Horde_Icalendar_Exception $e) { } } break; case 'vFreebusy': // Import into Kronolith. if ($registry->hasMethod('calendar/import_vfreebusy')) { try { $registry->call('calendar/import_vfreebusy', array($components[$key])); $notification->push(_("The user's free/busy information was sucessfully stored."), 'horde.success'); $result = true; } catch (Horde_Exception $e) { $notification->push(sprintf(_("There was an error importing user's free/busy information: %s"), $e->getMessage()), 'horde.error'); } } else { $notification->push(_("This action is not supported."), 'horde.warning'); } break; case 'vTodo': // Import into Nag. if ($registry->hasMethod('tasks/import')) { try { $guid = $registry->call('tasks/import', array($components[$key], $mime_part->getType())); $url = Horde::url($registry->link('tasks/show', array('uid' => $guid))); $notification->push(_("The task has been added to your tasklist.") . ' ' . Horde::link($url, _("View task"), null, '_blank') . Horde_Themes_Image::tag('mime/icalendar.png', array('alt' => _("View task"))) . '</a>', 'horde.success', array('content.raw')); $result = true; } catch (Horde_Exception $e) { $notification->push(sprintf(_("There was an error importing the task: %s"), $e->getMessage()), 'horde.error'); } } else { $notification->push(_("This action is not supported."), 'horde.warning'); } break; case 'vJournal': default: $notification->push(_("This action is not supported."), 'horde.warning'); } if ($action == 'import') { break; } // Fall-through for 'accept-import' // Fall-through for 'accept-import' case 'accept': case 'deny': case 'tentative': // vEvent request. if (isset($components[$key]) && $components[$key]->getType() == 'vEvent') { $vEvent = $components[$key]; $resource = new Horde_Itip_Resource_Identity($injector->getInstance('IMP_Identity'), $vEvent->getAttribute('ATTENDEE'), $vars->identity); switch ($action) { case 'accept': case 'accept-import': $type = new Horde_Itip_Response_Type_Accept($resource); break; case 'deny': $type = new Horde_Itip_Response_Type_Decline($resource); break; case 'tentative': $type = new Horde_Itip_Response_Type_Tentative($resource); break; } try { // Send the reply. Horde_Itip::factory($vEvent, $resource)->sendMultiPartResponse($type, new Horde_Core_Itip_Response_Options_Horde('UTF-8', array()), $injector->getInstance('IMP_Mail')); $notification->push(_("Reply Sent."), 'horde.success'); $result = true; } catch (Horde_Itip_Exception $e) { $notification->push(sprintf(_("Error sending reply: %s."), $e->getMessage()), 'horde.error'); } } else { $notification->push(_("This action is not supported."), 'horde.warning'); } break; case 'send': case 'reply': case 'reply2m': // vfreebusy request. if (isset($components[$key]) && $components[$key]->getType() == 'vFreebusy') { $vFb = $components[$key]; // Get the organizer details. try { $organizer = parse_url($vFb->getAttribute('ORGANIZER')); } catch (Horde_Icalendar_Exception $e) { break; } $organizerEmail = $organizer['path']; $organizer = $vFb->getAttribute('ORGANIZER', true); $organizerFullEmail = new Horde_Mail_Rfc822_Address($organizerEmail); if (isset($organizer['cn'])) { $organizerFullEmail->personal = $organizer['cn']; } if ($action == 'reply2m') { $startStamp = time(); $endStamp = $startStamp + 60 * 24 * 3600; } else { try { $startStamp = $vFb->getAttribute('DTSTART'); } catch (Horde_Icalendar_Exception $e) { $startStamp = time(); } try { $endStamp = $vFb->getAttribute('DTEND'); } catch (Horde_Icalendar_Exception $e) { } if (!$endStamp) { try { $duration = $vFb->getAttribute('DURATION'); $endStamp = $startStamp + $duration; } catch (Horde_Icalendar_Exception $e) { $endStamp = $startStamp + 60 * 24 * 3600; } } } $vfb_reply = $registry->call('calendar/getFreeBusy', array($startStamp, $endStamp)); // Find out who we are and update status. $identity = $injector->getInstance('IMP_Identity'); $email = $identity->getFromAddress(); // Build the reply. $msg_headers = new Horde_Mime_Headers(); $vCal = new Horde_Icalendar(); $vCal->setAttribute('PRODID', '-//The Horde Project//' . $msg_headers->getUserAgent() . '//EN'); $vCal->setAttribute('METHOD', 'REPLY'); $vCal->addComponent($vfb_reply); $message = _("Attached is a reply to a calendar request you sent."); $body = new Horde_Mime_Part(); $body->setType('text/plain'); $body->setCharset('UTF-8'); $body->setContents(Horde_String::wrap($message, 76)); $ics = new Horde_Mime_Part(); $ics->setType('text/calendar'); $ics->setCharset('UTF-8'); $ics->setContents($vCal->exportvCalendar()); $ics->setName('icalendar.ics'); $ics->setContentTypeParameter('METHOD', 'REPLY'); $mime = new Horde_Mime_Part(); $mime->addPart($body); $mime->addPart($ics); // Build the reply headers. $msg_headers->addReceivedHeader(array('dns' => $injector->getInstance('Net_DNS2_Resolver'), 'server' => $conf['server']['name'])); $msg_headers->addMessageIdHeader(); $msg_headers->addHeader('Date', date('r')); $msg_headers->addHeader('From', $email); $msg_headers->addHeader('To', $organizerFullEmail); $identity->setDefault($vars->identity); $replyto = $identity->getValue('replyto_addr'); if (!empty($replyto) && !$email->match($replyto)) { $msg_headers->addHeader('Reply-To', $replyto); } $msg_headers->addHeader('Subject', _("Free/Busy Request Response")); // Send the reply. try { $mime->send($organizerEmail, $msg_headers, $injector->getInstance('IMP_Mail')); $notification->push(_("Reply Sent."), 'horde.success'); $result = true; } catch (Exception $e) { $notification->push(sprintf(_("Error sending reply: %s."), $e->getMessage()), 'horde.error'); } } else { $notification->push(_("Invalid Action selected for this component."), 'horde.warning'); } break; case 'nosup': // vFreebusy request. // vFreebusy request. default: $notification->push(_("This action is not supported."), 'horde.warning'); break; } } return $result; }
/** * Copies or moves a list of messages to a tasklist or notepad. * Handles search and Trash mailboxes. * * @param string $list The list in which the task or note will be * created. * @param string $action Either 'copy' or 'move'. * @param IMP_Indices $indices An indices object. * @param string $type The object type to create ('note' or * 'task'). */ protected function _createTasksOrNotes($list, $action, IMP_Indices $indices, $type) { global $injector, $registry, $notification; foreach ($indices as $ob) { foreach ($ob->uids as $uid) { /* Fetch the message contents. */ $imp_contents = $injector->getInstance('IMP_Factory_Contents')->create($ob->mbox->getIndicesOb($uid)); /* Fetch the message headers. */ $imp_headers = $imp_contents->getHeader(); $subject = $imp_headers->getValue('subject'); /* Re-flow the message for prettier formatting. */ $body_part = $imp_contents->getMIMEPart($imp_contents->findBody()); $flowed = new Horde_Text_Flowed($body_part->getContents()); if ($body_part->getContentTypeParameter('delsp') == 'yes') { $flowed->setDelSp(true); } $body = $flowed->toFlowed(false); /* Convert to current charset */ /* TODO: When Horde_Icalendar supports setting of charsets * we need to set it there instead of relying on the fact * that both Nag and IMP use the same charset. */ $body = Horde_String::convertCharset($body, $body_part->getCharset(), 'UTF-8'); /* Create a new iCalendar. */ $vCal = new Horde_Icalendar(); $vCal->setAttribute('PRODID', '-//The Horde Project//IMP ' . $registry->getVersion() . '//EN'); $vCal->setAttribute('METHOD', 'PUBLISH'); switch ($type) { case 'task': /* Create a new vTodo object using this message's * contents. */ $vTodo = Horde_Icalendar::newComponent('vtodo', $vCal); $vTodo->setAttribute('SUMMARY', $subject); $vTodo->setAttribute('DESCRIPTION', $body); $vTodo->setAttribute('PRIORITY', '3'); /* Get the list of editable tasklists. */ try { $lists = $registry->call('tasks/listTasklists', array(false, Horde_Perms::EDIT)); } catch (Horde_Exception $e) { $lists = null; $notification->push($e); } /* Attempt to add the new vTodo item to the requested * tasklist. */ try { $res = $registry->call('tasks/import', array($vTodo, 'text/calendar', $list)); } catch (Horde_Exception $e) { $res = null; $notification->push($e); } break; case 'note': /* Create a new vNote object using this message's * contents. */ $vNote = Horde_Icalendar::newComponent('vnote', $vCal); $vNote->setAttribute('BODY', $subject . "\n" . $body); /* Get the list of editable notepads. */ try { $lists = $registry->call('notes/listNotepads', array(false, Horde_Perms::EDIT)); } catch (Horde_Exception $e) { $lists = null; $notification->push($e); } /* Attempt to add the new vNote item to the requested * notepad. */ try { $res = $registry->call('notes/import', array($vNote, 'text/x-vnote', $list)); } catch (Horde_Exception $e) { $res = null; $notification->push($e); } break; } if (!is_null($res)) { if (!$res) { switch ($type) { case 'task': $notification->push(_("An unknown error occured while creating the new task."), 'horde.error'); break; case 'note': $notification->push(_("An unknown error occured while creating the new note."), 'horde.error'); break; } } elseif (!is_null($lists)) { $name = '"' . htmlspecialchars($subject) . '"'; /* Attempt to convert the object name into a * hyperlink. */ try { switch ($type) { case 'task': $link = $registry->link('tasks/show', array('uid' => $res)); break; case 'note': $link = $registry->hasMethod('notes/show') ? $registry->link('notes/show', array('uid' => $res)) : false; break; } if ($link) { $name = sprintf('<a href="%s">%s</a>', Horde::url($link), $name); } $notification->push(sprintf(_("%s was successfully added to \"%s\"."), $name, htmlspecialchars($lists[$list]->get('name'))), 'horde.success', array('content.raw')); } catch (Horde_Exception $e) { } } } } } /* Delete the original messages if this is a "move" operation. */ if ($action == 'move') { $this->delete($indices); } }