From 3f3858f63d293d587be48d3bcccaf6f13a7cf4a4 Mon Sep 17 00:00:00 2001 From: Michael Rubinsky Date: Mon, 28 Dec 2009 19:07:06 +0000 Subject: [PATCH] Revert "Move incomplete H4 Icalendar library to H4-refactoring branch." This reverts commit 96f6126bb425a507b1840a3710b4b26fae789350. --- framework/Icalendar/lib/Horde/Icalendar/Base.php | 241 +++++++++++++++++++++ .../Icalendar/lib/Horde/Icalendar/Exception.php | 5 + framework/Icalendar/lib/Horde/Icalendar/Valarm.php | 20 ++ .../Icalendar/lib/Horde/Icalendar/Vcalendar.php | 46 ++++ framework/Icalendar/lib/Horde/Icalendar/Vevent.php | 53 +++++ .../Icalendar/lib/Horde/Icalendar/Vfreebusy.php | 37 ++++ .../Icalendar/lib/Horde/Icalendar/Vjournal.php | 26 +++ .../Icalendar/lib/Horde/Icalendar/Vtimezone.php | 25 +++ framework/Icalendar/lib/Horde/Icalendar/Vtodo.php | 32 +++ framework/Icalendar/lib/Horde/Icalendar/Writer.php | 27 +++ .../Icalendar/lib/Horde/Icalendar/Writer/Base.php | 42 ++++ .../lib/Horde/Icalendar/Writer/Vcalendar/20.php | 26 +++ .../Icalendar/test/Horde/Icalendar/AllTests.php | 32 +++ .../Icalendar/test/Horde/Icalendar/WriterTest.php | 66 ++++++ 14 files changed, 678 insertions(+) create mode 100644 framework/Icalendar/lib/Horde/Icalendar/Base.php create mode 100644 framework/Icalendar/lib/Horde/Icalendar/Exception.php create mode 100644 framework/Icalendar/lib/Horde/Icalendar/Valarm.php create mode 100644 framework/Icalendar/lib/Horde/Icalendar/Vcalendar.php create mode 100644 framework/Icalendar/lib/Horde/Icalendar/Vevent.php create mode 100644 framework/Icalendar/lib/Horde/Icalendar/Vfreebusy.php create mode 100644 framework/Icalendar/lib/Horde/Icalendar/Vjournal.php create mode 100644 framework/Icalendar/lib/Horde/Icalendar/Vtimezone.php create mode 100644 framework/Icalendar/lib/Horde/Icalendar/Vtodo.php create mode 100644 framework/Icalendar/lib/Horde/Icalendar/Writer.php create mode 100644 framework/Icalendar/lib/Horde/Icalendar/Writer/Base.php create mode 100644 framework/Icalendar/lib/Horde/Icalendar/Writer/Vcalendar/20.php create mode 100644 framework/Icalendar/test/Horde/Icalendar/AllTests.php create mode 100644 framework/Icalendar/test/Horde/Icalendar/WriterTest.php diff --git a/framework/Icalendar/lib/Horde/Icalendar/Base.php b/framework/Icalendar/lib/Horde/Icalendar/Base.php new file mode 100644 index 000000000..1b9e4d8ca --- /dev/null +++ b/framework/Icalendar/lib/Horde/Icalendar/Base.php @@ -0,0 +1,241 @@ + $value) { + $this->addProperty($property, $value); + } + } + + /** + * Validates a property-value-pair. + * + * @throws InvalidArgumentException + */ + protected function _validate($property, &$value, &$params = array()) + { + if (!isset($this->_properties[$property])) { + throw new InvalidArgumentException($property . ' is not a valid property'); + } + $myProperty = &$this->_properties[$property]; + if (isset($myProperty['type'])) { + $func = 'is_' . $myProperty['type']; + if (!$func) { + throw new InvalidArgumentException($value . ' is not a ' . $myProperty['type']); + } + } elseif (isset($myProperty['class'])) { + if (!($value instanceof $myProperty['class'])) { + throw new InvalidArgumentException($value . ' is not of class ' . $myProperty['class']); + } + } + if ($property == 'stamp') { + $value->setTimezone('UTC'); + } + } + + /** + * Setter. + * + * @throws InvalidArgumentException + */ + public function __set($property, $value) + { + $this->_validate($property, $value); + $this->_setProperty($property, $value); + } + + /** + * Sets the value of a property. + * + * @param string $property The name of the property. + * @param string $value The value of the property. + * @param array $params Array containing any addition parameters for + * this property. + * + * @throws InvalidArgumentException + */ + public function setProperty($property, $value, $params = array()) + { + $this->_validate($property, $value); + $this->_setProperty($property, $value, $params); + } + + /** + * Adds the value of a property. + * + * @param string $property The name of the property. + * @param string $value The value of the property. + * @param array $params Array containing any addition parameters for + * this property. + * + * @throws InvalidArgumentException + * @throws Horde_Icalendar_Exception + */ + public function addProperty($property, $value, $params = array()) + { + $this->_validate($property, $value); + if (!$this->_properties[$property]['multiple'] && + !empty($this->_properties[$property]['values'])) { + throw new Horde_Icalendar_Exception($property . ' properties must not occur more than once.'); + } + $this->_setProperty($property, $value, $params, true); + } + + /** + * Sets the value of a property. + * + * @param string $property The name of the property. + * @param string $value The value of the property. + * @param array $params Array containing any addition parameters for + * this property. + * @param boolean $add Whether to add (instead of replace) the value. + * + * @throws InvalidArgumentException + */ + protected function _setProperty($property, $value, $params = array(), $add = false) + { + if ($add) { + if (!isset($this->_properties[$property]['values'])) { + $this->_properties[$property]['values'] = array(); + $this->_properties[$property]['params'] = array(); + } + $this->_properties[$property]['values'][] = $value; + $this->_properties[$property]['params'][] = $params; + } else { + $this->_properties[$property]['values'] = array($value); + $this->_properties[$property]['params'] = $params; + } + } + + /** + * Getter. + * + * @throws InvalidArgumentException + */ + public function __get($property) + { + if (!isset($this->_properties[$property])) { + throw new InvalidArgumentException($property . ' is not a valid property'); + } + return isset($this->_properties[$property]['values']) + ? ($this->_properties[$property]['multiple'] + ? $this->_properties[$property]['values'] + : $this->_properties[$property]['values'][0]) + : null; + } + + /** + * Returns the value of an property. + * + * @param string $name The name of the property. + * @param boolean $params Return the parameters for this property instead + * of its value. + * + * @return mixed (object) PEAR_Error if the property does not exist. + * (string) The value of the property. + * (array) The parameters for the property or + * multiple values for an property. + */ + function getProperty($name, $params = false) + { + $result = array(); + foreach ($this->_properties as $property) { + if ($property['name'] == $name) { + if ($params) { + $result[] = $property['params']; + } else { + $result[] = $property['value']; + } + } + } + if (!count($result)) { + require_once 'PEAR.php'; + return PEAR::raiseError('Property "' . $name . '" Not Found'); + } if (count($result) == 1 && !$params) { + return $result[0]; + } else { + return $result; + } + } + + public function getProperties() + { + return $this->_properties; + } + + /** + * Validates the complete component for missing properties or invalid + * property combinations. + * + * @throws Horde_Icalendar_Exception + */ + public function validate() + { + foreach ($this->_properties as $name => $property) { + if (!empty($property['required']) && !isset($property['values'])) { + switch ($name) { + case 'uid': + $this->uid = (string)new Horde_Support_Guid; + break; + case 'stamp': + $this->stamp = new Horde_Date(time()); + break; + default: + // @todo Use LSB (static::__CLASS__) once we require PHP 5.3 + $component = Horde_String::upper(str_replace('Horde_Icalendar_', '', get_class($this))); + throw new Horde_Icalendar_Exception('This ' . $component . ' component must have a ' . $name . ' property set'); + } + } + } + } + + public function current() + { + return current($this->_properties); + } + + public function key() + { + return key($this->_properties); + } + + public function next() + { + next($this->_properties); + } + + public function rewind() + { + reset($this->_properties); + } + + public function valid() + { + return current($this->_properties) !== false; + } + + /** + * @todo Use LSB (static::__CLASS__) once we require PHP 5.3 + */ + public function export() + { + $this->validate(); + $writer = Horde_Icalendar_Writer::factory( + str_replace('Horde_Icalendar_', '', get_class($this)), + str_replace('.', '', $this->version)); + return $writer->export($this); + } + +} diff --git a/framework/Icalendar/lib/Horde/Icalendar/Exception.php b/framework/Icalendar/lib/Horde/Icalendar/Exception.php new file mode 100644 index 000000000..9c7fc1c50 --- /dev/null +++ b/framework/Icalendar/lib/Horde/Icalendar/Exception.php @@ -0,0 +1,5 @@ +_properties += array( + 'summary' => array('required' => false, + 'multiple' => false, + 'type' => 'string'), + 'description' => array('required' => false, + 'multiple' => false, + 'type' => 'string')); + parent::__construct($properties); + } + +} diff --git a/framework/Icalendar/lib/Horde/Icalendar/Vcalendar.php b/framework/Icalendar/lib/Horde/Icalendar/Vcalendar.php new file mode 100644 index 000000000..5092a9b5b --- /dev/null +++ b/framework/Icalendar/lib/Horde/Icalendar/Vcalendar.php @@ -0,0 +1,46 @@ +_properties += array( + // RFC 2445 Section 4.7.1 + 'scale' => array('required' => false, + 'multiple' => false, + 'type' => 'string'), + // RFC 2445 Section 4.7.2 + 'method' => array('required' => false, + 'multiple' => false, + 'type' => 'string'), + // RFC 2445 Section 4.7.3 + 'product' => array('required' => true, + 'multiple' => false, + 'type' => 'string'), + // RFC 2445 Section 4.7.4 + 'version' => array('required' => true, + 'multiple' => false, + 'type' => 'string'), + ); + + $properties = array_merge(array('version' => '2.0', + 'product' => '-//The Horde Project//Horde_Icalendar Library//EN'), + $properties); + parent::__construct($properties); + } + + /** + * Getter. + * + * @throws InvalidArgumentException + */ + public function __get($property) + { + $value = parent::__get($property); + if ($property == 'scale' && is_null($value)) { + $value = 'GREGORIAN'; + } + return $value; + } + +} diff --git a/framework/Icalendar/lib/Horde/Icalendar/Vevent.php b/framework/Icalendar/lib/Horde/Icalendar/Vevent.php new file mode 100644 index 000000000..f3a541775 --- /dev/null +++ b/framework/Icalendar/lib/Horde/Icalendar/Vevent.php @@ -0,0 +1,53 @@ +_properties += array( + 'uid' => array('required' => true, + 'multiple' => false, + 'type' => 'string'), + 'start' => array('required' => true, + 'multiple' => false, + 'class' => 'Horde_Date'), + 'startDate' => array('required' => false, + 'multiple' => false, + 'class' => 'Horde_Date'), + 'stamp' => array('required' => true, + 'multiple' => false, + 'class' => 'Horde_Date'), + 'summary' => array('required' => false, + 'multiple' => false, + 'type' => 'string'), + 'description' => array('required' => false, + 'multiple' => false, + 'type' => 'string')); + parent::__construct($properties); + } + + /** + * Sets the value of a property. + * + * @param string $property The name of the property. + * @param string $value The value of the property. + * @param array $params Array containing any addition parameters for + * this property. + * @param boolean $add Whether to add (instead of replace) the value. + * + * @throws InvalidArgumentException + */ + protected function _setProperty($property, $value, $params = array(), $add = false) + { + if ($property == 'startDate') { + $this->_validate('start', $value); + $property = 'start'; + $params['value'] = 'date'; + } + parent::_setProperty($property, $value, $params, $add); + } + +} diff --git a/framework/Icalendar/lib/Horde/Icalendar/Vfreebusy.php b/framework/Icalendar/lib/Horde/Icalendar/Vfreebusy.php new file mode 100644 index 000000000..d7040d1a7 --- /dev/null +++ b/framework/Icalendar/lib/Horde/Icalendar/Vfreebusy.php @@ -0,0 +1,37 @@ +_properties += array( + 'uid' => array('required' => true, + 'multiple' => false, + 'type' => 'string'), + 'start' => array('required' => true, + 'multiple' => false, + 'class' => 'Horde_Date'), + 'stamp' => array('required' => true, + 'multiple' => false, + 'class' => 'Horde_Date'), + ); + parent::__construct($properties); + } + + /** + * Validates a property-value-pair. + * + * @throws InvalidArgumentException + */ + protected function _validate($property, &$value) + { + parent::_validate($property, $value); + if ($property == 'start') { + $value->setTimezone('UTC'); + } + } + +} diff --git a/framework/Icalendar/lib/Horde/Icalendar/Vjournal.php b/framework/Icalendar/lib/Horde/Icalendar/Vjournal.php new file mode 100644 index 000000000..094d91fa1 --- /dev/null +++ b/framework/Icalendar/lib/Horde/Icalendar/Vjournal.php @@ -0,0 +1,26 @@ +_properties += array( + 'uid' => array('required' => true, + 'multiple' => false, + 'type' => 'string'), + 'stamp' => array('required' => true, + 'multiple' => false, + 'class' => 'Horde_Date'), + 'summary' => array('required' => false, + 'multiple' => false, + 'type' => 'string'), + 'description' => array('required' => false, + 'multiple' => false, + 'type' => 'string')); + parent::__construct($properties); + } + +} diff --git a/framework/Icalendar/lib/Horde/Icalendar/Vtimezone.php b/framework/Icalendar/lib/Horde/Icalendar/Vtimezone.php new file mode 100644 index 000000000..86f06c17b --- /dev/null +++ b/framework/Icalendar/lib/Horde/Icalendar/Vtimezone.php @@ -0,0 +1,25 @@ +_properties += array( + /* + Within the "VTIMEZONE" calendar component, this property defines the + effective start date and time for a time zone specification. This + property is REQUIRED within each STANDARD and DAYLIGHT part included + in "VTIMEZONE" calendar components and MUST be specified as a local + DATE-TIME without the "TZID" property parameter. + */ + 'start' => array('required' => true, + 'multiple' => false, + 'class' => 'Horde_Date'), + ); + parent::__construct($properties); + } + +} diff --git a/framework/Icalendar/lib/Horde/Icalendar/Vtodo.php b/framework/Icalendar/lib/Horde/Icalendar/Vtodo.php new file mode 100644 index 000000000..ee4e74b79 --- /dev/null +++ b/framework/Icalendar/lib/Horde/Icalendar/Vtodo.php @@ -0,0 +1,32 @@ +_properties += array( + 'uid' => array('required' => true, + 'multiple' => false, + 'type' => 'string'), + 'start' => array('required' => false, + 'multiple' => false, + 'class' => 'Horde_Date'), + 'startDate' => array('required' => false, + 'multiple' => false, + 'class' => 'Horde_Date'), + 'stamp' => array('required' => true, + 'multiple' => false, + 'class' => 'Horde_Date'), + 'summary' => array('required' => false, + 'multiple' => false, + 'type' => 'string'), + 'description' => array('required' => false, + 'multiple' => false, + 'type' => 'string')); + parent::__construct($properties); + } + +} diff --git a/framework/Icalendar/lib/Horde/Icalendar/Writer.php b/framework/Icalendar/lib/Horde/Icalendar/Writer.php new file mode 100644 index 000000000..d59d3ed71 --- /dev/null +++ b/framework/Icalendar/lib/Horde/Icalendar/Writer.php @@ -0,0 +1,27 @@ +_output = ''; + $this->_exportComponent($object); + return $this->_output; + } + + protected function _exportComponent($object) + { + $basename = Horde_String::upper(str_replace('Horde_Icalendar_', '', get_class($object))); + $this->_output .= 'BEGIN:' . $basename . "\n"; + foreach ($object as $name => $property) { + $this->_exportProperty($name, $property); + } + foreach ($object->components as $component) { + $this->_exportComponent($component); + } + $this->_output .= 'END:' . $basename . "\n"; + return $this->_output; + } + + protected function _exportProperty($name, $property) + { + if (isset($property['values'])) { + if (isset($this->_propertyMap[$name])) { + $name = $this->_propertyMap[$name]; + } + foreach ($property['values'] as $value) { + $this->_output .= Horde_String::upper($name) . ':' . $value . "\n"; + } + } + } + +} diff --git a/framework/Icalendar/lib/Horde/Icalendar/Writer/Vcalendar/20.php b/framework/Icalendar/lib/Horde/Icalendar/Writer/Vcalendar/20.php new file mode 100644 index 000000000..645929f43 --- /dev/null +++ b/framework/Icalendar/lib/Horde/Icalendar/Writer/Vcalendar/20.php @@ -0,0 +1,26 @@ + 'PRODID', + 'start' => 'DTSTART', + 'stamp' => 'DTSTAMP'); + + protected function _exportProperty($name, $property) + { + if (!isset($property['values'])) { + return; + } + if (isset($property['class']) && $property['class'] == 'Horde_Date') { + if (isset($this->_propertyMap[$name])) { + $name = $this->_propertyMap[$name]; + } + foreach ($property['values'] as $value) { + $this->_output .= Horde_String::upper($name) . ':' . $value->format('Ymd\THms\Z') . "\n"; + } + } else { + parent::_exportProperty($name, $property); + } + } + +} diff --git a/framework/Icalendar/test/Horde/Icalendar/AllTests.php b/framework/Icalendar/test/Horde/Icalendar/AllTests.php new file mode 100644 index 000000000..335c39130 --- /dev/null +++ b/framework/Icalendar/test/Horde/Icalendar/AllTests.php @@ -0,0 +1,32 @@ + '2.0')); + $event1 = new Horde_Icalendar_Vevent(); + $event2 = new Horde_Icalendar_Vevent(); + + $event1->uid = '20041120-8550-innerjoin-org'; + $event1->startDate = new Horde_Date(array('year' => 2005, 'month' => 5, 'mday' => 3)); + $event1->stamp = new Horde_Date(array('year' => 2004, 'month' => 11, 'mday' => 20)); + $event1->summary = 'Escaped Comma in Description Field'; + $event1->description = 'There is a comma (escaped with a baskslash) in this sentence and some important words after it, see anything here?'; + + $event2->uid = '20041120-8549-innerjoin-org'; + $event2->startDate = new Horde_Date(array('year' => 2005, 'month' => 5, 'mday' => 4)); + $event2->stamp = new Horde_Date(array('year' => 2004, 'month' => 11, 'mday' => 20)); + $event2->summary = 'Dash (rather than Comma) in the Description Field'; + $event2->description = 'There are important words after this dash - see anything here or have the words gone?'; + + $ical->components[] = $event1; + $ical->components[] = $event2; + + $this->assertEquals('BEGIN:VCALENDAR +VERSION:2.0 +PRODID:-//The Horde Project//Horde_iCalendar Library//EN +METHOD:PUBLISH +BEGIN:VEVENT +UID:20041120-8550-innerjoin-org +DTSTART;VALUE=DATE:20050503 +DTSTAMP:20041120T000000Z +SUMMARY:Escaped Comma in Description Field +DESCRIPTION:There is a comma (escaped with a baskslash) in this sentence + and some important words after it\, see anything here? +END:VEVENT +BEGIN:VEVENT +UID:20041120-8549-innerjoin-org +DTSTART;VALUE=DATE:20050504 +DTSTAMP:20041120T000000Z +SUMMARY:Dash (rather than Comma) in the Description Field +DESCRIPTION:There are important words after this dash - see anything here + or have the words gone? +END:VEVENT +END:VCALENDAR', + $ical->export()); + } + +} \ No newline at end of file -- 2.11.0