--- /dev/null
+
+ - Merge with Horde Imp
+ - Complete unit testing
--- /dev/null
+<?php
+/**
+ * Handles iTip invitation requests/responses.
+ *
+ * PHP version 5
+ *
+ * @category Horde
+ * @package Itip
+ * @author Gunnar Wrobel <wrobel@pardus.de>
+ * @license http://www.fsf.org/copyleft/lgpl.html LGPL
+ * @link http://pear.horde.org/index.php?package=Itip
+ */
+
+/**
+ * Handles iTip invitation requests/responses.
+ *
+ * Copyright 2010 Klarälvdalens Datakonsult AB
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you did not
+ * receive this file, see
+ * http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+ *
+ * @category Horde
+ * @package Itip
+ * @author Gunnar Wrobel <wrobel@pardus.de>
+ * @license http://www.fsf.org/copyleft/lgpl.html LGPL
+ * @link http://pear.horde.org/index.php?package=Itip
+ */
+class Horde_Itip
+{
+ /**
+ * The iTip response.
+ *
+ * @var Horde_Itip_Response
+ */
+ private $_response;
+
+ /**
+ * Constructor.
+ *
+ * @param Horde_Itip_Response $response The iTip response.
+ */
+ public function __construct(
+ Horde_Itip_Response $response
+ ) {
+ $this->_response = $response;
+ }
+
+ /**
+ * Return the response as an iCalendar vEvent object.
+ *
+ * @param Horde_Itip_Response_Type $type The response type.
+ *
+ * @return Horde_iCalendar_vevent The response object.
+ */
+ public function getVeventResponse(
+ Horde_Itip_Response_Type $type
+ ) {
+ return $this->_response->getVevent(
+ $type, false
+ );
+ }
+
+ /**
+ * Return the response as an iCalendar object.
+ *
+ * @param Horde_Itip_Response_Type $type The response type.
+ * @param string $product_id The ID that should be set as
+ * the iCalendar product id.
+ *
+ * @return Horde_iCalendar The response object.
+ */
+ public function getIcalendarResponse(
+ Horde_Itip_Response_Type $type,
+ $product_id
+ ) {
+ return $this->_response->getIcalendar(
+ $type, $product_id
+ );
+ }
+
+ /**
+ * Return the response as a MIME message.
+ *
+ * @param Horde_Itip_Response_Type $type The response type.
+ * @param string $product_id The ID that should be set
+ * as the iCalendar product
+ * id.
+ * @param string $subject_comment An optional comment on
+ * the subject line.
+ *
+ * @return array A list of two object: The mime headers and the mime
+ * message.
+ */
+ public function getMessageResponse(
+ Horde_Itip_Response_Type $type,
+ $product_id,
+ $subject_comment = null
+ ) {
+ return $this->_response->getMessage(
+ $type, $product_id, $subject_comment
+ );
+ }
+
+ /**
+ * Factory for generating a response object for an iCalendar invitation.
+ *
+ * @param Horde_iCalendar_vevent $vevent The iCalendar request.
+ * @param Horde_Itip_Resource $resource The invited resource.
+ *
+ * @return Horde_Itip_Response The prepared response.
+ */
+ static public function prepareResponse(
+ Horde_iCalendar_vevent $vevent,
+ Horde_Itip_Resource $resource
+ ) {
+ return new Horde_Itip_Response(
+ new Horde_Itip_Event_Vevent(
+ $vevent
+ ),
+ $resource
+ );
+ }
+
+ /**
+ * Factory for generating an iTip handler for an iCalendar invitation.
+ *
+ * @param Horde_iCalendar_vevent $vevent The iCalendar request.
+ * @param Horde_Itip_Resource $resource The invited resource.
+ *
+ * @return Horde_Itip The iTip handler.
+ */
+ static public function factory(
+ Horde_iCalendar_vevent $vevent,
+ Horde_Itip_Resource $resource
+ ) {
+ return new Horde_Itip(
+ self::prepareResponse($vevent, $resource)
+ );
+ }
+}
\ No newline at end of file
--- /dev/null
+<?php
+/**
+ * Defines the event interface required for iTip-Handling / resource booking.
+ *
+ * PHP version 5
+ *
+ * @category Horde
+ * @package Itip
+ * @author Gunnar Wrobel <wrobel@pardus.de>
+ * @license http://www.fsf.org/copyleft/lgpl.html LGPL
+ * @link http://pear.horde.org/index.php?package=Itip
+ */
+
+/**
+ * Defines the event interface required for iTip-Handling / resource booking.
+ *
+ * Copyright 2010 Klarälvdalens Datakonsult AB
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you did not
+ * receive this file, see
+ * http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+ *
+ * @category Horde
+ * @package Itip
+ * @author Gunnar Wrobel <wrobel@pardus.de>
+ * @license http://www.fsf.org/copyleft/lgpl.html LGPL
+ * @link http://pear.horde.org/index.php?package=Itip
+ */
+interface Horde_Itip_Event
+{
+ /**
+ * Returns the event as vEvent.
+ *
+ * @return Horde_iCalendar_vevent The wrapped event.
+ */
+ public function getVevent();
+
+ /**
+ * Return the method of the iTip request.
+ *
+ * @return string The method of the request.
+ */
+ public function getMethod();
+
+ /**
+ * Return the uid of the iTip event.
+ *
+ * @return string The uid of the event.
+ */
+ public function getUid();
+
+ /**
+ * Return the summary for the event.
+ *
+ * @return string The summary.
+ */
+ public function getSummary();
+
+ /**
+ * Return the start of the iTip event.
+ *
+ * @return string The start of the event.
+ */
+ public function getStart();
+
+ /**
+ * Return the end of the iTip event.
+ *
+ * @return string The end of the event.
+ */
+ public function getEnd();
+
+ /**
+ * Return the organizer of the iTip event.
+ *
+ * @return string The organizer of the event.
+ */
+ public function getOrganizer();
+
+ /**
+ * Copy the details from an event into this one.
+ *
+ * @param Horde_Itip_Event $event The event to copy from.
+ *
+ * @return NULL
+ */
+ public function copyEventInto(Horde_Itip_Event $event);
+
+ /**
+ * Set the attendee parameters.
+ *
+ * @param string $attendee The mail address of the attendee.
+ * @param string $common_name Common name of the attendee.
+ * @param string $status Attendee status (ACCPETED, DECLINED, TENTATIVE)
+ *
+ * @return NULL
+ */
+ public function setAttendee($attendee, $common_name, $status);
+
+ public function getKolabObject();
+
+ public function setAccepted($resource);
+}
\ No newline at end of file
--- /dev/null
+<?php
+/**
+ * A wrapper for vEvent iCalender data.
+ *
+ * PHP version 5
+ *
+ * @category Kolab
+ * @package Kolab_Filter
+ * @author Gunnar Wrobel <wrobel@pardus.de>
+ * @license http://www.fsf.org/copyleft/lgpl.html LGPL
+ * @link http://pear.horde.org/index.php?package=Kolab_Server
+ */
+
+/**
+ * A wrapper for vEvent iCalender data.
+ *
+ * Copyright 2010 Klarälvdalens Datakonsult AB
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you did not
+ * receive this file, see
+ * http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+ *
+ * @category Kolab
+ * @package Kolab_Filter
+ * @author Gunnar Wrobel <wrobel@pardus.de>
+ * @license http://www.fsf.org/copyleft/lgpl.html LGPL
+ * @link http://pear.horde.org/index.php?package=Kolab_Server
+ */
+class Horde_Itip_Event_Vevent
+implements Horde_Itip_Event
+{
+ /**
+ * The wrapped vEvent.
+ *
+ * @var Horde_iCalendar_vevent
+ */
+ private $_vevent;
+
+ /**
+ * Constructor.
+ *
+ * @param Horde_iCalendar_vevent $vevent The iCalendar object that will be
+ * wrapped by this instance.
+ */
+ public function __construct(Horde_iCalendar_vevent $vevent)
+ {
+ $this->_vevent = $vevent;
+ }
+
+ /**
+ * Returns the wrapped vEvent.
+ *
+ * @return Horde_iCalendar_vevent The wrapped event.
+ */
+ public function getVevent()
+ {
+ return $this->_vevent;
+ }
+
+ /**
+ * Return the method of the iTip request.
+ *
+ * @return string The method of the request.
+ */
+ public function getMethod()
+ {
+ return $this->_vevent->getAttributeDefault('METHOD', 'REQUEST');
+ }
+
+ /**
+ * Return the uid of the iTip event.
+ *
+ * @return string The uid of the event.
+ */
+ public function getUid()
+ {
+ return $this->_vevent->getAttributeDefault('UID', '');
+ }
+
+ /**
+ * Return the summary for the event.
+ *
+ * @return string|PEAR_Error The summary.
+ */
+ public function getSummary()
+ {
+ return $this->_vevent->getAttributeDefault('SUMMARY', _("No summary available"));
+ }
+
+ /**
+ * Return the start of the iTip event.
+ *
+ * @return string The start of the event.
+ */
+ public function getStart()
+ {
+ return $this->_vevent->getAttributeDefault('DTSTART', 0);
+ }
+
+ /**
+ * Return the end of the iTip event.
+ *
+ * @return string The end of the event.
+ */
+ public function getEnd()
+ {
+ return $this->_vevent->getAttributeDefault('DTEND', 0);
+ }
+
+ /**
+ * Return the organizer of the iTip event.
+ *
+ * @return string The organizer of the event.
+ */
+ public function getOrganizer()
+ {
+ return preg_replace('/^mailto:\s*/i', '', $this->_vevent->getAttributeDefault('ORGANIZER', ''));
+ }
+
+ /**
+ * Copy the details from an event into this one.
+ *
+ * @param Horde_Itip_Event $event The event to copy from.
+ *
+ * @return NULL
+ */
+ public function copyEventInto(Horde_Itip_Event $event)
+ {
+ $this->copyUid($event);
+ $this->copySummary($event);
+ $this->copyDescription($event);
+ $this->copyStart($event);
+ $this->copyEndOrDuration($event);
+ $this->copySequence($event);
+ $this->copyLocation($event);
+ $this->copyOrganizer($event);
+ }
+
+ /**
+ * Set the attendee parameters.
+ *
+ * @param string $attendee The mail address of the attendee.
+ * @param string $common_name Common name of the attendee.
+ * @param string $status Attendee status (ACCPETED, DECLINED, TENTATIVE)
+ *
+ * @return NULL
+ */
+ public function setAttendee($attendee, $common_name, $status)
+ {
+ $this->_vevent->setAttribute(
+ 'ATTENDEE',
+ 'MAILTO:' . $attendee,
+ array(
+ 'CN' => $common_name,
+ 'PARTSTAT' => $status
+ )
+ );
+ }
+
+ public function getKolabObject()
+ {
+ $object = array();
+ $object['uid'] = $this->getUid();
+
+ $org_params = $this->_vevent->getAttribute('ORGANIZER', true);
+ if (!is_a( $org_params, 'PEAR_Error')) {
+ if (!empty($org_params[0]['CN'])) {
+ $object['organizer']['display-name'] = $org_params[0]['CN'];
+ }
+ $orgemail = $this->_vevent->getAttributeDefault('ORGANIZER', '');
+ if (preg_match('/mailto:(.*)/i', $orgemail, $regs )) {
+ $orgemail = $regs[1];
+ }
+ $object['organizer']['smtp-address'] = $orgemail;
+ }
+ $object['summary'] = $this->_vevent->getAttributeDefault('SUMMARY', '');
+ $object['location'] = $this->_vevent->getAttributeDefault('LOCATION', '');
+ $object['body'] = $this->_vevent->getAttributeDefault('DESCRIPTION', '');
+ $dtend = $this->_vevent->getAttributeDefault('DTEND', '');
+ if (is_array($dtend)) {
+ $object['_is_all_day'] = true;
+ }
+ $start = new Horde_Kolab_Resource_Epoch($this->getStart());
+ $object['start-date'] = $start->getEpoch();
+ $end = new Horde_Kolab_Resource_Epoch($dtend);
+ $object['end-date'] = $end->getEpoch();
+
+ $attendees = $this->_vevent->getAttribute('ATTENDEE');
+ if (!is_a( $attendees, 'PEAR_Error')) {
+ $attendees_params = $this->_vevent->getAttribute('ATTENDEE', true);
+ if (!is_array($attendees)) {
+ $attendees = array($attendees);
+ }
+ if (!is_array($attendees_params)) {
+ $attendees_params = array($attendees_params);
+ }
+
+ $object['attendee'] = array();
+ for ($i = 0; $i < count($attendees); $i++) {
+ $attendee = array();
+ if (isset($attendees_params[$i]['CN'])) {
+ $attendee['display-name'] = $attendees_params[$i]['CN'];
+ }
+
+ $attendeeemail = $attendees[$i];
+ if (preg_match('/mailto:(.*)/i', $attendeeemail, $regs)) {
+ $attendeeemail = $regs[1];
+ }
+ $attendee['smtp-address'] = $attendeeemail;
+
+ if (!isset($attendees_params[$i]['RSVP'])
+ || $attendees_params[$i]['RSVP'] == 'FALSE') {
+ $attendee['request-response'] = false;
+ } else {
+ $attendee['request-response'] = true;
+ }
+
+ if (isset($attendees_params[$i]['ROLE'])) {
+ $attendee['role'] = $attendees_params[$i]['ROLE'];
+ }
+
+ if (isset($attendees_params[$i]['PARTSTAT'])) {
+ $status = strtolower($attendees_params[$i]['PARTSTAT']);
+ switch ($status) {
+ case 'needs-action':
+ case 'delegated':
+ $attendee['status'] = 'none';
+ break;
+ default:
+ $attendee['status'] = $status;
+ break;
+ }
+ }
+
+ $object['attendee'][] = $attendee;
+ }
+ }
+
+ // Alarm
+ $valarm = $this->_vevent->findComponent('VALARM');
+ if ($valarm) {
+ $trigger = $valarm->getAttribute('TRIGGER');
+ if (!is_a($trigger, 'PEAR_Error')) {
+ $p = $valarm->getAttribute('TRIGGER', true);
+ if ($trigger < 0) {
+ // All OK, enter the alarm into the XML
+ // NOTE: The Kolab XML format seems underspecified
+ // wrt. alarms currently...
+ $object['alarm'] = -$trigger / 60;
+ }
+ }
+ }
+
+ // Recurrence
+ $rrule_str = $this->_vevent->getAttribute('RRULE');
+ if (!is_a($rrule_str, 'PEAR_Error')) {
+ require_once 'Horde/Date/Recurrence.php';
+ $recurrence = new Horde_Date_Recurrence(time());
+ $recurrence->fromRRule20($rrule_str);
+ $object['recurrence'] = $recurrence->toHash();
+ }
+
+ return $object;
+ }
+
+ public function setAccepted($resource)
+ {
+ // Update our status within the iTip request and send the reply
+ $this->_vevent->setAttribute('STATUS', 'CONFIRMED', array(), false);
+ $attendees = $this->_vevent->getAttribute('ATTENDEE');
+ if (!is_array($attendees)) {
+ $attendees = array($attendees);
+ }
+ $attparams = $this->_vevent->getAttribute('ATTENDEE', true);
+ foreach ($attendees as $i => $attendee) {
+ $attendee = preg_replace('/^mailto:\s*/i', '', $attendee);
+ if ($attendee != $resource) {
+ continue;
+ }
+
+ $attparams[$i]['PARTSTAT'] = 'ACCEPTED';
+ if (array_key_exists('RSVP', $attparams[$i])) {
+ unset($attparams[$i]['RSVP']);
+ }
+ }
+
+ // Re-add all the attendees to the event, using our updates status info
+ $firstatt = array_pop($attendees);
+ $firstattparams = array_pop($attparams);
+ $this->_vevent->setAttribute('ATTENDEE', $firstatt, $firstattparams, false);
+ foreach ($attendees as $i => $attendee) {
+ $this->_vevent->setAttribute('ATTENDEE', $attendee, $attparams[$i]);
+ }
+ }
+
+ /**
+ * Set the uid of the iTip event.
+ *
+ * @param string $uid The uid of the event.
+ *
+ * @return NULL
+ */
+ private function setUid($uid)
+ {
+ $this->_vevent->setAttribute('UID', $uid);
+ }
+
+ /**
+ * Copy the uid from the request into the provided iTip instance.
+ *
+ * @return NULL
+ */
+ private function copyUid(Horde_Itip_Event $itip)
+ {
+ $itip->setUid($this->getUid());
+ }
+
+ /**
+ * Set the summary for the event.
+ *
+ * @param string $summary The summary.
+ *
+ * @return NULL
+ */
+ private function setSummary($summary)
+ {
+ $this->_vevent->setAttribute('SUMMARY', $summary);
+ }
+
+ /**
+ * Copy the summary from the request into the provided iTip instance.
+ *
+ * @return NULL
+ */
+ private function copySummary(Horde_Itip_Event $itip)
+ {
+ $itip->setSummary($this->getSummary());
+ }
+
+ /**
+ * Does the event have a description?
+ *
+ * @return boolean True if it has a description, false otherwise.
+ */
+ private function hasDescription()
+ {
+ return !($this->_vevent->getAttribute('DESCRIPTION') instanceOf PEAR_Error);
+ }
+
+ /**
+ * Return the description for the event.
+ *
+ * @return string|PEAR_Error The description.
+ */
+ private function getDescription()
+ {
+ return $this->_vevent->getAttribute('DESCRIPTION');
+ }
+
+ /**
+ * Set the description for the event.
+ *
+ * @param string $description The description.
+ *
+ * @return NULL
+ */
+ private function setDescription($description)
+ {
+ $this->_vevent->setAttribute('DESCRIPTION', $description);
+ }
+
+ /**
+ * Copy the description from the request into the provided iTip instance.
+ *
+ * @return NULL
+ */
+ private function copyDescription(Horde_Itip_Event $itip)
+ {
+ if ($this->hasDescription()) {
+ $itip->setDescription($this->getDescription());
+ }
+ }
+
+ /**
+ * Return the start parameters of the iTip event.
+ *
+ * @return array The start parameters of the event.
+ */
+ public function getStartParameters()
+ {
+ return array_pop($this->_vevent->getAttribute('DTSTART', true));
+ }
+
+ /**
+ * Set the start of the iTip event.
+ *
+ * @param string $start The start of the event.
+ * @param array $parameters Additional parameters.
+ *
+ * @return NULL
+ */
+ private function setStart($start, $parameters)
+ {
+ $this->_vevent->setAttribute('DTSTART', $start, $parameters);
+ }
+
+ /**
+ * Copy the start time from the request into the provided iTip instance.
+ *
+ * @return NULL
+ */
+ private function copyStart(Horde_Itip_Event $itip)
+ {
+ $itip->setStart($this->getStart(), $this->getStartParameters());
+ }
+
+ /**
+ * Does the event have an end?
+ *
+ * @return boolean True if it has an end, false otherwise.
+ */
+ private function hasEnd()
+ {
+ return !($this->_vevent->getAttribute('DTEND') instanceOf PEAR_Error);
+ }
+
+ /**
+ * Return the end parameters of the iTip event.
+ *
+ * @return array The end parameters of the event.
+ */
+ private function getEndParameters()
+ {
+ return array_pop($this->_vevent->getAttribute('DTEND', true));
+ }
+
+ /**
+ * Set the end of the iTip event.
+ *
+ * @param string $end The end of the event.
+ * @param array $parameters Additional parameters.
+ *
+ * @return NULL
+ */
+ private function setEnd($end, $parameters)
+ {
+ $this->_vevent->setAttribute('DTEND', $end, $parameters);
+ }
+
+ /**
+ * Return the duration for the event.
+ *
+ * @return string|PEAR_Error The duration of the event.
+ */
+ private function getDuration()
+ {
+ return $this->_vevent->getAttribute('DURATION');
+ }
+
+ /**
+ * Return the duration parameters of the iTip event.
+ *
+ * @return array The duration parameters of the event.
+ */
+ private function getDurationParameters()
+ {
+ return array_pop($this->_vevent->getAttribute('DURATION', true));
+ }
+
+ /**
+ * Set the duration of the iTip event.
+ *
+ * @param string $duration The duration of the event.
+ * @param array $parameters Additional parameters.
+ *
+ * @return NULL
+ */
+ private function setDuration($duration, $parameters)
+ {
+ $this->_vevent->setAttribute('DURATION', $duration, $parameters);
+ }
+
+ /**
+ * Copy the end time or event duration from the request into the provided
+ * iTip instance.
+ *
+ * @return NULL
+ */
+ private function copyEndOrDuration(Horde_Itip_Event $itip)
+ {
+ if ($this->hasEnd()) {
+ $itip->setEnd($this->getEnd(), $this->getEndParameters());
+ } else {
+ $itip->setDuration($this->getDuration(), $this->getDurationParameters());
+ }
+ }
+
+ /**
+ * Return the sequence for the event.
+ *
+ * @return string|PEAR_Error The sequence.
+ */
+ private function getSequence()
+ {
+ return $this->_vevent->getAttributeDefault('SEQUENCE', 0);
+ }
+
+ /**
+ * Set the sequence for the event.
+ *
+ * @param string $sequence The sequence.
+ *
+ * @return NULL
+ */
+ private function setSequence($sequence)
+ {
+ $this->_vevent->setAttribute('SEQUENCE', $sequence);
+ }
+ /**
+ * Copy the sequence from the request into the provided iTip instance.
+ *
+ * @return NULL
+ */
+ private function copySequence(Horde_Itip_Event $itip)
+ {
+ $itip->setSequence($this->getSequence());
+ }
+
+ /**
+ * Does the event have a location?
+ *
+ * @return boolean True if it has a location, false otherwise.
+ */
+ private function hasLocation()
+ {
+ return !($this->_vevent->getAttribute('LOCATION') instanceOf PEAR_Error);
+ }
+
+ /**
+ * Return the location for the event.
+ *
+ * @return string|PEAR_Error The location.
+ */
+ private function getLocation()
+ {
+ return $this->_vevent->getAttribute('LOCATION');
+ }
+
+ /**
+ * Set the location for the event.
+ *
+ * @param string $location The location.
+ *
+ * @return NULL
+ */
+ private function setLocation($location)
+ {
+ $this->_vevent->setAttribute('LOCATION', $location);
+ }
+
+ /**
+ * Copy the location from the request into the provided iTip instance.
+ *
+ * @return NULL
+ */
+ private function copyLocation(Horde_Itip_Event $itip)
+ {
+ if ($this->hasLocation()) {
+ $itip->setLocation($this->getLocation());
+ }
+ }
+
+ /**
+ * Return the organizer for the event.
+ *
+ * @return string|PEAR_Error The organizer of the event.
+ */
+ private function getRawOrganizer()
+ {
+ return $this->_vevent->getAttribute('ORGANIZER');
+ }
+
+ /**
+ * Return the organizer parameters of the iTip event.
+ *
+ * @return array The organizer parameters of the event.
+ */
+ private function getOrganizerParameters()
+ {
+ return array_pop($this->_vevent->getAttribute('ORGANIZER', true));
+ }
+
+ /**
+ * Set the organizer of the iTip event.
+ *
+ * @param string $organizer The organizer of the event.
+ * @param array $parameters Additional parameters.
+ *
+ * @return NULL
+ */
+ private function setOrganizer($organizer, $parameters)
+ {
+ $this->_vevent->setAttribute('ORGANIZER', $organizer, $parameters);
+ }
+
+ /**
+ * Copy the organizer from the request into the provided iTip instance.
+ *
+ * @return NULL
+ */
+ private function copyOrganizer(Horde_Itip_Event $itip)
+ {
+ $itip->setOrganizer($this->getRawOrganizer(), $this->getOrganizerParameters());
+ }
+}
\ No newline at end of file
--- /dev/null
+<?php
+/**
+ * This class provides the standard error class for Horde_Itip exceptions.
+ *
+ * PHP version 5
+ *
+ * @category Horde
+ * @package Itip
+ * @author Gunnar Wrobel <wrobel@pardus.de>
+ * @license http://www.fsf.org/copyleft/lgpl.html LGPL
+ * @link http://pear.horde.org/index.php?package=Itip
+ */
+
+/**
+ * This class provides the standard error class for Horde_Itip exceptions.
+ *
+ * Copyright 2010 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
+ *
+ * @category Horde
+ * @package Itip
+ * @author Gunnar Wrobel <wrobel@pardus.de>
+ * @license http://www.fsf.org/copyleft/lgpl.html LGPL
+ * @link http://pear.horde.org/index.php?package=Itip
+ */
+class Horde_Itip_Exception extends Exception
+{
+}
--- /dev/null
+<?php
+/**
+ * Provides information about an invited resource.
+ *
+ * PHP version 5
+ *
+ * @category Horde
+ * @package Itip
+ * @author Gunnar Wrobel <wrobel@pardus.de>
+ * @license http://www.fsf.org/copyleft/lgpl.html LGPL
+ * @link http://pear.horde.org/index.php?package=Itip
+ */
+
+/**
+ * Provides information about an invited resource.
+ *
+ * Copyright 2010 Kolab Systems AG
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you did not
+ * receive this file, see
+ * http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+ *
+ * @category Horde
+ * @package Itip
+ * @author Gunnar Wrobel <wrobel@pardus.de>
+ * @license http://www.fsf.org/copyleft/lgpl.html LGPL
+ * @link http://pear.horde.org/index.php?package=Itip
+ */
+interface Horde_Itip_Resource
+{
+ /**
+ * Retrieve the mail address of the resource.
+ *
+ * @return string The mail address.
+ */
+ public function getMailAddress();
+
+ /**
+ * Retrieve the common name of the resource.
+ *
+ * @return string The common name.
+ */
+ public function getCommonName();
+
+ /**
+ * Retrieve the "From" address for this resource.
+ *
+ * @return string The "From" address.
+ */
+ public function getFrom();
+}
\ No newline at end of file
--- /dev/null
+<?php
+/**
+ * Simple information provider for an invited resource.
+ *
+ * PHP version 5
+ *
+ * @category Horde
+ * @package Itip
+ * @author Gunnar Wrobel <wrobel@pardus.de>
+ * @license http://www.fsf.org/copyleft/lgpl.html LGPL
+ * @link http://pear.horde.org/index.php?package=Itip
+ */
+
+/**
+ * Simple information provider for an invited resource.
+ *
+ * Copyright 2010 Kolab Systems AG
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you did not
+ * receive this file, see
+ * http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+ *
+ * @category Horde
+ * @package Itip
+ * @author Gunnar Wrobel <wrobel@pardus.de>
+ * @license http://www.fsf.org/copyleft/lgpl.html LGPL
+ * @link http://pear.horde.org/index.php?package=Itip
+ */
+class Horde_Itip_Resource_Base
+implements Horde_Itip_Resource
+{
+ /**
+ * The mail address.
+ *
+ * @var string
+ */
+ private $_mail;
+
+ /**
+ * The common name.
+ *
+ * @var string
+ */
+ private $_common_name;
+
+ /**
+ * Constructor.
+ *
+ * @param string $mail The mail address.
+ * @param string $common_name The common name.
+ */
+ public function __construct($mail, $common_name)
+ {
+ $this->_mail = $mail;
+ $this->_common_name = $common_name;
+ }
+
+ /**
+ * Retrieve the mail address of the resource.
+ *
+ * @return string The mail address.
+ */
+ public function getMailAddress()
+ {
+ return $this->_mail;
+ }
+
+ /**
+ * Retrieve the common name of the resource.
+ *
+ * @return string The common name.
+ */
+ public function getCommonName()
+ {
+ return $this->_common_name;
+ }
+
+ /**
+ * Retrieve the "From" address for this resource.
+ *
+ * @return string The "From" address.
+ */
+ public function getFrom()
+ {
+ return sprintf("%s <%s>", $this->_common_name, $this->_mail);
+ }
+}
\ No newline at end of file
--- /dev/null
+<?php
+/**
+ * Handles Itip response data.
+ *
+ * PHP version 5
+ *
+ * @category Horde
+ * @package Itip
+ * @author Steffen Hansen <steffen@klaralvdalens-datakonsult.se>
+ * @author Gunnar Wrobel <wrobel@pardus.de>
+ * @license http://www.fsf.org/copyleft/lgpl.html LGPL
+ * @link http://pear.horde.org/index.php?package=Itip
+ */
+
+/**
+ * Handles Itip response data.
+ *
+ * Copyright 2004-2010 Klarälvdalens Datakonsult AB
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you did not
+ * receive this file, see
+ * http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+ *
+ * @category Horde
+ * @package Itip
+ * @author Steffen Hansen <steffen@klaralvdalens-datakonsult.se>
+ * @author Gunnar Wrobel <wrobel@pardus.de>
+ * @license http://www.fsf.org/copyleft/lgpl.html LGPL
+ * @link http://pear.horde.org/index.php?package=Itip
+ */
+class Horde_Itip_Response
+{
+ /**
+ * The request we are going to answer.
+ *
+ * @var Horde_Itip_Event
+ */
+ private $_request;
+
+ /**
+ * The requested resource.
+ *
+ * @var Horde_Itip_Resource
+ */
+ private $_resource;
+
+ /**
+ * The status type of this response.
+ *
+ * @var Horde_Itip_Response_Type
+ */
+ private $_type;
+
+ /**
+ * Constructor.
+ *
+ * @param Horde_Itip_Event $request The request this
+ * instance will respond
+ * to.
+ * @param Horde_Itip_Resource $resource The requested
+ * resource.
+ */
+ public function __construct(
+ Horde_Itip_Event $request,
+ Horde_Itip_Resource $resource
+ ) {
+ $this->_request = $request;
+ $this->_resource = $resource;
+ }
+
+ /**
+ * Return the response as an iCalendar vveEnt object.
+ *
+ * @param Horde_Itip_Response_Type $type The response type.
+ * @param Horde_iCalendar|boolean $vCal The parent container or false if not
+ * provided.
+ *
+ * @return Horde_iCalendar_vevent The response object.
+ */
+ public function getVevent(
+ Horde_Itip_Response_Type $type,
+ $vCal = false
+ ) {
+ $itip_reply = new Horde_Itip_Event_Vevent(
+ Horde_iCalendar::newComponent('VEVENT', $vCal)
+ );
+ $this->_request->copyEventInto($itip_reply);
+
+ $type->setRequest($this->_request);
+
+ $itip_reply->setAttendee(
+ $this->_resource->getMailAddress(),
+ $this->_resource->getCommonName(),
+ $type->getStatus()
+ );
+ return $itip_reply->getVevent();
+ }
+
+ /**
+ * Return the response as an iCalendar object.
+ *
+ * @param Horde_Itip_Response_Type $type The response
+ * type.
+ * @param string $product_id The ID that
+ * should be set
+ * as the iCalendar
+ * product id.
+ *
+ * @return Horde_iCalendar The response object.
+ */
+ public function getIcalendar(
+ Horde_Itip_Response_Type $type,
+ $product_id
+ ) {
+ $vCal = new Horde_iCalendar();
+ $vCal->setAttribute('PRODID', $product_id);
+ $vCal->setAttribute('METHOD', 'REPLY');
+ $vCal->addComponent($this->getVevent($type, $vCal));
+ return $vCal;
+ }
+
+ /**
+ * Return the response as a MIME message.
+ *
+ * @param Horde_Itip_Response_Type $type The response
+ * type.
+ * @param string $product_id The ID that
+ * should be set
+ * as the iCalendar
+ * product id.
+ * @param string $subject_comment An optional comment on the subject line.
+ *
+ * @return array A list of two object: The mime headers and the mime
+ * message.
+ */
+ public function getMessage(
+ Horde_Itip_Response_Type $type,
+ $product_id,
+ $subject_comment = null
+ ) {
+ $ics = new MIME_Part(
+ 'text/calendar',
+ $this->getIcalendar($type, $product_id)->exportvCalendar(),
+ 'UTF-8'
+ );
+ $ics->setContentTypeParameter('method', 'REPLY');
+
+ //$mime->addPart($body);
+ //$mime->addPart($ics);
+ // The following was ::convertMimePart($mime). This was removed so that we
+ // send out single-part MIME replies that have the iTip file as the body,
+ // with the correct mime-type header set, etc. The reason we want to do this
+ // is so that Outlook interprets the messages as it does Outlook-generated
+ // responses, i.e. double-clicking a reply will automatically update your
+ // meetings, showing different status icons in the UI, etc.
+ $message = MIME_Message::convertMimePart($ics);
+ $message->setCharset('UTF-8');
+ $message->setTransferEncoding('quoted-printable');
+ $message->transferEncodeContents();
+
+ // Build the reply headers.
+ $headers = new MIME_Headers();
+ $headers->addHeader('Date', date('r'));
+ $headers->addHeader('From', $this->_resource->getFrom());
+ $headers->addHeader('To', $this->_request->getOrganizer());
+ $headers->addHeader(
+ 'Subject', $type->getSubject($subject_comment)
+ );
+ $headers->addMIMEHeaders($message);
+ return array($headers, $message);
+ }
+}
\ No newline at end of file
--- /dev/null
+<?php
+/**
+ * Marks the response type.
+ *
+ * PHP version 5
+ *
+ * @category Kolab
+ * @package Kolab_Filter
+ * @author Gunnar Wrobel <wrobel@pardus.de>
+ * @license http://www.fsf.org/copyleft/lgpl.html LGPL
+ * @link http://pear.horde.org/index.php?package=Kolab_Server
+ */
+
+/**
+ * Marks the response type.
+ *
+ * Copyright 2010 Klarälvdalens Datakonsult AB
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you did not
+ * receive this file, see
+ * http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+ *
+ * @category Kolab
+ * @package Kolab_Filter
+ * @author Gunnar Wrobel <wrobel@pardus.de>
+ * @license http://www.fsf.org/copyleft/lgpl.html LGPL
+ * @link http://pear.horde.org/index.php?package=Kolab_Server
+ */
+interface Horde_Itip_Response_Type
+{
+ /**
+ * Return the status of the response.
+ *
+ * @return string The status.
+ */
+ public function getStatus();
+
+ /**
+ * Return the abbreviated subject of the response.
+ *
+ * @return string The short subject.
+ */
+ public function getShortSubject();
+
+ /**
+ * Return the subject of the response.
+ *
+ * @param string $comment An optional comment that should appear in the
+ * response subject.
+ *
+ * @return string The subject.
+ */
+ public function getSubject($comment = null);
+
+ /**
+ * Return an additional message for the response.
+ *
+ * @param boolean $is_update Indicates if the request was an update.
+ * @param string $comment An optional comment that should appear in the
+ * response message.
+ *
+ * @return string The message.
+ */
+ public function getMessage($is_update = false, $comment = null);
+}
\ No newline at end of file
--- /dev/null
+<?php
+/**
+ * Indicates an accepted invitation.
+ *
+ * PHP version 5
+ *
+ * @category Kolab
+ * @package Kolab_Filter
+ * @author Gunnar Wrobel <wrobel@pardus.de>
+ * @license http://www.fsf.org/copyleft/lgpl.html LGPL
+ * @link http://pear.horde.org/index.php?package=Kolab_Server
+ */
+
+/**
+ * Indicates an accepted invitation.
+ *
+ * Copyright 2010 Klarälvdalens Datakonsult AB
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you did not
+ * receive this file, see
+ * http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+ *
+ * @category Kolab
+ * @package Kolab_Filter
+ * @author Gunnar Wrobel <wrobel@pardus.de>
+ * @license http://www.fsf.org/copyleft/lgpl.html LGPL
+ * @link http://pear.horde.org/index.php?package=Kolab_Server
+ */
+class Horde_Itip_Response_Type_Accept
+extends Horde_Itip_Response_Type_Base
+{
+ /**
+ * Return the status of the response.
+ *
+ * @return string The status.
+ */
+ public function getStatus()
+ {
+ return 'ACCEPTED';
+ }
+
+ /**
+ * Return the abbreviated subject of the response.
+ *
+ * @return string The short subject.
+ */
+ public function getShortSubject()
+ {
+ return _("Accepted");
+ }
+
+ /**
+ * Return the short message for the response.
+ *
+ * @param boolean $is_update Indicates if the request was an update.
+ *
+ * @return string The short message.
+ */
+ public function getShortMessage($is_update = false)
+ {
+ return $is_update
+ ? _("has accepted the update to the following event")
+ : _("has accepted the invitation to the following event");
+ }
+}
\ No newline at end of file
--- /dev/null
+<?php
+/**
+ * Basic iTip response type definition.
+ *
+ * PHP version 5
+ *
+ * @category Kolab
+ * @package Kolab_Filter
+ * @author Gunnar Wrobel <wrobel@pardus.de>
+ * @license http://www.fsf.org/copyleft/lgpl.html LGPL
+ * @link http://pear.horde.org/index.php?package=Kolab_Server
+ */
+
+/**
+ * Basic iTip response type definition.
+ *
+ * Copyright 2010 Klarälvdalens Datakonsult AB
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you did not
+ * receive this file, see
+ * http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+ *
+ * @category Kolab
+ * @package Kolab_Filter
+ * @author Gunnar Wrobel <wrobel@pardus.de>
+ * @license http://www.fsf.org/copyleft/lgpl.html LGPL
+ * @link http://pear.horde.org/index.php?package=Kolab_Server
+ */
+abstract class Horde_Itip_Response_Type_Base
+implements Horde_Itip_Response_Type
+{
+ /**
+ * The request we are going to answer.
+ *
+ * @var Horde_Itip_Event
+ */
+ private $_request;
+
+ /**
+ * Set the request.
+ *
+ * @param Horde_Itip_Event $request The request this
+ * instance will respond
+ * to.
+ *
+ * @return NULL
+ */
+ public function setRequest(
+ Horde_Itip_Event $request
+ ) {
+ $this->_request = $request;
+ }
+
+ /**
+ * Get the request for this response.
+ *
+ * @return Horde_Itip_Event The request this instance will
+ * respond to.
+ *
+ * @throws Horde_Itip_Exception If the request has not been
+ * set yet.
+ */
+ public function getRequest()
+ {
+ if (empty($this->_request)) {
+ throw new Horde_Itip_Exception(
+ 'The iTip request is still undefined!'
+ );
+ }
+ return $this->_request;
+ }
+
+ /**
+ * Return the subject of the response.
+ *
+ * @param string $comment An optional comment that should appear in the
+ * response subject.
+ *
+ * @return string The subject.
+ */
+ public function getSubject($comment = null)
+ {
+ if ($comment === null) {
+ return sprintf(
+ '%s: %s',
+ $this->getShortSubject(),
+ $this->getRequest()->getSummary()
+ );
+ } else {
+ return sprintf(
+ '%s [%s]: %s',
+ $this->getShortSubject(),
+ $comment,
+ $this->getRequest()->getSummary()
+ );
+ }
+ }
+
+ /**
+ * Return an additional message for the response.
+ *
+ * @param boolean $is_update Indicates if the request was an update.
+ * @param string $comment An optional comment that should appear in the
+ * response message.
+ *
+ * @return string The message.
+ */
+ public function getMessage($is_update = false, $comment = null)
+ {
+ if ($comment === null) {
+ return sprintf(
+ "%s %s:\n\n%s",
+ $this->getShortMessage($update),
+ $this->getRequest()->getSummary()
+ );
+ } else {
+ return sprintf(
+ "%s %s:\n\n%s\n\n%s",
+ $this->getShortMessage($update),
+ $this->getRequest()->getSummary(),
+ $comment
+ );
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+<?php
+/**
+ * Indicates a declined invitation.
+ *
+ * PHP version 5
+ *
+ * @category Kolab
+ * @package Kolab_Filter
+ * @author Gunnar Wrobel <wrobel@pardus.de>
+ * @license http://www.fsf.org/copyleft/lgpl.html LGPL
+ * @link http://pear.horde.org/index.php?package=Kolab_Server
+ */
+
+/**
+ * Indicates a declined invitation.
+ *
+ * Copyright 2010 Klarälvdalens Datakonsult AB
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you did not
+ * receive this file, see
+ * http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+ *
+ * @category Kolab
+ * @package Kolab_Filter
+ * @author Gunnar Wrobel <wrobel@pardus.de>
+ * @license http://www.fsf.org/copyleft/lgpl.html LGPL
+ * @link http://pear.horde.org/index.php?package=Kolab_Server
+ */
+class Horde_Itip_Response_Type_Decline
+extends Horde_Itip_Response_Type_Base
+{
+ /**
+ * Return the status of the response.
+ *
+ * @return string The status.
+ */
+ public function getStatus()
+ {
+ return 'DECLINED';
+ }
+
+ /**
+ * Return the abbreviated subject of the response.
+ *
+ * @return string The short subject.
+ */
+ public function getShortSubject()
+ {
+ return _("Declined");
+ }
+
+ /**
+ * Return the short message for the response.
+ *
+ * @param boolean $is_update Indicates if the request was an update.
+ *
+ * @return string The short message.
+ */
+ public function getShortMessage($is_update = false)
+ {
+ return $is_update
+ ? _("has declined the update to the following event")
+ : _("has declined the invitation to the following event");
+ }
+}
\ No newline at end of file
--- /dev/null
+<?php
+/**
+ * Indicates a tentatively accepted invitation.
+ *
+ * PHP version 5
+ *
+ * @category Kolab
+ * @package Kolab_Filter
+ * @author Gunnar Wrobel <wrobel@pardus.de>
+ * @license http://www.fsf.org/copyleft/lgpl.html LGPL
+ * @link http://pear.horde.org/index.php?package=Kolab_Server
+ */
+
+/**
+ * Indicates a tentatively accepted invitation.
+ *
+ * Copyright 2010 Klarälvdalens Datakonsult AB
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you did not
+ * receive this file, see
+ * http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+ *
+ * @category Kolab
+ * @package Kolab_Filter
+ * @author Gunnar Wrobel <wrobel@pardus.de>
+ * @license http://www.fsf.org/copyleft/lgpl.html LGPL
+ * @link http://pear.horde.org/index.php?package=Kolab_Server
+ */
+class Horde_Itip_Response_Type_Tentative
+extends Horde_Itip_Response_Type_Base
+{
+ /**
+ * Return the status of the response.
+ *
+ * @return string The status.
+ */
+ public function getStatus()
+ {
+ return 'TENTATIVE';
+ }
+
+ /**
+ * Return the abbreviated subject of the response.
+ *
+ * @return string The short subject.
+ */
+ public function getShortSubject()
+ {
+ return _("Tentative");
+ }
+
+ /**
+ * Return the short message for the response.
+ *
+ * @param boolean $is_update Indicates if the request was an update.
+ *
+ * @return string The short message.
+ */
+ public function getShortMessage($is_update = false)
+ {
+ return $is_update
+ ? _("has tentatively accepted the update to the following event")
+ : _("has tentatively accepted the invitation to the following event");
+ }
+}
\ No newline at end of file