/**
* A wrapper for vEvent iCalender data.
*
- * Copyright 2010 Klarälvdalens Datakonsult AB
+ * Copyright 2002-2010 The Horde Project (http://www.horde.org/)
+ * Copyright 2004-2010 Klarälvdalens Datakonsult AB
*
* See the enclosed file COPYING for license information (LGPL). If you did not
* receive this file, see
*/
public function getStartParameters()
{
- return array_pop($this->_vevent->getAttribute('DTSTART', true));
+ $parameters = $this->_vevent->getAttribute('DTSTART', true);
+ return array_pop($parameters);
}
/**
}
/**
- * 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));
+ $parameters = $this->_vevent->getAttribute('DTEND', true);
+ return array_pop($parameters);
}
/**
*/
private function getDurationParameters()
{
- return array_pop($this->_vevent->getAttribute('DURATION', true));
+ $parameters = $this->_vevent->getAttribute('DURATION', true);
+ return array_pop($parameters);
}
/**
*/
private function copyEndOrDuration(Horde_Itip_Event $itip)
{
- if ($this->hasEnd()) {
+ try {
$itip->setEnd($this->getEnd(), $this->getEndParameters());
- } else {
+ } catch (Horde_Icalendar_Exception $e) {
$itip->setDuration($this->getDuration(), $this->getDurationParameters());
}
}
}
/**
- * 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 copyLocation(Horde_Itip_Event $itip)
{
- if ($this->hasLocation()) {
+ try {
$itip->setLocation($this->getLocation());
+ } catch (Horde_Icalendar_Exception $e) {
}
}
*/
private function getOrganizerParameters()
{
- return array_pop($this->_vevent->getAttribute('ORGANIZER', true));
+ $parameters = $this->_vevent->getAttribute('ORGANIZER', true);
+ return array_pop($parameters);
}
/**
*
* @category Horde
* @package Itip
+ * @author Mike Cochrane <mike@graftonhall.co.nz>
+ * @author Chuck Hagenbuch <chuck@horde.org>
* @author Steffen Hansen <steffen@klaralvdalens-datakonsult.se>
* @author Gunnar Wrobel <wrobel@pardus.de>
* @license http://www.fsf.org/copyleft/lgpl.html LGPL
/**
* Handles Itip response data.
*
+ * Copyright 2002-2010 The Horde Project (http://www.horde.org/)
* Copyright 2004-2010 Klarälvdalens Datakonsult AB
*
* See the enclosed file COPYING for license information (LGPL). If you did not
*
* @category Horde
* @package Itip
+ * @author Mike Cochrane <mike@graftonhall.co.nz>
+ * @author Chuck Hagenbuch <chuck@horde.org>
* @author Steffen Hansen <steffen@klaralvdalens-datakonsult.se>
* @author Gunnar Wrobel <wrobel@pardus.de>
* @license http://www.fsf.org/copyleft/lgpl.html LGPL
/**
* Constructor.
*
- * @param Horde_Itip_Event $request The request this
- * instance will respond
- * to.
- * @param Horde_Itip_Resource $resource The requested
- * resource.
+ * @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,
}
/**
- * Return the response as an iCalendar vveEnt object.
+ * Return the response as an iCalendar vEvent object.
*
* @param Horde_Itip_Response_Type $type The response type.
* @param Horde_iCalendar|boolean $vCal The parent container or false if not
/**
* 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.
+ * @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.
*/
/**
* 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.
+ * @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.
$product_id,
$subject_comment = null
) {
- $ics = new MIME_Part(
- 'text/calendar',
- $this->getIcalendar($type, $product_id)->exportvCalendar(),
- 'UTF-8'
+ $ics = new Horde_Mime_Part();
+ $ics->setType('text/calendar');
+ $ics->setCharset('UTF-8');
+ $ics->setContents(
+ $this->getIcalendar($type, $product_id)->exportvCalendar()
);
$ics->setContentTypeParameter('method', 'REPLY');
// 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 = Horde_Mime_Message::convertMimePart($ics);
$message->setCharset('UTF-8');
$message->setTransferEncoding('quoted-printable');
$message->transferEncodeContents();
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<package packagerversion="1.9.0" version="2.0" xmlns="http://pear.php.net/dtd/package-2.0" xmlns:tasks="http://pear.php.net/dtd/tasks-1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://pear.php.net/dtd/tasks-1.0 http://pear.php.net/dtd/tasks-1.0.xsd http://pear.php.net/dtd/package-2.0 http://pear.php.net/dtd/package-2.0.xsd">
+ <name>Itip</name>
+ <channel>pear.horde.org</channel>
+ <summary>iTip invitation response handling.</summary>
+ <description>This package allows to generate MIME encapsuled
+ responses to iCalender invitations.</description>
+ <lead>
+ <name>Gunnar Wrobel</name>
+ <user>wrobel</user>
+ <email>p@rdus.de</email>
+ <active>yes</active>
+ </lead>
+ <lead>
+ <name>Chuck Hagenbuch</name>
+ <user>chuck</user>
+ <email>chuck@horde.org</email>
+ <active>yes</active>
+ </lead>
+ <lead>
+ <name>Jan Schneider</name>
+ <user>jan</user>
+ <email>jan@horde.org</email>
+ <active>yes</active>
+ </lead>
+ <date>2010-08-06</date>
+ <time>21:15:38</time>
+ <version>
+ <release>0.1.0</release>
+ <api>0.1.0</api>
+ </version>
+ <stability>
+ <release>alpha</release>
+ <api>alpha</api>
+ </stability>
+ <license uri="http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html">LGPL</license>
+ <notes>
+* Extracted package from Kolab_Resource.
+ </notes>
+ <contents>
+ <dir baseinstalldir="/" name="/">
+ <dir name="lib">
+ <dir name="Horde">
+ <dir name="Itip">
+ <dir name="Event">
+ <file name="Vevent.php" role="php" />
+ </dir> <!-- /lib/Horde/Itip/Event -->
+ <dir name="Resource">
+ <file name="Base.php" role="php" />
+ </dir> <!-- /lib/Horde/Itip/Resource -->
+ <dir name="Response">
+ <dir name="Type">
+ <file name="Accept.php" role="php" />
+ <file name="Base.php" role="php" />
+ <file name="Decline.php" role="php" />
+ <file name="Tentative.php" role="php" />
+ </dir> <!-- /lib/Horde/Itip/Response/Type -->
+ <file name="Type.php" role="php" />
+ </dir> <!-- /lib/Horde/Itip/Response -->
+ <file name="Event.php" role="php" />
+ <file name="Exception.php" role="php" />
+ <file name="Resource.php" role="php" />
+ <file name="Response.php" role="php" />
+ </dir> <!-- /lib/Horde/Itip -->
+ <file name="Itip.php" role="php" />
+ </dir> <!-- /lib/Horde -->
+ </dir> <!-- /lib -->
+ <dir name="test">
+ <dir name="Horde">
+ <dir name="Itip">
+ <dir name="Integration">
+ <file name="ItipTest.php" role="test" />
+ </dir> <!-- /test/Horde/Itip/Integration -->
+ <file name="AllTests.php" role="test" />
+ <file name="Autoload.php" role="test" />
+ <file name="phpunit.xml" role="test" />
+ </dir> <!-- /test/Horde/Itip -->
+ </dir> <!-- /test/Horde -->
+ </dir> <!-- /test -->
+ <file name="TODO" role="data" />
+ </dir> <!-- / -->
+ </contents>
+ <dependencies>
+ <required>
+ <php>
+ <min>5.0.0</min>
+ </php>
+ <pearinstaller>
+ <min>1.4.0b1</min>
+ </pearinstaller>
+ <package>
+ <name>Icalendar</name>
+ <channel>pear.horde.org</channel>
+ <min>0.2.0</min>
+ </package>
+ <package>
+ <name>Mime</name>
+ <channel>pear.horde.org</channel>
+ <min>0.1.0</min>
+ </package>
+ </required>
+ </dependencies>
+ <phprelease>
+ <filelist>
+ <install as="Horde/Itip.php" name="lib/Horde/Itip.php" />
+ <install as="Horde/Itip/Event.php" name="lib/Horde/Itip/Event.php" />
+ <install as="Horde/Itip/Exception.php" name="lib/Horde/Itip/Exception.php" />
+ <install as="Horde/Itip/Resource.php" name="lib/Horde/Itip/Resource.php" />
+ <install as="Horde/Itip/Response.php" name="lib/Horde/Itip/Response.php" />
+ <install as="Horde/Itip/Event/Vevent.php" name="lib/Horde/Itip/Event/Vevent.php" />
+ <install as="Horde/Itip/Resource/Base.php" name="lib/Horde/Itip/Resource/Base.php" />
+ <install as="Horde/Itip/Response/Type.php" name="lib/Horde/Itip/Response/Type.php" />
+ <install as="Horde/Itip/Response/Type/Accept.php" name="lib/Horde/Itip/Response/Type/Accept.php" />
+ <install as="Horde/Itip/Response/Type/Base.php" name="lib/Horde/Itip/Response/Type/Base.php" />
+ <install as="Horde/Itip/Response/Type/Decline.php" name="lib/Horde/Itip/Response/Type/Decline.php" />
+ <install as="Horde/Itip/Response/Type/Tentative.php" name="lib/Horde/Itip/Response/Type/Tentative.php" />
+ <install as="Horde/Itip/AllTests.php" name="test/Horde/Itip/AllTests.php" />
+ <install as="Horde/Itip/Autoload.php" name="test/Horde/Itip/Autoload.php" />
+ <install as="Horde/Itip/phpunit.xml" name="test/Horde/Itip/phpunit.xml" />
+ <install as="Horde/Itip/Integration/ItipTest.php" name="test/Horde/Itip/Integration/ItipTest.php" />
+ </filelist>
+ </phprelease>
+ <changelog>
+ <release>
+ <version>
+ <release>0.1.0</release>
+ <api>0.1.0</api>
+ </version>
+ <stability>
+ <release>alpha</release>
+ <api>alpha</api>
+ </stability>
+ <date>2010-08-06</date>
+ <license uri="http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html">LGPL</license>
+ <notes>
+* Extracted package from Kolab_Resource.
+ </notes>
+ </release>
+ </changelog>
+</package>
--- /dev/null
+<?php
+/**
+ * All tests for the Itip:: package.
+ *
+ * PHP version 5
+ *
+ * @category Horde
+ * @package Itip
+ * @subpackage UnitTests
+ * @author Gunnar Wrobel <wrobel@pardus.de>
+ * @license http://www.fsf.org/copyleft/lgpl.html LGPL
+ * @link http://pear.horde.org/index.php?package=Itip
+ */
+
+/**
+ * Define the main method
+ */
+if (!defined('PHPUnit_MAIN_METHOD')) {
+ define('PHPUnit_MAIN_METHOD', 'Horde_Itip_AllTests::main');
+}
+
+/**
+ * Prepare the test setup.
+ */
+require_once 'Horde/Test/AllTests.php';
+
+/**
+ * All tests for the Itip:: package.
+ *
+ * @category Horde
+ * @package Itip
+ * @subpackage UnitTests
+ * @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_AllTests extends Horde_Test_AllTests
+{
+}
+
+Horde_Itip_AllTests::init('Horde_Itip', __FILE__);
+
+if (PHPUnit_MAIN_METHOD == 'Horde_Itip_AllTests::main') {
+ Horde_Itip_AllTests::main();
+}
--- /dev/null
+<?php
+/**
+ * Setup autoloading for the tests.
+ *
+ * PHP version 5
+ *
+ * @category Horde
+ * @package Itip
+ * @subpackage UnitTests
+ * @author Gunnar Wrobel <wrobel@pardus.de>
+ * @license http://www.fsf.org/copyleft/lgpl.html LGPL
+ * @link http://pear.horde.org/index.php?package=Itip
+ */
+
+if (!spl_autoload_functions()) {
+ spl_autoload_register(
+ create_function(
+ '$class',
+ '$filename = str_replace(array(\'::\', \'_\'), \'/\', $class);'
+ . '$err_mask = E_ALL ^ E_WARNING;'
+ . '$oldErrorReporting = error_reporting($err_mask);'
+ . 'include "$filename.php";'
+ . 'error_reporting($oldErrorReporting);'
+ )
+ );
+}
+
+/** Catch strict standards */
+error_reporting(E_ALL | E_STRICT);
--- /dev/null
+<?php
+/**
+ * Test the itip response handling.
+ *
+ * PHP version 5
+ *
+ * @category Horde
+ * @package Itip
+ * @subpackage UnitTests
+ * @author Gunnar Wrobel <wrobel@pardus.de>
+ * @license http://www.fsf.org/copyleft/lgpl.html LGPL
+ * @link http://pear.horde.org/index.php?package=Itip
+ */
+
+/**
+ * Prepare the test setup.
+ */
+require_once dirname(__FILE__) . '/../Autoload.php';
+
+/**
+ * Test the itip response handling.
+ *
+ * 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
+ * @subpackage UnitTests
+ * @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_Integration_ItipTest
+extends PHPUnit_Framework_TestCase
+{
+ public function testMinimalItipHandlingSteps()
+ {
+ $iTip = $this->_getItip();
+ $reply = $iTip->getVeventResponse(
+ new Horde_Itip_Response_Type_Accept()
+ );
+ $this->assertEquals($reply->getAttribute('ATTENDEE'), 'MAILTO:test@example.org');
+ }
+
+ public function testDefaultSequenceIdSetToZero()
+ {
+ $iTip = $this->_getItip();
+ $reply = $iTip->getVeventResponse(
+ new Horde_Itip_Response_Type_Accept()
+ );
+ $this->assertSame($reply->getAttribute('SEQUENCE'), 0);
+ }
+
+ public function testForCopiedSequenceIdFromRequestToResponse()
+ {
+ $inv = $this->_getInvitation();
+ $inv->setAttribute('SEQUENCE', 555);
+ $iTip = $this->_getItip($inv);
+ $reply = $iTip->getVeventResponse(
+ new Horde_Itip_Response_Type_Accept()
+ );
+ $this->assertSame($reply->getAttribute('SEQUENCE'), 555);
+ }
+
+ public function testForCopiedStartTimeFromRequestToResponse()
+ {
+ $iTip = $this->_getItip();
+ $reply = $iTip->getVeventResponse(
+ new Horde_Itip_Response_Type_Accept()
+ );
+ $this->assertSame($reply->getAttribute('DTSTART'), array('20080926T110000'));
+ }
+
+ public function testForCopiedEndTimeFromRequestToResponse()
+ {
+ $iTip = $this->_getItip();
+ $reply = $iTip->getVeventResponse(
+ new Horde_Itip_Response_Type_Accept()
+ );
+ $this->assertSame($reply->getAttribute('DTEND'), array('20080926T120000'));
+ }
+
+ public function testForCopiedDurationFromRequestToResponse()
+ {
+ $vCal = new Horde_iCalendar();
+ $inv = Horde_iCalendar::newComponent('VEVENT', $vCal);
+ $inv->setAttribute('METHOD', 'REQUEST');
+ $inv->setAttribute('UID', '1');
+ $inv->setAttribute('SUMMARY', 'Test Invitation');
+ $inv->setAttribute('DESCRIPTION', 'You are invited');
+ $inv->setAttribute('ORGANIZER', 'orga@example.org');
+ $inv->setAttribute('DTSTART', '20080926T110000');
+ $inv->setAttribute('DURATION', 3600);
+ $iTip = $this->_getItip($inv);
+ $reply = $iTip->getVeventResponse(
+ new Horde_Itip_Response_Type_Accept()
+ );
+ $this->assertSame($reply->getAttribute('DURATION'), 3600);
+ }
+
+ public function testForCopiedOrganizerFromRequestToResponse()
+ {
+ $iTip = $this->_getItip();
+ $reply = $iTip->getVeventResponse(
+ new Horde_Itip_Response_Type_Accept()
+ );
+ $this->assertSame($reply->getAttribute('ORGANIZER'), 'orga@example.org');
+ }
+
+ public function testForCopiedUidFromRequestToResponse()
+ {
+ $iTip = $this->_getItip();
+ $reply = $iTip->getVeventResponse(
+ new Horde_Itip_Response_Type_Accept()
+ );
+ $this->assertSame($reply->getAttribute('UID'), '1');
+ }
+
+ public function testIcalendarResponseHasMethodReply()
+ {
+ $iTip = $this->_getItip();
+ $reply = $iTip->getIcalendarResponse(
+ new Horde_Itip_Response_Type_Accept(), ''
+ );
+ $this->assertEquals($reply->getAttribute('METHOD'), 'REPLY');
+ }
+
+ public function testIcalendarResponseAllowsSettingTheProductId()
+ {
+ $iTip = $this->_getItip();
+ $reply = $iTip->getIcalendarResponse(
+ new Horde_Itip_Response_Type_Accept(), 'My product'
+ );
+ $this->assertEquals($reply->getAttribute('PRODID'), 'My product');
+ }
+
+ public function testMessageResponseHasFromAddress()
+ {
+ $_SERVER['SERVER_NAME'] = 'localhost';
+ $iTip = $this->_getItip();
+ $reply = $iTip->getMessageResponse(
+ new Horde_Itip_Response_Type_Accept(), '', ''
+ );
+
+ $this->assertContains('From: Mister Test <test@example.org>', $reply[0]->toString());
+ }
+
+ public function testMessageResponseHasToAddress()
+ {
+ $_SERVER['SERVER_NAME'] = 'localhost';
+ $iTip = $this->_getItip();
+ $reply = $iTip->getMessageResponse(
+ new Horde_Itip_Response_Type_Accept(), '', ''
+ );
+
+ $this->assertContains('To: orga@example.org', $reply[0]->toString());
+ }
+
+ public function testMessageResponseHasSubjectAddress()
+ {
+ $_SERVER['SERVER_NAME'] = 'localhost';
+ $iTip = $this->_getItip();
+ $reply = $iTip->getMessageResponse(new Horde_Itip_Response_Type_Accept(), '');
+ $this->assertContains('Subject: Accepted: Test', $reply[0]->toString());
+ }
+
+ public function testMessageResponseAllowsAddingCommentsToTheSubject()
+ {
+ $_SERVER['SERVER_NAME'] = 'localhost';
+ $iTip = $this->_getItip();
+ $reply = $iTip->getMessageResponse(
+ new Horde_Itip_Response_Type_Accept(), '', 'info'
+ );
+ $this->assertContains('Subject: Accepted [info]: Test', $reply[0]->toString());
+ }
+
+ public function testAttendeeHoldsInformationAboutMailAddress()
+ {
+ $iTip = $this->_getItip();
+ $reply = $iTip->getVeventResponse(
+ new Horde_Itip_Response_Type_Accept(), ''
+ );
+ $this->assertEquals($reply->getAttribute('ATTENDEE'), 'MAILTO:test@example.org');
+ }
+
+ public function testAttendeeHoldsInformationAboutCommonNameAndStatus()
+ {
+ $iTip = $this->_getItip();
+ $reply = $iTip->getVeventResponse(
+ new Horde_Itip_Response_Type_Accept(), ''
+ );
+ $parameters = $reply->getAttribute('ATTENDEE', true);
+ $this->assertEquals(
+ array_pop($parameters),
+ array(
+ 'CN' => 'Mister Test',
+ 'PARTSTAT' => 'ACCEPTED'
+ )
+ );
+ }
+
+
+ /**
+ * Test the basic iTip handling method.
+ */
+ /* public function testBasic() */
+ /* { */
+ /* $iTip = new Horde_Itip( */
+ /* $request, $resource */
+ /* ); */
+ /* $reply = $itip->setResponseType($responseType) */
+ /* ->setSubjectComment('text') */
+ /* ->setMessageComment('text') */
+ /* ->setUpdate(true) */
+ /* ->getMimeMessage(); */
+ /* } */
+
+ private function _getItip($invitation = null)
+ {
+ if ($invitation === null) {
+ $invitation = $this->_getInvitation();
+ }
+ return Horde_Itip::factory(
+ $invitation,
+ $this->_getResource()
+ );
+ }
+
+ private function _getInvitation()
+ {
+ $vCal = new Horde_Icalendar();
+ $inv = Horde_Icalendar::newComponent('VEVENT', $vCal);
+ $inv->setAttribute('METHOD', 'REQUEST');
+ $inv->setAttribute('UID', '1');
+ $inv->setAttribute('SUMMARY', 'Test Invitation');
+ $inv->setAttribute('DESCRIPTION', 'You are invited');
+ $inv->setAttribute('ORGANIZER', 'orga@example.org');
+ $inv->setAttribute('DTSTART', array('20080926T110000'));
+ $inv->setAttribute('DTEND', array('20080926T120000'));
+ return $inv;
+ }
+
+ private function _getResource($mail = null, $cn = null)
+ {
+ if ($mail === null) {
+ $mail = 'test@example.org';
+ }
+ if ($cn === null) {
+ $cn = 'Mister Test';
+ }
+ return new Horde_Itip_Resource_Base($mail, $cn);
+ }
+}
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<phpunit>
+ <filter>
+ <whitelist>
+ <directory suffix=".php">../../../lib</directory>
+ </whitelist>
+ </filter>
+</phpunit>