mirror of
https://github.com/the-djmaze/snappymail.git
synced 2026-09-06 16:07:03 +03:00
CardDAV first look
This commit is contained in:
parent
c031a946e8
commit
7648000521
217 changed files with 31899 additions and 12 deletions
|
|
@ -0,0 +1,125 @@
|
|||
<?php
|
||||
|
||||
namespace Sabre\VObject\Property;
|
||||
|
||||
use Sabre\VObject;
|
||||
|
||||
/**
|
||||
* Compound property.
|
||||
*
|
||||
* This class adds (de)serialization of compound properties to/from arrays.
|
||||
*
|
||||
* Currently the following properties from RFC 6350 are mapped to use this
|
||||
* class:
|
||||
*
|
||||
* N: Section 6.2.2
|
||||
* ADR: Section 6.3.1
|
||||
* ORG: Section 6.6.4
|
||||
* CATEGORIES: Section 6.7.1
|
||||
*
|
||||
* In order to use this correctly, you must call setParts and getParts to
|
||||
* retrieve and modify dates respectively.
|
||||
*
|
||||
* @author Thomas Tanghus (http://tanghus.net/)
|
||||
* @author Lars Kneschke
|
||||
* @author Evert Pot (http://evertpot.com/)
|
||||
* @copyright Copyright (C) 2007-2013 fruux GmbH (https://fruux.com/).
|
||||
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
|
||||
*/
|
||||
class Compound extends VObject\Property {
|
||||
|
||||
/**
|
||||
* If property names are added to this map, they will be (de)serialised as arrays
|
||||
* using the getParts() and setParts() methods.
|
||||
* The keys are the property names, values are delimiter chars.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
static public $delimiterMap = array(
|
||||
'N' => ';',
|
||||
'ADR' => ';',
|
||||
'ORG' => ';',
|
||||
'CATEGORIES' => ',',
|
||||
);
|
||||
|
||||
/**
|
||||
* The currently used delimiter.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $delimiter = null;
|
||||
|
||||
/**
|
||||
* Get a compound value as an array.
|
||||
*
|
||||
* @param $name string
|
||||
* @return array
|
||||
*/
|
||||
public function getParts() {
|
||||
|
||||
if (is_null($this->value)) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$delimiter = $this->getDelimiter();
|
||||
|
||||
// split by any $delimiter which is NOT prefixed by a slash.
|
||||
// Note that this is not a a perfect solution. If a value is prefixed
|
||||
// by two slashes, it should actually be split anyway.
|
||||
//
|
||||
// Hopefully we can fix this better in a future version, where we can
|
||||
// break compatibility a bit.
|
||||
$compoundValues = preg_split("/(?<!\\\)$delimiter/", $this->value);
|
||||
|
||||
// remove slashes from any semicolon and comma left escaped in the single values
|
||||
$compoundValues = array_map(
|
||||
function($val) {
|
||||
return strtr($val, array('\,' => ',', '\;' => ';'));
|
||||
}, $compoundValues);
|
||||
|
||||
return $compoundValues;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the delimiter for this property.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getDelimiter() {
|
||||
|
||||
if (!$this->delimiter) {
|
||||
if (isset(self::$delimiterMap[$this->name])) {
|
||||
$this->delimiter = self::$delimiterMap[$this->name];
|
||||
} else {
|
||||
// To be a bit future proof, we are going to default the
|
||||
// delimiter to ;
|
||||
$this->delimiter = ';';
|
||||
}
|
||||
}
|
||||
return $this->delimiter;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a compound value as an array.
|
||||
*
|
||||
*
|
||||
* @param $name string
|
||||
* @return array
|
||||
*/
|
||||
public function setParts(array $values) {
|
||||
|
||||
// add slashes to all semicolons and commas in the single values
|
||||
$values = array_map(
|
||||
function($val) {
|
||||
return strtr($val, array(',' => '\,', ';' => '\;'));
|
||||
}, $values);
|
||||
|
||||
$this->setValue(
|
||||
implode($this->getDelimiter(), $values)
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,245 @@
|
|||
<?php
|
||||
|
||||
namespace Sabre\VObject\Property;
|
||||
|
||||
use Sabre\VObject;
|
||||
|
||||
/**
|
||||
* DateTime property
|
||||
*
|
||||
* This element is used for iCalendar properties such as the DTSTART property.
|
||||
* It basically provides a few helper functions that make it easier to deal
|
||||
* with these. It supports both DATE-TIME and DATE values.
|
||||
*
|
||||
* In order to use this correctly, you must call setDateTime and getDateTime to
|
||||
* retrieve and modify dates respectively.
|
||||
*
|
||||
* If you use the 'value' or properties directly, this object does not keep
|
||||
* reference and results might appear incorrectly.
|
||||
*
|
||||
* @copyright Copyright (C) 2007-2013 fruux GmbH (https://fruux.com/).
|
||||
* @author Evert Pot (http://evertpot.com/)
|
||||
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
|
||||
*/
|
||||
class DateTime extends VObject\Property {
|
||||
|
||||
/**
|
||||
* Local 'floating' time
|
||||
*/
|
||||
const LOCAL = 1;
|
||||
|
||||
/**
|
||||
* UTC-based time
|
||||
*/
|
||||
const UTC = 2;
|
||||
|
||||
/**
|
||||
* Local time plus timezone
|
||||
*/
|
||||
const LOCALTZ = 3;
|
||||
|
||||
/**
|
||||
* Only a date, time is ignored
|
||||
*/
|
||||
const DATE = 4;
|
||||
|
||||
/**
|
||||
* DateTime representation
|
||||
*
|
||||
* @var \DateTime
|
||||
*/
|
||||
protected $dateTime;
|
||||
|
||||
/**
|
||||
* dateType
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $dateType;
|
||||
|
||||
/**
|
||||
* Updates the Date and Time.
|
||||
*
|
||||
* @param \DateTime $dt
|
||||
* @param int $dateType
|
||||
* @return void
|
||||
*/
|
||||
public function setDateTime(\DateTime $dt, $dateType = self::LOCALTZ) {
|
||||
|
||||
switch($dateType) {
|
||||
|
||||
case self::LOCAL :
|
||||
$this->setValue($dt->format('Ymd\\THis'));
|
||||
$this->offsetUnset('VALUE');
|
||||
$this->offsetUnset('TZID');
|
||||
$this->offsetSet('VALUE','DATE-TIME');
|
||||
break;
|
||||
case self::UTC :
|
||||
$dt->setTimeZone(new \DateTimeZone('UTC'));
|
||||
$this->setValue($dt->format('Ymd\\THis\\Z'));
|
||||
$this->offsetUnset('VALUE');
|
||||
$this->offsetUnset('TZID');
|
||||
$this->offsetSet('VALUE','DATE-TIME');
|
||||
break;
|
||||
case self::LOCALTZ :
|
||||
$this->setValue($dt->format('Ymd\\THis'));
|
||||
$this->offsetUnset('VALUE');
|
||||
$this->offsetUnset('TZID');
|
||||
$this->offsetSet('VALUE','DATE-TIME');
|
||||
$this->offsetSet('TZID', $dt->getTimeZone()->getName());
|
||||
break;
|
||||
case self::DATE :
|
||||
$this->setValue($dt->format('Ymd'));
|
||||
$this->offsetUnset('VALUE');
|
||||
$this->offsetUnset('TZID');
|
||||
$this->offsetSet('VALUE','DATE');
|
||||
break;
|
||||
default :
|
||||
throw new \InvalidArgumentException('You must pass a valid dateType constant');
|
||||
|
||||
}
|
||||
$this->dateTime = $dt;
|
||||
$this->dateType = $dateType;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current DateTime value.
|
||||
*
|
||||
* If no value was set, this method returns null.
|
||||
*
|
||||
* @return \DateTime|null
|
||||
*/
|
||||
public function getDateTime() {
|
||||
|
||||
if ($this->dateTime)
|
||||
return $this->dateTime;
|
||||
|
||||
list(
|
||||
$this->dateType,
|
||||
$this->dateTime
|
||||
) = self::parseData($this->value, $this);
|
||||
return $this->dateTime;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the type of Date format.
|
||||
*
|
||||
* This method returns one of the format constants. If no date was set,
|
||||
* this method will return null.
|
||||
*
|
||||
* @return int|null
|
||||
*/
|
||||
public function getDateType() {
|
||||
|
||||
if ($this->dateType)
|
||||
return $this->dateType;
|
||||
|
||||
list(
|
||||
$this->dateType,
|
||||
$this->dateTime,
|
||||
) = self::parseData($this->value, $this);
|
||||
return $this->dateType;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will return true, if the property had a date and a time, as
|
||||
* opposed to only a date.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function hasTime() {
|
||||
|
||||
return $this->getDateType()!==self::DATE;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the internal data structure to figure out what the current date
|
||||
* and time is.
|
||||
*
|
||||
* The returned array contains two elements:
|
||||
* 1. A 'DateType' constant (as defined on this class), or null.
|
||||
* 2. A DateTime object (or null)
|
||||
*
|
||||
* @param string|null $propertyValue The string to parse (yymmdd or
|
||||
* ymmddThhmmss, etc..)
|
||||
* @param \Sabre\VObject\Property|null $property The instance of the
|
||||
* property we're parsing.
|
||||
* @return array
|
||||
*/
|
||||
static public function parseData($propertyValue, VObject\Property $property = null) {
|
||||
|
||||
if (is_null($propertyValue)) {
|
||||
return array(null, null);
|
||||
}
|
||||
|
||||
$date = '(?P<year>[1-2][0-9]{3})(?P<month>[0-1][0-9])(?P<date>[0-3][0-9])';
|
||||
$time = '(?P<hour>[0-2][0-9])(?P<minute>[0-5][0-9])(?P<second>[0-5][0-9])';
|
||||
$regex = "/^$date(T$time(?P<isutc>Z)?)?$/";
|
||||
|
||||
if (!preg_match($regex, $propertyValue, $matches)) {
|
||||
throw new \InvalidArgumentException($propertyValue . ' is not a valid \DateTime or Date string');
|
||||
}
|
||||
|
||||
if (!isset($matches['hour'])) {
|
||||
// Date-only
|
||||
return array(
|
||||
self::DATE,
|
||||
new \DateTime($matches['year'] . '-' . $matches['month'] . '-' . $matches['date'] . ' 00:00:00', new \DateTimeZone('UTC')),
|
||||
);
|
||||
}
|
||||
|
||||
$dateStr =
|
||||
$matches['year'] .'-' .
|
||||
$matches['month'] . '-' .
|
||||
$matches['date'] . ' ' .
|
||||
$matches['hour'] . ':' .
|
||||
$matches['minute'] . ':' .
|
||||
$matches['second'];
|
||||
|
||||
if (isset($matches['isutc'])) {
|
||||
$dt = new \DateTime($dateStr,new \DateTimeZone('UTC'));
|
||||
$dt->setTimeZone(new \DateTimeZone('UTC'));
|
||||
return array(
|
||||
self::UTC,
|
||||
$dt
|
||||
);
|
||||
}
|
||||
|
||||
// Finding the timezone.
|
||||
$tzid = $property['TZID'];
|
||||
if (!$tzid) {
|
||||
// This was a floating time string. This implies we use the
|
||||
// timezone from date_default_timezone_set / date.timezone ini
|
||||
// setting.
|
||||
return array(
|
||||
self::LOCAL,
|
||||
new \DateTime($dateStr)
|
||||
);
|
||||
}
|
||||
|
||||
// To look up the timezone, we must first find the VCALENDAR component.
|
||||
$root = $property;
|
||||
while($root->parent) {
|
||||
$root = $root->parent;
|
||||
}
|
||||
if ($root->name === 'VCALENDAR') {
|
||||
$tz = VObject\TimeZoneUtil::getTimeZone((string)$tzid, $root);
|
||||
} else {
|
||||
$tz = VObject\TimeZoneUtil::getTimeZone((string)$tzid);
|
||||
}
|
||||
|
||||
$dt = new \DateTime($dateStr, $tz);
|
||||
$dt->setTimeZone($tz);
|
||||
|
||||
return array(
|
||||
self::LOCALTZ,
|
||||
$dt
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,180 @@
|
|||
<?php
|
||||
|
||||
namespace Sabre\VObject\Property;
|
||||
|
||||
use Sabre\VObject;
|
||||
|
||||
/**
|
||||
* Multi-DateTime property
|
||||
*
|
||||
* This element is used for iCalendar properties such as the EXDATE property.
|
||||
* It basically provides a few helper functions that make it easier to deal
|
||||
* with these. It supports both DATE-TIME and DATE values.
|
||||
*
|
||||
* In order to use this correctly, you must call setDateTimes and getDateTimes
|
||||
* to retrieve and modify dates respectively.
|
||||
*
|
||||
* If you use the 'value' or properties directly, this object does not keep
|
||||
* reference and results might appear incorrectly.
|
||||
*
|
||||
* @copyright Copyright (C) 2007-2013 fruux GmbH (https://fruux.com/).
|
||||
* @author Evert Pot (http://evertpot.com/)
|
||||
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
|
||||
*/
|
||||
class MultiDateTime extends VObject\Property {
|
||||
|
||||
/**
|
||||
* DateTime representation
|
||||
*
|
||||
* @var DateTime[]
|
||||
*/
|
||||
protected $dateTimes;
|
||||
|
||||
/**
|
||||
* dateType
|
||||
*
|
||||
* This is one of the Sabre\VObject\Property\DateTime constants.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $dateType;
|
||||
|
||||
/**
|
||||
* Updates the value
|
||||
*
|
||||
* @param array $dt Must be an array of DateTime objects.
|
||||
* @param int $dateType
|
||||
* @return void
|
||||
*/
|
||||
public function setDateTimes(array $dt, $dateType = VObject\Property\DateTime::LOCALTZ) {
|
||||
|
||||
foreach($dt as $i)
|
||||
if (!$i instanceof \DateTime)
|
||||
throw new \InvalidArgumentException('You must pass an array of DateTime objects');
|
||||
|
||||
$this->offsetUnset('VALUE');
|
||||
$this->offsetUnset('TZID');
|
||||
switch($dateType) {
|
||||
|
||||
case DateTime::LOCAL :
|
||||
$val = array();
|
||||
foreach($dt as $i) {
|
||||
$val[] = $i->format('Ymd\\THis');
|
||||
}
|
||||
$this->setValue(implode(',',$val));
|
||||
$this->offsetSet('VALUE','DATE-TIME');
|
||||
break;
|
||||
case DateTime::UTC :
|
||||
$val = array();
|
||||
foreach($dt as $i) {
|
||||
$i->setTimeZone(new \DateTimeZone('UTC'));
|
||||
$val[] = $i->format('Ymd\\THis\\Z');
|
||||
}
|
||||
$this->setValue(implode(',',$val));
|
||||
$this->offsetSet('VALUE','DATE-TIME');
|
||||
break;
|
||||
case DateTime::LOCALTZ :
|
||||
$val = array();
|
||||
foreach($dt as $i) {
|
||||
$val[] = $i->format('Ymd\\THis');
|
||||
}
|
||||
$this->setValue(implode(',',$val));
|
||||
$this->offsetSet('VALUE','DATE-TIME');
|
||||
$this->offsetSet('TZID', $dt[0]->getTimeZone()->getName());
|
||||
break;
|
||||
case DateTime::DATE :
|
||||
$val = array();
|
||||
foreach($dt as $i) {
|
||||
$val[] = $i->format('Ymd');
|
||||
}
|
||||
$this->setValue(implode(',',$val));
|
||||
$this->offsetSet('VALUE','DATE');
|
||||
break;
|
||||
default :
|
||||
throw new \InvalidArgumentException('You must pass a valid dateType constant');
|
||||
|
||||
}
|
||||
$this->dateTimes = $dt;
|
||||
$this->dateType = $dateType;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current DateTime value.
|
||||
*
|
||||
* If no value was set, this method returns null.
|
||||
*
|
||||
* @return array|null
|
||||
*/
|
||||
public function getDateTimes() {
|
||||
|
||||
if ($this->dateTimes)
|
||||
return $this->dateTimes;
|
||||
|
||||
$dts = array();
|
||||
|
||||
if (!$this->value) {
|
||||
$this->dateTimes = null;
|
||||
$this->dateType = null;
|
||||
return null;
|
||||
}
|
||||
|
||||
foreach(explode(',',$this->value) as $val) {
|
||||
list(
|
||||
$type,
|
||||
$dt
|
||||
) = DateTime::parseData($val, $this);
|
||||
$dts[] = $dt;
|
||||
$this->dateType = $type;
|
||||
}
|
||||
$this->dateTimes = $dts;
|
||||
return $this->dateTimes;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the type of Date format.
|
||||
*
|
||||
* This method returns one of the format constants. If no date was set,
|
||||
* this method will return null.
|
||||
*
|
||||
* @return int|null
|
||||
*/
|
||||
public function getDateType() {
|
||||
|
||||
if ($this->dateType)
|
||||
return $this->dateType;
|
||||
|
||||
if (!$this->value) {
|
||||
$this->dateTimes = null;
|
||||
$this->dateType = null;
|
||||
return null;
|
||||
}
|
||||
|
||||
$dts = array();
|
||||
foreach(explode(',',$this->value) as $val) {
|
||||
list(
|
||||
$type,
|
||||
$dt
|
||||
) = DateTime::parseData($val, $this);
|
||||
$dts[] = $dt;
|
||||
$this->dateType = $type;
|
||||
}
|
||||
$this->dateTimes = $dts;
|
||||
return $this->dateType;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* This method will return true, if the property had a date and a time, as
|
||||
* opposed to only a date.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function hasTime() {
|
||||
|
||||
return $this->getDateType()!==DateTime::DATE;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue