Archived
New style calendar generation
This commit is contained in:
1 parent
b27a90ed82
commit
30eccd374a
50 files changed
+5097
-10535
No files matched your search
Whitespace-only changes.
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"require": {
|
||||
"jsvrcek/ics": "^0.5.1"
|
||||
}
|
||||
}
|
||||
Generated
+66
@@ -0,0 +1,66 @@
|
||||
{
|
||||
"_readme": [
|
||||
"This file locks the dependencies of your project to a known state",
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "dc0b84df01241ef3d112862283e7b985",
|
||||
"packages": [
|
||||
{
|
||||
"name": "jsvrcek/ics",
|
||||
"version": "0.5.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/jasvrcek/ICS.git",
|
||||
"reference": "c93b8dba37b35dd0b65d7b76c7d5b8bc38ecc74c"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/jasvrcek/ICS/zipball/c93b8dba37b35dd0b65d7b76c7d5b8bc38ecc74c",
|
||||
"reference": "c93b8dba37b35dd0b65d7b76c7d5b8bc38ecc74c",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^5.3 || ^7.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^4.8 || ^5.5"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Jsvrcek\\ICS\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Justin Svrcek",
|
||||
"homepage": "https://github.com/jasvrcek"
|
||||
}
|
||||
],
|
||||
"description": "abstraction layer for creating multi-byte safe RFC 5545 compliant .ics files",
|
||||
"homepage": "https://github.com/jasvrcek/ICS",
|
||||
"keywords": [
|
||||
".ics",
|
||||
"RFC 5545",
|
||||
"calendar",
|
||||
"export",
|
||||
"ical",
|
||||
"multi-byte safe"
|
||||
],
|
||||
"time": "2017-02-01T20:10:20+00:00"
|
||||
}
|
||||
],
|
||||
"packages-dev": [],
|
||||
"aliases": [],
|
||||
"minimum-stability": "stable",
|
||||
"stability-flags": [],
|
||||
"prefer-stable": false,
|
||||
"prefer-lowest": false,
|
||||
"platform": [],
|
||||
"platform-dev": []
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
@@ -1,6 +1,114 @@
|
||||
<?php
|
||||
/*
|
||||
* Template Name: Ical
|
||||
*
|
||||
* Generate an ical with the event schedule
|
||||
* Uses https://github.com/jasvrcek/ICS
|
||||
*/
|
||||
require get_stylesheet_directory() . '/vendor/autoload.php';
|
||||
|
||||
use Jsvrcek\ICS\CalendarExport;
|
||||
use Jsvrcek\ICS\CalendarStream;
|
||||
use Jsvrcek\ICS\Model\Calendar;
|
||||
use Jsvrcek\ICS\Model\CalendarEvent;
|
||||
use Jsvrcek\ICS\Model\Description\Location;
|
||||
use Jsvrcek\ICS\Utility\Formatter;
|
||||
|
||||
function fetch_events($from = '-6 months', $to = '+1 year') {
|
||||
global $post;
|
||||
$cache_key = 'dns2015-ical-events';
|
||||
$cache_expiry = 30*60; // 30 min in seconds
|
||||
|
||||
$cached_events = wp_cache_get($cache_key);
|
||||
if($cached_events !== false) {
|
||||
return $cached_events;
|
||||
}
|
||||
|
||||
$meta_query = [
|
||||
'key' => '_neuf_events_starttime',
|
||||
'value' => [date('U', strtotime($from)), date('U', strtotime($to))],
|
||||
'type' => 'numeric',
|
||||
'compare' => 'BETWEEN'
|
||||
];
|
||||
|
||||
$args = [
|
||||
'post_type' => 'event',
|
||||
'meta_query' => [$meta_query],
|
||||
'posts_per_page' => -1,
|
||||
'orderby' => 'meta_value_num',
|
||||
'meta_key' => '_neuf_events_starttime',
|
||||
'order' => 'ASC'
|
||||
];
|
||||
|
||||
$events = new WP_Query($args);
|
||||
|
||||
$event_list = [];
|
||||
|
||||
while ($events->have_posts()) {
|
||||
$events->the_post();
|
||||
|
||||
$start = new DateTime('@' . $post->neuf_events_starttime);
|
||||
$end = new DateTime('@' . $post->neuf_events_endtime);
|
||||
$description = strip_tags(get_the_content());
|
||||
$venue = $post->neuf_events_venue;
|
||||
$location = $venue == 'Annetsteds' ? $venue : $venue . ', Chateau Neuf, Slemdalsveien 15, 0313 OSLO';
|
||||
|
||||
array_push($event_list, [
|
||||
'start' => $start,
|
||||
'end' => $end,
|
||||
'locations' => [$location],
|
||||
'summary' => html_entity_decode(get_the_title()),
|
||||
'description' => html_entity_decode($description)
|
||||
]);
|
||||
}
|
||||
|
||||
wp_cache_set($cache_key, $event_list, '', $cache_expiry);
|
||||
|
||||
return $event_list;
|
||||
|
||||
}
|
||||
|
||||
function add_calendar_events($events, $calendar) {
|
||||
foreach ($events as $event) {
|
||||
$calendar_event = new CalendarEvent();
|
||||
$calendar_event->setStart($event['start'])
|
||||
->setEnd($event['end'])
|
||||
->setSummary($event['summary'])
|
||||
->setDescription($event['description'])
|
||||
->setUid('asdf');
|
||||
$calendar_locations = [];
|
||||
foreach ($event['locations'] as $location) {
|
||||
$cal_location = new Location();
|
||||
$cal_location->setName($location);
|
||||
$calendar_locations[] = $cal_location;
|
||||
}
|
||||
$calendar_event->setLocations($calendar_locations);
|
||||
|
||||
|
||||
$calendar->addEvent($calendar_event);
|
||||
|
||||
}
|
||||
return $calendar;
|
||||
}
|
||||
|
||||
$events = fetch_events();
|
||||
|
||||
$wp_timezone = get_option('timezone_string');
|
||||
$custom_cal_headers = [
|
||||
'X-WR-CALNAME' => 'Chateau Neuf / Studentersamfundet',
|
||||
'X-WR-CALDESC' => 'Program for Chateau Neuf - Det Norske Studentersamfund',
|
||||
'X-WR-TIMEZONE' => $wp_timezone
|
||||
];
|
||||
|
||||
$calendar = new Calendar();
|
||||
$calendar->setProdId('-//Chateau Neuf - Det Norske Studentersafund//Program for Chateau Neuf - Det Norske Studentersamfund//NB')
|
||||
->setTimezone(new DateTimeZone($wp_timezone))
|
||||
->setCustomHeaders($custom_cal_headers);
|
||||
|
||||
$calendar = add_calendar_events($events, $calendar);
|
||||
|
||||
//setup exporter and out .ics formatted text
|
||||
$calendarExport = new CalendarExport(new CalendarStream, new Formatter());
|
||||
$calendarExport->addCalendar($calendar);
|
||||
header("Content-type: text/calendar; charset=utf-8");
|
||||
echo file_get_contents(get_bloginfo('stylesheet_directory')."/cal/studentersamfundet.ics");
|
||||
echo $calendarExport->getStream();
|
||||
@@ -1,62 +0,0 @@
|
||||
<?php
|
||||
/** Usage with WP-CLI
|
||||
* wp --path=/path/to/wordpress eval-file program-ical-regen.php
|
||||
*/
|
||||
require_once('../inc/iCalcreator.class.php');
|
||||
//http://kigkonsult.se/iCalcreator/
|
||||
|
||||
$config = array(
|
||||
"unique_id" => "studentersamfundet.no",
|
||||
"directory" => "cal",
|
||||
"filename" => "studentersamfundet.ics"
|
||||
);
|
||||
$v = new vcalendar($config);
|
||||
$tz = "Europe/Oslo";
|
||||
|
||||
$v->setProperty("method", "PUBLISH");
|
||||
$v->setProperty("x-wr-calname", "Studentersamfundet");
|
||||
$v->setProperty("x-wr-caldesc", "Program for Det Norske Studentersamfund / Chateau Neuf");
|
||||
$v->setProperty("x-wr-timezone", $tz);
|
||||
$xprops = array("X-LIC-LOCATION" => $tz);
|
||||
iCalUtilityFunctions::createTimezone($v, $tz, $xprops);
|
||||
|
||||
$meta_query = array(
|
||||
'key' => '_neuf_events_starttime',
|
||||
'value' => array(date('U', strtotime('-6 months')), date('U', strtotime('+1 year'))),
|
||||
'type' => 'numeric',
|
||||
'compare' => 'BETWEEN'
|
||||
);
|
||||
|
||||
$args = array(
|
||||
'post_type' => 'event',
|
||||
'meta_query' => array($meta_query),
|
||||
'posts_per_page' => -1,
|
||||
'orderby' => 'meta_value_num',
|
||||
'meta_key' => '_neuf_events_starttime',
|
||||
'order' => 'ASC'
|
||||
);
|
||||
|
||||
$events = new WP_Query($args);
|
||||
|
||||
if ($events->have_posts()) {
|
||||
while ($events->have_posts()) {
|
||||
$events->the_post();
|
||||
|
||||
$neuf_events_starttime = $post->neuf_events_starttime;
|
||||
$neuf_events_endtime = $post->neuf_events_endtime;
|
||||
$neuf_events_venue = $post->neuf_events_venue;
|
||||
|
||||
$dtstart = date_i18n('Ymd\THis', (int) $neuf_events_starttime);
|
||||
$dtend = date_i18n('Ymd\THis', (int) $neuf_events_endtime);
|
||||
$description = strip_tags(get_the_content());
|
||||
|
||||
$vevent = & $v->newComponent("vevent");
|
||||
$vevent->setProperty("dtstart", $dtstart);
|
||||
$vevent->setProperty("dtend", $dtend);
|
||||
$vevent->setProperty("location", $neuf_events_venue);
|
||||
$vevent->setProperty("summary", html_entity_decode(get_the_title()));
|
||||
$vevent->setProperty("description", html_entity_decode($description));
|
||||
}
|
||||
}
|
||||
|
||||
$v->saveCalendar();
|
||||
Vendored
+7
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
|
||||
// autoload.php @generated by Composer
|
||||
|
||||
require_once __DIR__ . '/composer/autoload_real.php';
|
||||
|
||||
return ComposerAutoloaderInitc474cc171e7801a4a7be7490bdfb66aa::getLoader();
|
||||
+445
@@ -0,0 +1,445 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Composer.
|
||||
*
|
||||
* (c) Nils Adermann <naderman@naderman.de>
|
||||
* Jordi Boggiano <j.boggiano@seld.be>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Composer\Autoload;
|
||||
|
||||
/**
|
||||
* ClassLoader implements a PSR-0, PSR-4 and classmap class loader.
|
||||
*
|
||||
* $loader = new \Composer\Autoload\ClassLoader();
|
||||
*
|
||||
* // register classes with namespaces
|
||||
* $loader->add('Symfony\Component', __DIR__.'/component');
|
||||
* $loader->add('Symfony', __DIR__.'/framework');
|
||||
*
|
||||
* // activate the autoloader
|
||||
* $loader->register();
|
||||
*
|
||||
* // to enable searching the include path (eg. for PEAR packages)
|
||||
* $loader->setUseIncludePath(true);
|
||||
*
|
||||
* In this example, if you try to use a class in the Symfony\Component
|
||||
* namespace or one of its children (Symfony\Component\Console for instance),
|
||||
* the autoloader will first look for the class under the component/
|
||||
* directory, and it will then fallback to the framework/ directory if not
|
||||
* found before giving up.
|
||||
*
|
||||
* This class is loosely based on the Symfony UniversalClassLoader.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
* @author Jordi Boggiano <j.boggiano@seld.be>
|
||||
* @see http://www.php-fig.org/psr/psr-0/
|
||||
* @see http://www.php-fig.org/psr/psr-4/
|
||||
*/
|
||||
class ClassLoader
|
||||
{
|
||||
// PSR-4
|
||||
private $prefixLengthsPsr4 = array();
|
||||
private $prefixDirsPsr4 = array();
|
||||
private $fallbackDirsPsr4 = array();
|
||||
|
||||
// PSR-0
|
||||
private $prefixesPsr0 = array();
|
||||
private $fallbackDirsPsr0 = array();
|
||||
|
||||
private $useIncludePath = false;
|
||||
private $classMap = array();
|
||||
private $classMapAuthoritative = false;
|
||||
private $missingClasses = array();
|
||||
private $apcuPrefix;
|
||||
|
||||
public function getPrefixes()
|
||||
{
|
||||
if (!empty($this->prefixesPsr0)) {
|
||||
return call_user_func_array('array_merge', $this->prefixesPsr0);
|
||||
}
|
||||
|
||||
return array();
|
||||
}
|
||||
|
||||
public function getPrefixesPsr4()
|
||||
{
|
||||
return $this->prefixDirsPsr4;
|
||||
}
|
||||
|
||||
public function getFallbackDirs()
|
||||
{
|
||||
return $this->fallbackDirsPsr0;
|
||||
}
|
||||
|
||||
public function getFallbackDirsPsr4()
|
||||
{
|
||||
return $this->fallbackDirsPsr4;
|
||||
}
|
||||
|
||||
public function getClassMap()
|
||||
{
|
||||
return $this->classMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $classMap Class to filename map
|
||||
*/
|
||||
public function addClassMap(array $classMap)
|
||||
{
|
||||
if ($this->classMap) {
|
||||
$this->classMap = array_merge($this->classMap, $classMap);
|
||||
} else {
|
||||
$this->classMap = $classMap;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a set of PSR-0 directories for a given prefix, either
|
||||
* appending or prepending to the ones previously set for this prefix.
|
||||
*
|
||||
* @param string $prefix The prefix
|
||||
* @param array|string $paths The PSR-0 root directories
|
||||
* @param bool $prepend Whether to prepend the directories
|
||||
*/
|
||||
public function add($prefix, $paths, $prepend = false)
|
||||
{
|
||||
if (!$prefix) {
|
||||
if ($prepend) {
|
||||
$this->fallbackDirsPsr0 = array_merge(
|
||||
(array) $paths,
|
||||
$this->fallbackDirsPsr0
|
||||
);
|
||||
} else {
|
||||
$this->fallbackDirsPsr0 = array_merge(
|
||||
$this->fallbackDirsPsr0,
|
||||
(array) $paths
|
||||
);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$first = $prefix[0];
|
||||
if (!isset($this->prefixesPsr0[$first][$prefix])) {
|
||||
$this->prefixesPsr0[$first][$prefix] = (array) $paths;
|
||||
|
||||
return;
|
||||
}
|
||||
if ($prepend) {
|
||||
$this->prefixesPsr0[$first][$prefix] = array_merge(
|
||||
(array) $paths,
|
||||
$this->prefixesPsr0[$first][$prefix]
|
||||
);
|
||||
} else {
|
||||
$this->prefixesPsr0[$first][$prefix] = array_merge(
|
||||
$this->prefixesPsr0[$first][$prefix],
|
||||
(array) $paths
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a set of PSR-4 directories for a given namespace, either
|
||||
* appending or prepending to the ones previously set for this namespace.
|
||||
*
|
||||
* @param string $prefix The prefix/namespace, with trailing '\\'
|
||||
* @param array|string $paths The PSR-4 base directories
|
||||
* @param bool $prepend Whether to prepend the directories
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function addPsr4($prefix, $paths, $prepend = false)
|
||||
{
|
||||
if (!$prefix) {
|
||||
// Register directories for the root namespace.
|
||||
if ($prepend) {
|
||||
$this->fallbackDirsPsr4 = array_merge(
|
||||
(array) $paths,
|
||||
$this->fallbackDirsPsr4
|
||||
);
|
||||
} else {
|
||||
$this->fallbackDirsPsr4 = array_merge(
|
||||
$this->fallbackDirsPsr4,
|
||||
(array) $paths
|
||||
);
|
||||
}
|
||||
} elseif (!isset($this->prefixDirsPsr4[$prefix])) {
|
||||
// Register directories for a new namespace.
|
||||
$length = strlen($prefix);
|
||||
if ('\\' !== $prefix[$length - 1]) {
|
||||
throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
|
||||
}
|
||||
$this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
|
||||
$this->prefixDirsPsr4[$prefix] = (array) $paths;
|
||||
} elseif ($prepend) {
|
||||
// Prepend directories for an already registered namespace.
|
||||
$this->prefixDirsPsr4[$prefix] = array_merge(
|
||||
(array) $paths,
|
||||
$this->prefixDirsPsr4[$prefix]
|
||||
);
|
||||
} else {
|
||||
// Append directories for an already registered namespace.
|
||||
$this->prefixDirsPsr4[$prefix] = array_merge(
|
||||
$this->prefixDirsPsr4[$prefix],
|
||||
(array) $paths
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a set of PSR-0 directories for a given prefix,
|
||||
* replacing any others previously set for this prefix.
|
||||
*
|
||||
* @param string $prefix The prefix
|
||||
* @param array|string $paths The PSR-0 base directories
|
||||
*/
|
||||
public function set($prefix, $paths)
|
||||
{
|
||||
if (!$prefix) {
|
||||
$this->fallbackDirsPsr0 = (array) $paths;
|
||||
} else {
|
||||
$this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a set of PSR-4 directories for a given namespace,
|
||||
* replacing any others previously set for this namespace.
|
||||
*
|
||||
* @param string $prefix The prefix/namespace, with trailing '\\'
|
||||
* @param array|string $paths The PSR-4 base directories
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function setPsr4($prefix, $paths)
|
||||
{
|
||||
if (!$prefix) {
|
||||
$this->fallbackDirsPsr4 = (array) $paths;
|
||||
} else {
|
||||
$length = strlen($prefix);
|
||||
if ('\\' !== $prefix[$length - 1]) {
|
||||
throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
|
||||
}
|
||||
$this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
|
||||
$this->prefixDirsPsr4[$prefix] = (array) $paths;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Turns on searching the include path for class files.
|
||||
*
|
||||
* @param bool $useIncludePath
|
||||
*/
|
||||
public function setUseIncludePath($useIncludePath)
|
||||
{
|
||||
$this->useIncludePath = $useIncludePath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Can be used to check if the autoloader uses the include path to check
|
||||
* for classes.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function getUseIncludePath()
|
||||
{
|
||||
return $this->useIncludePath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Turns off searching the prefix and fallback directories for classes
|
||||
* that have not been registered with the class map.
|
||||
*
|
||||
* @param bool $classMapAuthoritative
|
||||
*/
|
||||
public function setClassMapAuthoritative($classMapAuthoritative)
|
||||
{
|
||||
$this->classMapAuthoritative = $classMapAuthoritative;
|
||||
}
|
||||
|
||||
/**
|
||||
* Should class lookup fail if not found in the current class map?
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isClassMapAuthoritative()
|
||||
{
|
||||
return $this->classMapAuthoritative;
|
||||
}
|
||||
|
||||
/**
|
||||
* APCu prefix to use to cache found/not-found classes, if the extension is enabled.
|
||||
*
|
||||
* @param string|null $apcuPrefix
|
||||
*/
|
||||
public function setApcuPrefix($apcuPrefix)
|
||||
{
|
||||
$this->apcuPrefix = function_exists('apcu_fetch') && ini_get('apc.enabled') ? $apcuPrefix : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* The APCu prefix in use, or null if APCu caching is not enabled.
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
public function getApcuPrefix()
|
||||
{
|
||||
return $this->apcuPrefix;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers this instance as an autoloader.
|
||||
*
|
||||
* @param bool $prepend Whether to prepend the autoloader or not
|
||||
*/
|
||||
public function register($prepend = false)
|
||||
{
|
||||
spl_autoload_register(array($this, 'loadClass'), true, $prepend);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregisters this instance as an autoloader.
|
||||
*/
|
||||
public function unregister()
|
||||
{
|
||||
spl_autoload_unregister(array($this, 'loadClass'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the given class or interface.
|
||||
*
|
||||
* @param string $class The name of the class
|
||||
* @return bool|null True if loaded, null otherwise
|
||||
*/
|
||||
public function loadClass($class)
|
||||
{
|
||||
if ($file = $this->findFile($class)) {
|
||||
includeFile($file);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the path to the file where the class is defined.
|
||||
*
|
||||
* @param string $class The name of the class
|
||||
*
|
||||
* @return string|false The path if found, false otherwise
|
||||
*/
|
||||
public function findFile($class)
|
||||
{
|
||||
// class map lookup
|
||||
if (isset($this->classMap[$class])) {
|
||||
return $this->classMap[$class];
|
||||
}
|
||||
if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) {
|
||||
return false;
|
||||
}
|
||||
if (null !== $this->apcuPrefix) {
|
||||
$file = apcu_fetch($this->apcuPrefix.$class, $hit);
|
||||
if ($hit) {
|
||||
return $file;
|
||||
}
|
||||
}
|
||||
|
||||
$file = $this->findFileWithExtension($class, '.php');
|
||||
|
||||
// Search for Hack files if we are running on HHVM
|
||||
if (false === $file && defined('HHVM_VERSION')) {
|
||||
$file = $this->findFileWithExtension($class, '.hh');
|
||||
}
|
||||
|
||||
if (null !== $this->apcuPrefix) {
|
||||
apcu_add($this->apcuPrefix.$class, $file);
|
||||
}
|
||||
|
||||
if (false === $file) {
|
||||
// Remember that this class does not exist.
|
||||
$this->missingClasses[$class] = true;
|
||||
}
|
||||
|
||||
return $file;
|
||||
}
|
||||
|
||||
private function findFileWithExtension($class, $ext)
|
||||
{
|
||||
// PSR-4 lookup
|
||||
$logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext;
|
||||
|
||||
$first = $class[0];
|
||||
if (isset($this->prefixLengthsPsr4[$first])) {
|
||||
$subPath = $class;
|
||||
while (false !== $lastPos = strrpos($subPath, '\\')) {
|
||||
$subPath = substr($subPath, 0, $lastPos);
|
||||
$search = $subPath.'\\';
|
||||
if (isset($this->prefixDirsPsr4[$search])) {
|
||||
foreach ($this->prefixDirsPsr4[$search] as $dir) {
|
||||
$length = $this->prefixLengthsPsr4[$first][$search];
|
||||
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $length))) {
|
||||
return $file;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// PSR-4 fallback dirs
|
||||
foreach ($this->fallbackDirsPsr4 as $dir) {
|
||||
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) {
|
||||
return $file;
|
||||
}
|
||||
}
|
||||
|
||||
// PSR-0 lookup
|
||||
if (false !== $pos = strrpos($class, '\\')) {
|
||||
// namespaced class name
|
||||
$logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1)
|
||||
. strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR);
|
||||
} else {
|
||||
// PEAR-like class name
|
||||
$logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext;
|
||||
}
|
||||
|
||||
if (isset($this->prefixesPsr0[$first])) {
|
||||
foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) {
|
||||
if (0 === strpos($class, $prefix)) {
|
||||
foreach ($dirs as $dir) {
|
||||
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
|
||||
return $file;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// PSR-0 fallback dirs
|
||||
foreach ($this->fallbackDirsPsr0 as $dir) {
|
||||
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
|
||||
return $file;
|
||||
}
|
||||
}
|
||||
|
||||
// PSR-0 include paths.
|
||||
if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) {
|
||||
return $file;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Scope isolated include.
|
||||
*
|
||||
* Prevents access to $this/self from included files.
|
||||
*/
|
||||
function includeFile($file)
|
||||
{
|
||||
include $file;
|
||||
}
|
||||
Vendored
+56
@@ -0,0 +1,56 @@
|
||||
Format: http://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
|
||||
Upstream-Name: Composer
|
||||
Upstream-Contact: Jordi Boggiano <j.boggiano@seld.be>
|
||||
Source: https://github.com/composer/composer
|
||||
|
||||
Files: *
|
||||
Copyright: 2016, Nils Adermann <naderman@naderman.de>
|
||||
2016, Jordi Boggiano <j.boggiano@seld.be>
|
||||
License: Expat
|
||||
|
||||
Files: src/Composer/Util/TlsHelper.php
|
||||
Copyright: 2016, Nils Adermann <naderman@naderman.de>
|
||||
2016, Jordi Boggiano <j.boggiano@seld.be>
|
||||
2013, Evan Coury <me@evancoury.com>
|
||||
License: Expat and BSD-2-Clause
|
||||
|
||||
License: BSD-2-Clause
|
||||
Redistribution and use in source and binary forms, with or without modification,
|
||||
are permitted provided that the following conditions are met:
|
||||
.
|
||||
* Redistributions of source code must retain the above copyright notice,
|
||||
this list of conditions and the following disclaimer.
|
||||
.
|
||||
* Redistributions in binary form must reproduce the above copyright notice,
|
||||
this list of conditions and the following disclaimer in the documentation
|
||||
and/or other materials provided with the distribution.
|
||||
.
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
|
||||
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
License: Expat
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is furnished
|
||||
to do so, subject to the following conditions:
|
||||
.
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
.
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
// autoload_classmap.php @generated by Composer
|
||||
|
||||
$vendorDir = dirname(dirname(__FILE__));
|
||||
$baseDir = dirname($vendorDir);
|
||||
|
||||
return array(
|
||||
);
|
||||
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
// autoload_namespaces.php @generated by Composer
|
||||
|
||||
$vendorDir = dirname(dirname(__FILE__));
|
||||
$baseDir = dirname($vendorDir);
|
||||
|
||||
return array(
|
||||
);
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
// autoload_psr4.php @generated by Composer
|
||||
|
||||
$vendorDir = dirname(dirname(__FILE__));
|
||||
$baseDir = dirname($vendorDir);
|
||||
|
||||
return array(
|
||||
'Jsvrcek\\ICS\\' => array($vendorDir . '/jsvrcek/ics/src'),
|
||||
);
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
<?php
|
||||
|
||||
// autoload_real.php @generated by Composer
|
||||
|
||||
class ComposerAutoloaderInitc474cc171e7801a4a7be7490bdfb66aa
|
||||
{
|
||||
private static $loader;
|
||||
|
||||
public static function loadClassLoader($class)
|
||||
{
|
||||
if ('Composer\Autoload\ClassLoader' === $class) {
|
||||
require __DIR__ . '/ClassLoader.php';
|
||||
}
|
||||
}
|
||||
|
||||
public static function getLoader()
|
||||
{
|
||||
if (null !== self::$loader) {
|
||||
return self::$loader;
|
||||
}
|
||||
|
||||
spl_autoload_register(array('ComposerAutoloaderInitc474cc171e7801a4a7be7490bdfb66aa', 'loadClassLoader'), true, true);
|
||||
self::$loader = $loader = new \Composer\Autoload\ClassLoader();
|
||||
spl_autoload_unregister(array('ComposerAutoloaderInitc474cc171e7801a4a7be7490bdfb66aa', 'loadClassLoader'));
|
||||
|
||||
$useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
|
||||
if ($useStaticLoader) {
|
||||
require_once __DIR__ . '/autoload_static.php';
|
||||
|
||||
call_user_func(\Composer\Autoload\ComposerStaticInitc474cc171e7801a4a7be7490bdfb66aa::getInitializer($loader));
|
||||
} else {
|
||||
$map = require __DIR__ . '/autoload_namespaces.php';
|
||||
foreach ($map as $namespace => $path) {
|
||||
$loader->set($namespace, $path);
|
||||
}
|
||||
|
||||
$map = require __DIR__ . '/autoload_psr4.php';
|
||||
foreach ($map as $namespace => $path) {
|
||||
$loader->setPsr4($namespace, $path);
|
||||
}
|
||||
|
||||
$classMap = require __DIR__ . '/autoload_classmap.php';
|
||||
if ($classMap) {
|
||||
$loader->addClassMap($classMap);
|
||||
}
|
||||
}
|
||||
|
||||
$loader->register(true);
|
||||
|
||||
return $loader;
|
||||
}
|
||||
}
|
||||
+31
@@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
// autoload_static.php @generated by Composer
|
||||
|
||||
namespace Composer\Autoload;
|
||||
|
||||
class ComposerStaticInitc474cc171e7801a4a7be7490bdfb66aa
|
||||
{
|
||||
public static $prefixLengthsPsr4 = array (
|
||||
'J' =>
|
||||
array (
|
||||
'Jsvrcek\\ICS\\' => 12,
|
||||
),
|
||||
);
|
||||
|
||||
public static $prefixDirsPsr4 = array (
|
||||
'Jsvrcek\\ICS\\' =>
|
||||
array (
|
||||
0 => __DIR__ . '/..' . '/jsvrcek/ics/src',
|
||||
),
|
||||
);
|
||||
|
||||
public static function getInitializer(ClassLoader $loader)
|
||||
{
|
||||
return \Closure::bind(function () use ($loader) {
|
||||
$loader->prefixLengthsPsr4 = ComposerStaticInitc474cc171e7801a4a7be7490bdfb66aa::$prefixLengthsPsr4;
|
||||
$loader->prefixDirsPsr4 = ComposerStaticInitc474cc171e7801a4a7be7490bdfb66aa::$prefixDirsPsr4;
|
||||
|
||||
}, null, ClassLoader::class);
|
||||
}
|
||||
}
|
||||
+52
@@ -0,0 +1,52 @@
|
||||
[
|
||||
{
|
||||
"name": "jsvrcek/ics",
|
||||
"version": "0.5.1",
|
||||
"version_normalized": "0.5.1.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/jasvrcek/ICS.git",
|
||||
"reference": "c93b8dba37b35dd0b65d7b76c7d5b8bc38ecc74c"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/jasvrcek/ICS/zipball/c93b8dba37b35dd0b65d7b76c7d5b8bc38ecc74c",
|
||||
"reference": "c93b8dba37b35dd0b65d7b76c7d5b8bc38ecc74c",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^5.3 || ^7.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^4.8 || ^5.5"
|
||||
},
|
||||
"time": "2017-02-01T20:10:20+00:00",
|
||||
"type": "library",
|
||||
"installation-source": "dist",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Jsvrcek\\ICS\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Justin Svrcek",
|
||||
"homepage": "https://github.com/jasvrcek"
|
||||
}
|
||||
],
|
||||
"description": "abstraction layer for creating multi-byte safe RFC 5545 compliant .ics files",
|
||||
"homepage": "https://github.com/jasvrcek/ICS",
|
||||
"keywords": [
|
||||
".ics",
|
||||
"RFC 5545",
|
||||
"calendar",
|
||||
"export",
|
||||
"ical",
|
||||
"multi-byte safe"
|
||||
]
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,7 @@
|
||||
.buildpath
|
||||
.project
|
||||
.settings
|
||||
.idea
|
||||
vendor
|
||||
composer.lock
|
||||
phpunit.xml
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
language: php
|
||||
|
||||
php:
|
||||
- 5.3
|
||||
- 5.4
|
||||
- 5.5
|
||||
- 5.6
|
||||
- 7.0
|
||||
- 7.1
|
||||
|
||||
sudo: false
|
||||
|
||||
install:
|
||||
- travis_retry composer install --no-interaction --prefer-source
|
||||
|
||||
script:
|
||||
- vendor/bin/phpunit
|
||||
|
||||
Vendored
+147
@@ -0,0 +1,147 @@
|
||||
[](https://travis-ci.org/jasvrcek/ICS)
|
||||
|
||||
ICS
|
||||
===
|
||||
|
||||
Object-oriented php library for creating (and eventually reading) .ics iCal files.
|
||||
|
||||
* This project does not yet support all functionality of the .ics format.
|
||||
|
||||
## 1. Basic Usage
|
||||
|
||||
```php
|
||||
use Jsvrcek\ICS\Model\Calendar;
|
||||
use Jsvrcek\ICS\Model\CalendarEvent;
|
||||
use Jsvrcek\ICS\Model\Relationship\Attendee;
|
||||
use Jsvrcek\ICS\Model\Relationship\Organizer;
|
||||
|
||||
use Jsvrcek\ICS\Utility\Formatter;
|
||||
use Jsvrcek\ICS\CalendarStream;
|
||||
use Jsvrcek\ICS\CalendarExport;
|
||||
|
||||
//setup an event
|
||||
$eventOne = new CalendarEvent();
|
||||
$eventOne->setStart(new \DateTime())
|
||||
->setSummary('Family reunion')
|
||||
->setUid('event-uid');
|
||||
|
||||
//add an Attendee
|
||||
$attendee = new Attendee(new Formatter());
|
||||
$attendee->setValue('moe@example.com')
|
||||
->setName('Moe Smith');
|
||||
$eventOne->addAttendee($attendee);
|
||||
|
||||
//set the Organizer
|
||||
$organizer = new Organizer(new Formatter());
|
||||
$organizer->setValue('heidi@example.com')
|
||||
->setName('Heidi Merkell')
|
||||
->setLanguage('de');
|
||||
$eventOne->setOrganizer($organizer);
|
||||
|
||||
//new event
|
||||
$eventTwo = new CalendarEvent();
|
||||
$eventTwo->setStart(new \DateTime())
|
||||
->setSummary('Dentist Appointment')
|
||||
->setUid('event-uid');
|
||||
|
||||
//setup calendar
|
||||
$calendar = new Calendar();
|
||||
$calendar->setProdId('-//My Company//Cool Calendar App//EN')
|
||||
->addEvent($eventOne)
|
||||
->addEvent($eventTwo);
|
||||
|
||||
//setup exporter
|
||||
$calendarExport = new CalendarExport(new CalendarStream, new Formatter());
|
||||
$calendarExport->addCalendar($calendar);
|
||||
|
||||
//output .ics formatted text
|
||||
echo $calendarExport->getStream();
|
||||
```
|
||||
|
||||
## 2. Batch Event Provider
|
||||
|
||||
The basic usage example will build the complete .ics string in memory and then echo it all
|
||||
at once. This will use a lot of memory for a large calendar. The following example shows
|
||||
how to make CalendarExport::getStream() output each line of the ics file as it is generated, as well as how to set a provider
|
||||
for building the event list of a calendar in batches during export.
|
||||
|
||||
```php
|
||||
use Jsvrcek\ICS\Model\Calendar;
|
||||
use Jsvrcek\ICS\Model\CalendarEvent;
|
||||
|
||||
use Jsvrcek\ICS\Utility\Formatter;
|
||||
use Jsvrcek\ICS\CalendarStream;
|
||||
use Jsvrcek\ICS\CalendarExport;
|
||||
|
||||
//setup calendar
|
||||
$calendar = new Calendar();
|
||||
$calendar->setProdId('-//My Company//Cool Calendar App//EN');
|
||||
|
||||
//setup event provider to add events in batches during event iteration in $calendarExport->getStream()
|
||||
$calendar->setEventsProvider(function ($startKey) use ($myDatabase) {
|
||||
|
||||
//pseudo-code to get a batch of events from database
|
||||
$eventDataArray = $myDatabase->getEventsBatch($startKey);
|
||||
|
||||
$events = array();
|
||||
|
||||
foreach ($eventDataArray as $row)
|
||||
{
|
||||
$event = new CalendarEvent();
|
||||
$event->setStart($row['start_date'])
|
||||
->setSummary($row['summary'])
|
||||
->setUid($row['event_uid']);
|
||||
|
||||
$events[] = $event;
|
||||
}
|
||||
|
||||
return $events;
|
||||
});
|
||||
|
||||
//setup exporter
|
||||
$calendarExport = new CalendarExport(new CalendarStream, new Formatter());
|
||||
$calendarExport->addCalendar($calendar);
|
||||
|
||||
//set exporter to send items directly to output instead of storing in memory
|
||||
$calendarExport->getStreamObject()->setDoImmediateOutput(true);
|
||||
|
||||
//output .ics formatted text
|
||||
echo $calendarExport->getStream();
|
||||
```
|
||||
|
||||
## Todos
|
||||
|
||||
* Jsvrcek\ICS\Model\CalendarTodo
|
||||
|
||||
## Reference
|
||||
|
||||
* http://tools.ietf.org/html/rfc5545
|
||||
|
||||
## Credits
|
||||
|
||||
* Alex Balhatchet at [kaoru](https://github.com/kaoru) implemented CalendarAlarm.
|
||||
* Thijs Wijnmaalen at [thijsw](https://github.com/thijsw/ics-large) provided inspiration on the batch provider code.
|
||||
|
||||
## License
|
||||
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2013 Justin Svrcek
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"name": "jsvrcek/ics",
|
||||
"license": "MIT",
|
||||
"description": "abstraction layer for creating multi-byte safe RFC 5545 compliant .ics files",
|
||||
"keywords": ["ical", "calendar", "export", ".ics", "RFC 5545", "multi-byte safe"],
|
||||
"homepage": "https://github.com/jasvrcek/ICS",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Justin Svrcek",
|
||||
"homepage": "https://github.com/jasvrcek"
|
||||
}
|
||||
],
|
||||
"require": {
|
||||
"php": "^5.3 || ^7.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^4.8 || ^5.5"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Jsvrcek\\ICS\\": "src/"
|
||||
}
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"Jsvrcek\\ICS\\Test\\": "src/"
|
||||
}
|
||||
}
|
||||
}
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<phpunit backupGlobals="false"
|
||||
backupStaticAttributes="false"
|
||||
beStrictAboutTestsThatDoNotTestAnything="true"
|
||||
beStrictAboutOutputDuringTests="true"
|
||||
bootstrap="vendor/autoload.php"
|
||||
colors="true"
|
||||
convertErrorsToExceptions="true"
|
||||
convertNoticesToExceptions="true"
|
||||
convertWarningsToExceptions="true"
|
||||
failOnRisky="true"
|
||||
failOnWarning="true"
|
||||
processIsolation="false"
|
||||
stopOnError="false"
|
||||
stopOnFailure="false"
|
||||
verbose="true"
|
||||
>
|
||||
<testsuites>
|
||||
<testsuite name="ICS Test Suite">
|
||||
<directory suffix="Test.php">./tests</directory>
|
||||
</testsuite>
|
||||
</testsuites>
|
||||
<filter>
|
||||
<whitelist processUncoveredFilesFromWhitelist="true">
|
||||
<directory suffix=".php">./src</directory>
|
||||
</whitelist>
|
||||
</filter>
|
||||
</phpunit>
|
||||
+295
@@ -0,0 +1,295 @@
|
||||
<?php
|
||||
|
||||
namespace Jsvrcek\ICS;
|
||||
|
||||
use Jsvrcek\ICS\Model\CalendarAlarm;
|
||||
use Jsvrcek\ICS\Model\Recurrence\RecurrenceRule;
|
||||
|
||||
use Jsvrcek\ICS\Utility\Formatter;
|
||||
|
||||
use Jsvrcek\ICS\Model\Calendar;
|
||||
use Jsvrcek\ICS\Model\CalendarEvent;
|
||||
use Jsvrcek\ICS\Model\Description\Location;
|
||||
use Jsvrcek\ICS\Model\Relationship\Attendee;
|
||||
use Jsvrcek\ICS\Model\Relationship\Organizer;
|
||||
|
||||
use Jsvrcek\ICS\CalendarStream;
|
||||
|
||||
class CalendarExport
|
||||
{
|
||||
/**
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $calendars = array();
|
||||
|
||||
/**
|
||||
*
|
||||
* @var CalendarStream;
|
||||
*/
|
||||
private $stream;
|
||||
|
||||
/**
|
||||
*
|
||||
* @var Formatter
|
||||
*/
|
||||
private $formatter;
|
||||
|
||||
public function __construct(CalendarStream $stream, Formatter $formatter)
|
||||
{
|
||||
$this->stream = $stream;
|
||||
$this->formatter = $formatter;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return CalendarStream
|
||||
*/
|
||||
public function getStreamObject()
|
||||
{
|
||||
return $this->stream;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getStream()
|
||||
{
|
||||
$this->stream->reset();
|
||||
|
||||
/* @var $cal Calendar */
|
||||
foreach ($this->getCalendars() as $cal)
|
||||
{
|
||||
//start calendar
|
||||
$this->stream->addItem('BEGIN:VCALENDAR')
|
||||
->addItem('VERSION:'.$cal->getVersion())
|
||||
->addItem('PRODID:'.$cal->getProdId())
|
||||
->addItem('CALSCALE:'.$cal->getCalendarScale())
|
||||
->addItem('METHOD:'.$cal->getMethod());
|
||||
|
||||
//custom headers
|
||||
foreach ($cal->getCustomHeaders() as $key => $value)
|
||||
{
|
||||
$this->stream->addItem($key.':'.$value);
|
||||
}
|
||||
|
||||
//timezone
|
||||
$this->stream->addItem('BEGIN:VTIMEZONE');
|
||||
|
||||
$tz = $cal->getTimezone();
|
||||
$transitions = $tz->getTransitions(strtotime('1970-01-01'), strtotime('1970-12-31'));
|
||||
|
||||
$daylightSavings = array(
|
||||
'exists' => false,
|
||||
'start' => '',
|
||||
'offsetTo' => '',
|
||||
'offsetFrom' => ''
|
||||
);
|
||||
|
||||
$standard = array(
|
||||
'start' => '',
|
||||
'offsetTo' => '',
|
||||
'offsetFrom' => ''
|
||||
);
|
||||
|
||||
foreach ($transitions as $transition)
|
||||
{
|
||||
$varName = ($transition['isdst']) ? 'daylightSavings' : 'standard';
|
||||
|
||||
${$varName}['exists'] = true;
|
||||
${$varName}['start'] = $this->formatter->getFormattedDateTime(new \DateTime($transition['time']));
|
||||
|
||||
${$varName}['offsetTo'] = $this->formatter->getFormattedTimeOffset($transition['offset']);
|
||||
|
||||
//get previous offset
|
||||
$previousTimezoneObservance = $transition['ts'] - 100;
|
||||
$tzDate = new \DateTime('now', $tz);
|
||||
$tzDate->setTimestamp($previousTimezoneObservance);
|
||||
$offset = $tzDate->getOffset();
|
||||
|
||||
${$varName}['offsetFrom'] = $this->formatter->getFormattedTimeOffset($offset);
|
||||
}
|
||||
|
||||
$this->stream->addItem('TZID:'.$tz->getName());
|
||||
|
||||
$this->stream->addItem('BEGIN:STANDARD')
|
||||
->addItem('DTSTART:'.$standard['start'])
|
||||
->addItem('TZOFFSETTO:'.$standard['offsetTo'])
|
||||
->addItem('TZOFFSETFROM:'.$standard['offsetFrom']);
|
||||
|
||||
if ($daylightSavings['exists'])
|
||||
{
|
||||
$this->stream->addItem('RRULE:FREQ=YEARLY;BYMONTH=11;BYDAY=1SU');
|
||||
}
|
||||
$this->stream->addItem('END:STANDARD');
|
||||
|
||||
if ($daylightSavings['exists'])
|
||||
{
|
||||
$this->stream->addItem('BEGIN:DAYLIGHT')
|
||||
->addItem('DTSTART:'.$daylightSavings['start'])
|
||||
->addItem('TZOFFSETTO:'.$daylightSavings['offsetTo'])
|
||||
->addItem('TZOFFSETFROM:'.$daylightSavings['offsetFrom'])
|
||||
->addItem('RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=2SU')
|
||||
->addItem('END:DAYLIGHT');
|
||||
}
|
||||
|
||||
$this->stream->addItem('END:VTIMEZONE');
|
||||
|
||||
//add events
|
||||
/* @var $event CalendarEvent */
|
||||
foreach ($cal->getEvents() as $event)
|
||||
{
|
||||
$dtStart = $event->isAllDay() ?
|
||||
$this->formatter->getFormattedDate($event->getStart()) :
|
||||
$this->formatter->getFormattedDateTime($event->getStart());
|
||||
|
||||
$dtEnd = $event->isAllDay() ?
|
||||
$this->formatter->getFormattedDate($event->getEnd()) :
|
||||
$this->formatter->getFormattedDateTime($event->getEnd());
|
||||
|
||||
$this->stream->addItem('BEGIN:VEVENT')
|
||||
->addItem('UID:'.$event->getUid())
|
||||
->addItem('DTSTART:'. $dtStart)
|
||||
->addItem('DTEND:'. $dtEnd);
|
||||
|
||||
if ($event->getRecurrenceRule() instanceof RecurrenceRule)
|
||||
$this->stream->addItem($event->getRecurrenceRule()->__toString());
|
||||
|
||||
foreach ($event->getExceptionDates() as $date)
|
||||
{
|
||||
$this->stream->addItem('EXDATE:'.$this->formatter->getFormattedDateTime($date));
|
||||
}
|
||||
|
||||
if ($event->getSequence())
|
||||
$this->stream->addItem('SEQUENCE:'.$event->getSequence());
|
||||
|
||||
$this->stream->addItem('STATUS:'.$event->getStatus())
|
||||
->addItem('SUMMARY:'.$event->getSummary())
|
||||
->addItem('DESCRIPTION:'.$event->getDescription());
|
||||
|
||||
if ($event->getClass())
|
||||
$this->stream->addItem('CLASS:'.$event->getClass());
|
||||
|
||||
/* @var $location Location */
|
||||
foreach ($event->getLocations() as $location)
|
||||
{
|
||||
$this->stream
|
||||
->addItem('LOCATION'.$location->getUri().$location->getLanguage().':'.$location->getName());
|
||||
}
|
||||
|
||||
if ($event->getPriority() > 0 && $event->getPriority() <= 9)
|
||||
$this->stream->addItem('PRIORITY:'.$event->getPriority());
|
||||
|
||||
if ($event->getGeo())
|
||||
$this->stream->addItem('GEO:'.$event->getGeo()->getLatitude().';'.$event->getGeo()->getLongitude());
|
||||
|
||||
if ($event->getUrl())
|
||||
$this->stream->addItem('URL:'.$event->getUrl());
|
||||
|
||||
|
||||
if ($event->getTimestamp())
|
||||
{
|
||||
$this->stream->addItem('DTSTAMP:'.$this->formatter->getFormattedUTCDateTime($event->getTimestamp()));
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->stream->addItem('DTSTAMP:'.$this->formatter->getFormattedUTCDateTime(new \DateTime()));
|
||||
}
|
||||
|
||||
if ($event->getCreated())
|
||||
$this->stream->addItem('CREATED:'.$this->formatter->getFormattedUTCDateTime($event->getCreated()));
|
||||
|
||||
if ($event->getLastModified())
|
||||
$this->stream->addItem('LAST-MODIFIED:'.$this->formatter->getFormattedUTCDateTime($event->getLastModified()));
|
||||
|
||||
foreach ($event->getAttendees() as $attendee)
|
||||
{
|
||||
$this->stream->addItem($attendee->__toString());
|
||||
}
|
||||
|
||||
if ($event->getOrganizer())
|
||||
$this->stream->addItem($event->getOrganizer()->__toString());
|
||||
|
||||
/** @var CalendarAlarm $alarm */
|
||||
foreach ($event->getAlarms() as $alarm)
|
||||
{
|
||||
//basic requirements for all types of alarm
|
||||
$this->stream->addItem('BEGIN:VALARM')
|
||||
->addItem('TRIGGER;VALUE=DATE-TIME:'.$this->formatter->getFormattedUTCDateTime($alarm->getTrigger()))
|
||||
->addItem('ACTION:'.$alarm->getAction());
|
||||
|
||||
//only handle repeats if both repeat and duration are set
|
||||
if ($alarm->getRepeat() && $alarm->getDuration()) {
|
||||
$this->stream->addItem('REPEAT:'.$alarm->getRepeat())
|
||||
->addItem('DURATION:'.$this->formatter->getFormattedDateInterval($alarm->getDuration()));
|
||||
}
|
||||
|
||||
//action specific logic
|
||||
switch ($alarm->getAction())
|
||||
{
|
||||
case 'AUDIO':
|
||||
$attachments = $alarm->getAttachments();
|
||||
$this->stream->addItem('ATTACH;'.$attachments[0]);
|
||||
break;
|
||||
case 'DISPLAY':
|
||||
$this->stream->addItem('DESCRIPTION:'.$alarm->getDescription());
|
||||
break;
|
||||
case 'EMAIL':
|
||||
$this->stream->addItem('SUMMARY:'.$alarm->getSummary())
|
||||
->addItem('DESCRIPTION:'.$alarm->getDescription());
|
||||
|
||||
foreach ($alarm->getAttendees() as $attendee)
|
||||
{
|
||||
$this->stream->addItem($attendee->__toString());
|
||||
}
|
||||
foreach ($alarm->getAttachments() as $attachment)
|
||||
{
|
||||
$this->stream->addItem('ATTACH;'.$attachment);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new \Exception("Unknown ALARM action: '{$alarm->getAction()}'");
|
||||
break;
|
||||
}
|
||||
|
||||
$this->stream->addItem('END:VALARM');
|
||||
}
|
||||
|
||||
$this->stream->addItem('END:VEVENT');
|
||||
}
|
||||
|
||||
//end calendar
|
||||
$this->stream->addItem('END:VCALENDAR');
|
||||
}
|
||||
|
||||
return $this->stream->getStream();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getCalendars()
|
||||
{
|
||||
return $this->calendars;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $calendars
|
||||
* @return CalendarExport
|
||||
*/
|
||||
public function setCalendars(array $calendars)
|
||||
{
|
||||
$this->calendars = $calendars;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Calendar $cal
|
||||
* @return CalendarExport
|
||||
*/
|
||||
public function addCalendar(Calendar $cal)
|
||||
{
|
||||
$this->calendars[] = $cal;
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
<?php
|
||||
|
||||
namespace Jsvrcek\ICS;
|
||||
|
||||
use Jsvrcek\ICS\Constants;
|
||||
|
||||
class CalendarStream
|
||||
{
|
||||
//length of line in bytes
|
||||
const LINE_LENGTH = 70;
|
||||
|
||||
/**
|
||||
* echo items as they are set rather than building stream in memory, for use with streaming a large calendar
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
private $doImmediateOutput = false;
|
||||
|
||||
/**
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $stream = '';
|
||||
|
||||
|
||||
/**
|
||||
* @param boolean $doImmediateOutput
|
||||
*/
|
||||
public function setDoImmediateOutput($doImmediateOutput)
|
||||
{
|
||||
$this->doImmediateOutput = $doImmediateOutput;
|
||||
}
|
||||
|
||||
/**
|
||||
* resets stream to blank string
|
||||
*/
|
||||
public function reset()
|
||||
{
|
||||
$this->stream = '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getStream()
|
||||
{
|
||||
return $this->stream;
|
||||
}
|
||||
|
||||
/**
|
||||
* splits item into new lines if necessary
|
||||
* @param string $item
|
||||
* @return CalendarStream
|
||||
*/
|
||||
public function addItem($item)
|
||||
{
|
||||
//get number of bytes
|
||||
$length = strlen($item);
|
||||
|
||||
$block = '';
|
||||
|
||||
if ($length > 75)
|
||||
{
|
||||
$start = 0;
|
||||
|
||||
while ($start < $length)
|
||||
{
|
||||
$block .= mb_strcut($item, $start, self::LINE_LENGTH, 'UTF-8');
|
||||
$start = $start + self::LINE_LENGTH;
|
||||
|
||||
//add space if not last line
|
||||
if ($start < $length) $block .= Constants::CRLF.' ';
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$block = $item;
|
||||
}
|
||||
|
||||
$this->stream .= $block.Constants::CRLF;
|
||||
|
||||
if ($this->doImmediateOutput)
|
||||
{
|
||||
echo $this;
|
||||
$this->reset();
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
return $this->getStream();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
<?php
|
||||
namespace Jsvrcek\ICS;
|
||||
|
||||
class Constants
|
||||
{
|
||||
const CRLF = "\r\n";
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
|
||||
namespace Jsvrcek\ICS\Exception;
|
||||
|
||||
class CalendarEventException extends CalendarException
|
||||
{
|
||||
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
|
||||
namespace Jsvrcek\ICS\Exception;
|
||||
|
||||
class CalendarException extends \Exception
|
||||
{
|
||||
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
|
||||
namespace Jsvrcek\ICS\Exception;
|
||||
|
||||
class CalendarRecurrenceException extends CalendarException
|
||||
{
|
||||
|
||||
}
|
||||
+293
@@ -0,0 +1,293 @@
|
||||
<?php
|
||||
|
||||
namespace Jsvrcek\ICS\Model;
|
||||
|
||||
use Jsvrcek\ICS\Utility\Provider;
|
||||
|
||||
class Calendar
|
||||
{
|
||||
/**
|
||||
*
|
||||
* @var string $version
|
||||
*/
|
||||
private $version = '2.0';
|
||||
|
||||
/**
|
||||
*
|
||||
* @var string $prodId
|
||||
*/
|
||||
private $prodId = '';
|
||||
|
||||
/**
|
||||
*
|
||||
* @var string $calendarScale
|
||||
*/
|
||||
private $calendarScale = 'GREGORIAN';
|
||||
|
||||
/**
|
||||
*
|
||||
* @var string $method
|
||||
*/
|
||||
private $method = 'PUBLISH';
|
||||
|
||||
/**
|
||||
*
|
||||
* @var array $customHeaders
|
||||
*/
|
||||
private $customHeaders = array();
|
||||
|
||||
/**
|
||||
*
|
||||
* @var \DateTimeZone $timezone
|
||||
*/
|
||||
private $timezone;
|
||||
|
||||
/**
|
||||
*
|
||||
* @var Provider
|
||||
*/
|
||||
private $events;
|
||||
|
||||
/**
|
||||
*
|
||||
* @var Provider
|
||||
*/
|
||||
private $todos;
|
||||
|
||||
/**
|
||||
*
|
||||
* @var Provider
|
||||
*/
|
||||
private $freeBusy;
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public function __construct()
|
||||
{
|
||||
$this->timezone = new \DateTimeZone('America/New_York');
|
||||
$this->events = new Provider();
|
||||
$this->todos = new Provider();
|
||||
$this->freeBusy = new Provider();
|
||||
}
|
||||
|
||||
/**
|
||||
* For use if you want CalendarExport::getStream to get events in batches from a database during
|
||||
* the output of the ics feed, instead of adding all events to the Calendar object before outputting
|
||||
* the ics feed.
|
||||
* - CalendarExport::getStream iterates through the Calendar::$events internal data array. The $eventsProvider
|
||||
* closure will be called every time this data array reaches its end during iteration, and the closure should
|
||||
* return the next batch of events
|
||||
* - A $startKey argument with the current key of the data array will be passed to the $eventsProvider closure
|
||||
* - The $eventsProvider must return an array of CalendarEvent objects
|
||||
*
|
||||
* Example: Calendar::setEventsProvider(function($startKey){
|
||||
* //get database rows starting with $startKey
|
||||
* //return an array of CalendarEvent objects
|
||||
* })
|
||||
*
|
||||
* @param \Closure $eventsProvider
|
||||
* @return \Jsvrcek\ICS\Model\Calendar
|
||||
*/
|
||||
public function setEventsProvider(\Closure $eventsProvider)
|
||||
{
|
||||
$this->events = new Provider($eventsProvider);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getVersion()
|
||||
{
|
||||
return $this->version;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $version
|
||||
* @return \Jsvrcek\ICS\Model\Calendar
|
||||
*/
|
||||
public function setVersion($version)
|
||||
{
|
||||
$this->version = $version;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getProdId()
|
||||
{
|
||||
return $this->prodId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $prodId
|
||||
* @return \Jsvrcek\ICS\Model\Calendar
|
||||
*/
|
||||
public function setProdId($prodId)
|
||||
{
|
||||
$this->prodId = $prodId;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getCalendarScale()
|
||||
{
|
||||
return $this->calendarScale;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $calendarScale
|
||||
* @return \Jsvrcek\ICS\Model\Calendar
|
||||
*/
|
||||
public function setCalendarScale($calendarScale)
|
||||
{
|
||||
$this->calendarScale = $calendarScale;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getMethod()
|
||||
{
|
||||
return $this->method;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $method
|
||||
* @return \Jsvrcek\ICS\Model\Calendar
|
||||
*/
|
||||
public function setMethod($method)
|
||||
{
|
||||
$this->method = $method;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getCustomHeaders()
|
||||
{
|
||||
return $this->customHeaders;
|
||||
}
|
||||
|
||||
/**
|
||||
* use to add custom headers as array key-value pairs<br>
|
||||
* <strong>Example:</strong> $customHeaders = array('X-WR-TIMEZONE' => 'America/New_York')
|
||||
*
|
||||
* @param array $customHeaders
|
||||
* @return \Jsvrcek\ICS\Model\Calendar
|
||||
*/
|
||||
public function setCustomHeaders(array $customHeaders)
|
||||
{
|
||||
$this->customHeaders = $customHeaders;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $key
|
||||
* @param string $value
|
||||
* @return \Jsvrcek\ICS\Model\Calendar
|
||||
*/
|
||||
public function addCustomHeader($key, $value)
|
||||
{
|
||||
$this->customHeaders[$key] = $value;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \DateTimeZone
|
||||
*/
|
||||
public function getTimezone()
|
||||
{
|
||||
return $this->timezone;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \DateTimeZone $timezone
|
||||
* @return \Jsvrcek\ICS\Model\Calendar
|
||||
*/
|
||||
public function setTimezone(\DateTimeZone $timezone)
|
||||
{
|
||||
$this->timezone = $timezone;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Provider
|
||||
*/
|
||||
public function getEvents()
|
||||
{
|
||||
return $this->events;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param CalendarEvent $event
|
||||
* @return \Jsvrcek\ICS\Model\Calendar
|
||||
*/
|
||||
public function addEvent(CalendarEvent $event)
|
||||
{
|
||||
$this->events->add($event);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array $todos returs array of CalendarTodo objects
|
||||
*/
|
||||
public function getTodos()
|
||||
{
|
||||
return $this->todos;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param CalendarTodo $todo
|
||||
* @return \Jsvrcek\ICS\Model\Calendar
|
||||
*/
|
||||
public function addTodo(CalendarTodo $todo)
|
||||
{
|
||||
$this->todos[] = $todo;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $todos
|
||||
* @return \Jsvrcek\ICS\Model\Calendar
|
||||
*/
|
||||
public function setTodos(array $todos)
|
||||
{
|
||||
$this->todos = $todos;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array $freeBusy returs array of CalendarFreeBusy objects
|
||||
*/
|
||||
public function getFreeBusy()
|
||||
{
|
||||
return $this->freeBusy;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param CalendarFreeBusy $todo
|
||||
* @return \Jsvrcek\ICS\Model\Calendar
|
||||
*/
|
||||
public function addFreeBusy(CalendarFreeBusy $todo)
|
||||
{
|
||||
$this->freeBusy[] = $todo;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $freeBusy
|
||||
* @return \Jsvrcek\ICS\Model\Calendar
|
||||
*/
|
||||
public function setFreeBusy(array $freeBusy)
|
||||
{
|
||||
$this->freeBusy = $freeBusy;
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,246 @@
|
||||
<?php
|
||||
|
||||
namespace Jsvrcek\ICS\Model;
|
||||
|
||||
use Jsvrcek\ICS\Model\Relationship\Attendee;
|
||||
use Jsvrcek\ICS\Utility\Formatter;
|
||||
|
||||
/**
|
||||
* See http://icalendar.org/iCalendar-RFC-5545/3-6-6-alarm-component.html
|
||||
*
|
||||
* Class CalendarAlarm
|
||||
* @package Jsvrcek\ICS\Model
|
||||
*/
|
||||
class CalendarAlarm
|
||||
{
|
||||
/**
|
||||
*
|
||||
* @var string $action
|
||||
*/
|
||||
private $action;
|
||||
|
||||
/**
|
||||
* RFC 5545 supports triggers relative to the parent VEVENT or VTODO, but Jsvrcek\ICS does not.
|
||||
* Only absolute trigger times are supported.
|
||||
* @todo Support RELATED, DTSTART, and DTEND.
|
||||
*
|
||||
* @var \DateTime $trigger
|
||||
*/
|
||||
private $trigger;
|
||||
|
||||
/**
|
||||
* For AUDIO and EMAIL actions only.
|
||||
* For AUDIO there must be exactly one attachment, which must point to a sound resource.
|
||||
* For EMAIL there can be any number of attachments, including zero.
|
||||
*
|
||||
* Should be a string including a path and a file type, like so:
|
||||
*
|
||||
* "FMTTYPE=application/msword:http://example.com/agenda.doc"
|
||||
*
|
||||
* @var array $attachments
|
||||
*/
|
||||
private $attachments = array();
|
||||
|
||||
/**
|
||||
* For DISPLAY and EMAIL actions only. For EMAIL this is the body.
|
||||
*
|
||||
* @var string $description
|
||||
*/
|
||||
private $description;
|
||||
|
||||
/**
|
||||
* For EMAIL action only. This is the email subject.
|
||||
*
|
||||
* @var string $summary
|
||||
*/
|
||||
private $summary;
|
||||
|
||||
/**
|
||||
* For EMAIL action only. This is the email recipients.
|
||||
*
|
||||
* @var array $attendees
|
||||
*/
|
||||
private $attendees = array();
|
||||
|
||||
/**
|
||||
* For all actions. The number of times to repeat the alarm.
|
||||
* If REPEAT is set then DURATION must also be set.
|
||||
*
|
||||
* @var integer $repeat
|
||||
*/
|
||||
private $repeat;
|
||||
|
||||
/**
|
||||
* For all actions. The duration of the alarm.
|
||||
* If DURATION is set then REPEAT must also be set.
|
||||
*
|
||||
* @var \DateInterval $duration
|
||||
*/
|
||||
private $duration;
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*
|
||||
*/
|
||||
public function getAction()
|
||||
{
|
||||
return $this->action;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $action
|
||||
* @return \Jsvrcek\ICS\Model\CalendarAlarm
|
||||
*/
|
||||
public function setAction($action)
|
||||
{
|
||||
$action = strtoupper($action);
|
||||
$this->action = $action;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \DateTime
|
||||
*/
|
||||
public function getTrigger()
|
||||
{
|
||||
return $this->trigger;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \DateTime $trigger
|
||||
* @return \Jsvrcek\ICS\Model\CalendarAlarm
|
||||
*/
|
||||
public function setTrigger($trigger)
|
||||
{
|
||||
$this->trigger = $trigger;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getAttachments()
|
||||
{
|
||||
return $this->attachments;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $attachments
|
||||
* @return \Jsvrcek\ICS\Model\CalendarAlarm
|
||||
*/
|
||||
public function setAttachments($attachments)
|
||||
{
|
||||
$this->attachments = $attachments;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $attachment
|
||||
* @return \Jsvrcek\ICS\Model\CalendarAlarm
|
||||
*/
|
||||
public function addAttachment($attachment)
|
||||
{
|
||||
$this->attachments[] = $attachment;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getDescription()
|
||||
{
|
||||
return $this->description;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $description
|
||||
* @return \Jsvrcek\ICS\Model\CalendarAlarm
|
||||
*/
|
||||
public function setDescription($description)
|
||||
{
|
||||
$this->description = $description;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getSummary()
|
||||
{
|
||||
return $this->summary;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $summary
|
||||
* @return \Jsvrcek\ICS\Model\CalendarAlarm
|
||||
*/
|
||||
public function setSummary($summary)
|
||||
{
|
||||
$this->summary = $summary;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array $attendees array of Attendee objects
|
||||
*/
|
||||
public function getAttendees()
|
||||
{
|
||||
return $this->attendees;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $attendees array of Attendee objects
|
||||
* @return \Jsvrcek\ICS\Model\CalendarAlarm
|
||||
*/
|
||||
public function setAttendees(array $attendees)
|
||||
{
|
||||
$this->attendees = $attendees;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Attendee $attendee
|
||||
* @return \Jsvrcek\ICS\Model\CalendarAlarm
|
||||
*/
|
||||
public function addAttendee(Attendee $attendee)
|
||||
{
|
||||
$this->attendees[] = $attendee;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getRepeat()
|
||||
{
|
||||
return $this->repeat;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $repeat
|
||||
* @return \Jsvrcek\ICS\Model\CalendarAlarm
|
||||
*/
|
||||
public function setRepeat($repeat)
|
||||
{
|
||||
$this->repeat = $repeat;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \DateInterval
|
||||
*/
|
||||
public function getDuration()
|
||||
{
|
||||
return $this->duration;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \DateInterval $duration
|
||||
* @return \Jsvrcek\ICS\Model\CalendarAlarm
|
||||
*/
|
||||
public function setDuration($duration)
|
||||
{
|
||||
$this->duration = $duration;
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
+620
@@ -0,0 +1,620 @@
|
||||
<?php
|
||||
|
||||
namespace Jsvrcek\ICS\Model;
|
||||
|
||||
use Jsvrcek\ICS\Model\Recurrence\RecurrenceRule;
|
||||
use Jsvrcek\ICS\Model\Description\Geo;
|
||||
use Jsvrcek\ICS\Model\Description\Location;
|
||||
use Jsvrcek\ICS\Model\Relationship\Organizer;
|
||||
use Jsvrcek\ICS\Model\Relationship\Attendee;
|
||||
use Jsvrcek\ICS\Model\CalendarAlarm;
|
||||
use Jsvrcek\ICS\Exception\CalendarEventException;
|
||||
|
||||
/**
|
||||
* @author justinsvrcek
|
||||
* http://tools.ietf.org/html/rfc5545#page-52
|
||||
*/
|
||||
class CalendarEvent
|
||||
{
|
||||
/**
|
||||
*
|
||||
* @var string $uid
|
||||
*/
|
||||
private $uid;
|
||||
|
||||
/**
|
||||
*
|
||||
* @var \DateTime $start
|
||||
*/
|
||||
private $start;
|
||||
|
||||
/**
|
||||
*
|
||||
* @var \DateTime $end
|
||||
*/
|
||||
private $end;
|
||||
|
||||
/**
|
||||
*
|
||||
* @var RecurrenceRule
|
||||
*/
|
||||
private $recurrenceRule;
|
||||
|
||||
/**
|
||||
* array of dates to skip
|
||||
* https://tools.ietf.org/html/rfc5545#page-120
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $exceptionDates = array();
|
||||
|
||||
/**
|
||||
* @var string $class
|
||||
*/
|
||||
private $class;
|
||||
|
||||
/**
|
||||
* @var \DateTime $created
|
||||
*/
|
||||
private $created;
|
||||
|
||||
/**
|
||||
*
|
||||
* @var string $description
|
||||
*/
|
||||
private $description;
|
||||
|
||||
/**
|
||||
* @var Geo $geo
|
||||
*/
|
||||
private $geo;
|
||||
|
||||
/**
|
||||
* @var string $lastModified
|
||||
*/
|
||||
private $lastModified;
|
||||
|
||||
/**
|
||||
* @var array $locations
|
||||
*/
|
||||
private $locations = array();
|
||||
|
||||
/**
|
||||
*
|
||||
* @var Organizer $organizer
|
||||
*/
|
||||
private $organizer;
|
||||
|
||||
/**
|
||||
*
|
||||
* @var string $priority
|
||||
*/
|
||||
private $priority;
|
||||
|
||||
/**
|
||||
*
|
||||
* @var \DateTime $timestamp
|
||||
*/
|
||||
private $timestamp;
|
||||
|
||||
/**
|
||||
*
|
||||
* @var string $status
|
||||
*/
|
||||
private $status;
|
||||
|
||||
/**
|
||||
*
|
||||
* @var string $summary
|
||||
*/
|
||||
private $summary;
|
||||
|
||||
/**
|
||||
* @todo add support in CalendarExport
|
||||
* @var string $recuringId
|
||||
*/
|
||||
private $recuringId;
|
||||
|
||||
/**
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
private $sequence;
|
||||
|
||||
/**
|
||||
*
|
||||
* @var array $attendees
|
||||
*/
|
||||
private $attendees = array();
|
||||
|
||||
/**
|
||||
*
|
||||
* @var array $alarms
|
||||
*/
|
||||
private $alarms = array();
|
||||
|
||||
/**
|
||||
* @var string $url
|
||||
*/
|
||||
private $url;
|
||||
|
||||
/**
|
||||
* @var boolean
|
||||
*/
|
||||
private $allDay = false;
|
||||
|
||||
/**
|
||||
* @return boolean
|
||||
*/
|
||||
public function isAllDay()
|
||||
{
|
||||
return $this->allDay;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param boolean $allDay
|
||||
* @return \Jsvrcek\ICS\Model\CalendarEvent
|
||||
*/
|
||||
public function setAllDay($allDay)
|
||||
{
|
||||
$this->allDay = $allDay;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getUid()
|
||||
{
|
||||
return $this->uid;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $uid
|
||||
* @return \Jsvrcek\ICS\Model\CalendarEvent
|
||||
*/
|
||||
public function setUid($uid)
|
||||
{
|
||||
$this->uid = $uid;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \DateTime
|
||||
*/
|
||||
public function getStart()
|
||||
{
|
||||
return $this->start;
|
||||
}
|
||||
|
||||
/**
|
||||
* also sets end time to 30 minutes after start as default<br>
|
||||
* - end time can be overridden with setEnd()
|
||||
*
|
||||
* @param \DateTime $start
|
||||
* @return \Jsvrcek\ICS\Model\CalendarEvent
|
||||
*/
|
||||
public function setStart(\DateTime $start)
|
||||
{
|
||||
$this->start = $start;
|
||||
$end = clone $start;
|
||||
$this->setEnd($end->add(\DateInterval::createFromDateString('30 minutes')));
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \DateTime
|
||||
*/
|
||||
public function getEnd()
|
||||
{
|
||||
return $this->end;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \DateTime $end
|
||||
* @return \Jsvrcek\ICS\Model\CalendarEvent
|
||||
*/
|
||||
public function setEnd(\DateTime $end)
|
||||
{
|
||||
//check End is greater than Start
|
||||
if ($this->getStart() instanceof \DateTime)
|
||||
{
|
||||
if ($this->getStart() > $end)
|
||||
throw new CalendarEventException('End DateTime must be greater than Start DateTime');
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new CalendarEventException('You must set the Start time before setting the End Time of a CalendarEvent');
|
||||
}
|
||||
|
||||
$this->end = $end;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Jsvrcek\ICS\Model\Recurrence\RecurrenceRule
|
||||
*/
|
||||
public function getRecurrenceRule()
|
||||
{
|
||||
return $this->recurrenceRule;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param RecurrenceRule $recurrenceRule
|
||||
* @return \Jsvrcek\ICS\Model\CalendarEvent
|
||||
*/
|
||||
public function setRecurrenceRule(RecurrenceRule $recurrenceRule)
|
||||
{
|
||||
$this->recurrenceRule = $recurrenceRule;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* array of DateTime instances
|
||||
* @param array $dates
|
||||
*/
|
||||
public function setExceptionDates(array $dates)
|
||||
{
|
||||
$this->exceptionDates = $dates;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getExceptionDates()
|
||||
{
|
||||
return $this->exceptionDates;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \DateTime $date
|
||||
* @return \Jsvrcek\ICS\Model\CalendarEvent
|
||||
*/
|
||||
public function addExceptionDate(\DateTime $date)
|
||||
{
|
||||
$this->exceptionDates[] = $date;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the string
|
||||
*/
|
||||
public function getSummary()
|
||||
{
|
||||
return $this->summary;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $summary
|
||||
* @return \Jsvrcek\ICS\Model\CalendarEvent
|
||||
*/
|
||||
public function setSummary($summary)
|
||||
{
|
||||
$this->summary = $summary;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the string
|
||||
*/
|
||||
public function getDescription()
|
||||
{
|
||||
return $this->description;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $description
|
||||
* @return \Jsvrcek\ICS\Model\CalendarEvent
|
||||
*/
|
||||
public function setDescription($description)
|
||||
{
|
||||
$this->description = $description;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array $alarms returs array of CalendarAlarm objects
|
||||
*/
|
||||
public function getAlarms()
|
||||
{
|
||||
return $this->alarms;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param CalendarAlarm $alarm
|
||||
* @return \Jsvrcek\ICS\Model\CalendarEvent
|
||||
*/
|
||||
public function addAlarm(CalendarAlarm $alarm)
|
||||
{
|
||||
$this->alarms[] = $alarm;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $alarms
|
||||
* @return \Jsvrcek\ICS\Model\CalendarEvent
|
||||
*/
|
||||
public function setAlarms(array $alarms)
|
||||
{
|
||||
$this->alarms = $alarms;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getClass()
|
||||
{
|
||||
return $this->class;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param string $class
|
||||
* @return \Jsvrcek\ICS\Model\CalendarEvent
|
||||
*/
|
||||
public function setClass($class)
|
||||
{
|
||||
$this->class = $class;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return \DateTime
|
||||
*/
|
||||
public function getCreated()
|
||||
{
|
||||
return $this->created;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param \DateTime $created
|
||||
* @return \Jsvrcek\ICS\Model\CalendarEvent
|
||||
*/
|
||||
public function setCreated(\DateTime $created)
|
||||
{
|
||||
$this->created = $created;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return Geo|null
|
||||
*/
|
||||
public function getGeo()
|
||||
{
|
||||
return $this->geo;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param Geo $geo
|
||||
* @return \Jsvrcek\ICS\Model\CalendarEvent
|
||||
*/
|
||||
public function setGeo(Geo $geo)
|
||||
{
|
||||
$this->geo = $geo;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return \DateTime
|
||||
*/
|
||||
public function getLastModified()
|
||||
{
|
||||
return $this->lastModified;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param \DateTime $lastModified
|
||||
* @return \Jsvrcek\ICS\Model\CalendarEvent
|
||||
*/
|
||||
public function setLastModified(\DateTime $lastModified)
|
||||
{
|
||||
$this->lastModified = $lastModified;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return array $locations array of Location objects
|
||||
*/
|
||||
public function getLocations()
|
||||
{
|
||||
return $this->locations;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param array $locations array of Location objects
|
||||
* @return \Jsvrcek\ICS\Model\CalendarEvent
|
||||
*/
|
||||
public function setLocations(array $locations)
|
||||
{
|
||||
$this->locations = $locations;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param Location $location
|
||||
* @return \Jsvrcek\ICS\Model\CalendarEvent
|
||||
*/
|
||||
public function addLocation(Location $location)
|
||||
{
|
||||
$this->locations[] = $location;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return Organizer
|
||||
*/
|
||||
public function getOrganizer()
|
||||
{
|
||||
return $this->organizer;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param Organizer $organizer
|
||||
* @return \Jsvrcek\ICS\Model\CalendarEvent
|
||||
*/
|
||||
public function setOrganizer(Organizer $organizer)
|
||||
{
|
||||
$this->organizer = $organizer;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getPriority()
|
||||
{
|
||||
return $this->priority;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param string $priority
|
||||
* @return \Jsvrcek\ICS\Model\CalendarEvent
|
||||
*/
|
||||
public function setPriority($priority)
|
||||
{
|
||||
$this->priority = $priority;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return \DateTime
|
||||
*/
|
||||
public function getTimestamp()
|
||||
{
|
||||
return $this->timestamp;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param \DateTime $timestamp
|
||||
* @return \Jsvrcek\ICS\Model\CalendarEvent
|
||||
*/
|
||||
public function setTimestamp(\DateTime $timestamp)
|
||||
{
|
||||
$this->timestamp = $timestamp;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getStatus()
|
||||
{
|
||||
return $this->status;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param string $status
|
||||
* @return \Jsvrcek\ICS\Model\CalendarEvent
|
||||
*/
|
||||
public function setStatus($status)
|
||||
{
|
||||
$this->status = $status;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getRecuringId()
|
||||
{
|
||||
return $this->recuringId;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param string $recuringId
|
||||
* @return \Jsvrcek\ICS\Model\CalendarEvent
|
||||
*/
|
||||
public function setRecuringId($recuringId)
|
||||
{
|
||||
$this->recuringId = $recuringId;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return integer
|
||||
*/
|
||||
public function getSequence()
|
||||
{
|
||||
return $this->sequence;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param integer $sequence
|
||||
* @return \Jsvrcek\ICS\Model\CalendarEvent
|
||||
*/
|
||||
public function setSequence($sequence)
|
||||
{
|
||||
$this->sequence = $sequence;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return array $attendees array of Attendee objects
|
||||
*/
|
||||
public function getAttendees()
|
||||
{
|
||||
return $this->attendees;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param array $attendees array of Attendee objects
|
||||
* @return \Jsvrcek\ICS\Model\CalendarEvent
|
||||
*/
|
||||
public function setAttendees(array $attendees)
|
||||
{
|
||||
$this->attendees = $attendees;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Attendee $attendee
|
||||
* @return \Jsvrcek\ICS\Model\CalendarEvent
|
||||
*/
|
||||
public function addAttendee(Attendee $attendee)
|
||||
{
|
||||
$this->attendees[] = $attendee;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $url
|
||||
* @return \Jsvrcek\ICS\Model\CalendarEvent
|
||||
*/
|
||||
public function setUrl($url)
|
||||
{
|
||||
$this->url = $url;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getUrl()
|
||||
{
|
||||
return $this->url;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
|
||||
namespace Jsvrcek\ICS\Model;
|
||||
|
||||
class CalendarFreeBusy
|
||||
{
|
||||
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
|
||||
namespace Jsvrcek\ICS\Model;
|
||||
|
||||
class CalendarTodo
|
||||
{
|
||||
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
<?php
|
||||
|
||||
namespace Jsvrcek\ICS\Model\Description;
|
||||
class Geo
|
||||
{
|
||||
/**
|
||||
* @var float $latitude
|
||||
*/
|
||||
private $latitude;
|
||||
|
||||
/**
|
||||
*
|
||||
* @var float $longitude
|
||||
*/
|
||||
private $longitude;
|
||||
|
||||
/**
|
||||
* @return number
|
||||
*/
|
||||
public function getLatitude()
|
||||
{
|
||||
return $this->latitude;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param float $latitude
|
||||
* @return \Jsvrcek\ICS\Model\Description\Geo
|
||||
*/
|
||||
public function setLatitude($latitude)
|
||||
{
|
||||
$this->latitude = $latitude;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return number
|
||||
*/
|
||||
public function getLongitude()
|
||||
{
|
||||
return $this->longitude;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param float $longitude
|
||||
* @return \Jsvrcek\ICS\Model\Description\Geo
|
||||
*/
|
||||
public function setLongitude($longitude)
|
||||
{
|
||||
$this->longitude = $longitude;
|
||||
return $this;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
<?php
|
||||
|
||||
namespace Jsvrcek\ICS\Model\Description;
|
||||
class Location
|
||||
{
|
||||
/**
|
||||
*
|
||||
* @var string $name
|
||||
*/
|
||||
private $name;
|
||||
|
||||
/**
|
||||
*
|
||||
* @var string $uri
|
||||
*/
|
||||
private $uri;
|
||||
|
||||
/**
|
||||
*
|
||||
* @var string $language
|
||||
*/
|
||||
private $language;
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @return \Jsvrcek\ICS\Model\Description\Location
|
||||
*/
|
||||
public function setName($name)
|
||||
{
|
||||
$this->name = $name;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getUri()
|
||||
{
|
||||
return $this->uri;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $uri uri to vCard or other uri
|
||||
* @return \Jsvrcek\ICS\Model\Description\Location
|
||||
*/
|
||||
public function setUri($uri)
|
||||
{
|
||||
$this->uri = ';ALTREP="' . $uri . '"';
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getLanguage()
|
||||
{
|
||||
return $this->language;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $language RFC 1766 language identifier
|
||||
* @return \Jsvrcek\ICS\Model\Description\Location
|
||||
*/
|
||||
public function setLanguage($language)
|
||||
{
|
||||
$this->language = ';LANGUAGE='.$language;
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
<?php
|
||||
|
||||
namespace Jsvrcek\ICS\Model\Recurrence\DataType;
|
||||
|
||||
use Jsvrcek\ICS\Exception\CalendarRecurrenceException;
|
||||
|
||||
/**
|
||||
* @author justinsvrcek
|
||||
* http://tools.ietf.org/html/rfc5545#page-38
|
||||
*/
|
||||
class Frequency
|
||||
{
|
||||
const KEY = 'FREQ';
|
||||
|
||||
const SECONDLY = 1;
|
||||
const MINUTELY = 2;
|
||||
const HOURLY = 3;
|
||||
const DAILY = 4;
|
||||
const WEEKLY = 5;
|
||||
const MONTHLY = 6;
|
||||
const YEARLY = 7;
|
||||
|
||||
/**
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
private $freq;
|
||||
|
||||
public static $values = array(
|
||||
self::SECONDLY => 'SECONDLY',
|
||||
self::MINUTELY => 'MINUTELY',
|
||||
self::HOURLY => 'HOURLY',
|
||||
self::DAILY => 'DAILY',
|
||||
self::WEEKLY => 'WEEKLY',
|
||||
self::MONTHLY => 'MONTHLY',
|
||||
self::YEARLY => 'YEARLY'
|
||||
);
|
||||
|
||||
/**
|
||||
* @param integer $frequency Frequency::SECONDLY, Frequency::MINUTELY,
|
||||
* Frequency::HOURLY, Frequency::DAILY, Frequency::WEEKLY,
|
||||
* Frequency::MONTHLY, Frequency::YEARLY
|
||||
*/
|
||||
public function __construct($frequency)
|
||||
{
|
||||
$this->validateFrequency($frequency);
|
||||
|
||||
$this->freq = $frequency;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return number
|
||||
*/
|
||||
public function getFreq()
|
||||
{
|
||||
return $this->freq;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param integer $freq
|
||||
* @return \Jsvrcek\ICS\Model\Recurrence\DataType\Frequency
|
||||
*/
|
||||
public function setFreq($freq)
|
||||
{
|
||||
$this->validateFrequency($freq);
|
||||
|
||||
$this->freq = $freq;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param integer $frequency
|
||||
* @throws CalendarRecurrenceException
|
||||
*/
|
||||
private function validateFrequency($frequency)
|
||||
{
|
||||
if (!is_int($frequency) || $frequency < 1 || $frequency > 7)
|
||||
{
|
||||
throw new CalendarRecurrenceException('You must pass a Frequency constant to the contructor.');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
return self::KEY.'='.self::$values[$this->freq];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
<?php
|
||||
|
||||
namespace Jsvrcek\ICS\Model\Recurrence\DataType;
|
||||
|
||||
use Jsvrcek\ICS\Exception\CalendarRecurrenceException;
|
||||
|
||||
/**
|
||||
* @author justinsvrcek
|
||||
* http://tools.ietf.org/html/rfc5545#page-38
|
||||
*/
|
||||
class Weekday
|
||||
{
|
||||
const SUNDAY = 1;
|
||||
const MONDAY = 2;
|
||||
const TUESDAY = 3;
|
||||
const WEDNESDAY = 4;
|
||||
const THURSDAY = 5;
|
||||
const FRIDAY = 6;
|
||||
const SATURDAY = 7;
|
||||
|
||||
/**
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
private $weekday;
|
||||
|
||||
/**
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $values = array(
|
||||
self::SUNDAY => 'SU',
|
||||
self::MONDAY => 'MO',
|
||||
self::TUESDAY => 'TU',
|
||||
self::WEDNESDAY => 'WE',
|
||||
self::THURSDAY => 'TH',
|
||||
self::FRIDAY => 'FR',
|
||||
self::SATURDAY => 'SA'
|
||||
);
|
||||
|
||||
/**
|
||||
* @param integer $weekday Weekday::SUNDAY, Weekday::MONDAY,
|
||||
* Weekday::TUESDAY, Weekday::WEDNESDAY, Weekday::THURSDAY,
|
||||
* Weekday::FRIDAY, Weekday::SATURDAY
|
||||
*/
|
||||
public function __construct($weekday)
|
||||
{
|
||||
$this->validateWeekday($weekday);
|
||||
|
||||
$this->weekday = $weekday;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return number
|
||||
*/
|
||||
public function getWeekday()
|
||||
{
|
||||
return $this->weekday;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param integer $weekday
|
||||
* @return \Jsvrcek\ICS\Model\Recurrence\DataType\Weekday
|
||||
*/
|
||||
public function setWeekday($weekday)
|
||||
{
|
||||
$this->validateWeekday($weekday);
|
||||
|
||||
$this->weekday = $weekday;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param integer $weekday
|
||||
* @throws CalendarRecurrenceException
|
||||
*/
|
||||
private function validateWeekday($weekday)
|
||||
{
|
||||
if (!is_int($weekday) || $weekday < 1 || $weekday > 7)
|
||||
{
|
||||
throw new CalendarRecurrenceException('You must pass a Weekday constant to the contructor.');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
return $this->values[$this->weekday];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
<?php
|
||||
|
||||
namespace Jsvrcek\ICS\Model\Recurrence\DataType;
|
||||
|
||||
use Jsvrcek\ICS\Exception\CalendarRecurrenceException;
|
||||
|
||||
/**
|
||||
* @author justinsvrcek
|
||||
* http://tools.ietf.org/html/rfc5545#page-38
|
||||
*/
|
||||
class WeekdayNum extends Weekday
|
||||
{
|
||||
const COUNT_FROM_START = null;
|
||||
const COUNT_FROM_END = '-';
|
||||
|
||||
/**
|
||||
*
|
||||
* @var integer 1-53
|
||||
*/
|
||||
private $weekdaynum;
|
||||
|
||||
/**
|
||||
*
|
||||
* @var mixed
|
||||
*/
|
||||
private $countFromStartOrEnd;
|
||||
|
||||
/**
|
||||
* WeekdayNum(Weekday::MONDAY, 2, WeekdayNum:COUNT_FROM_END) will convert to the
|
||||
* string "-2MO", or "second from last Monday"
|
||||
*
|
||||
* @param integer $weekday
|
||||
* @param integer $weekdaynum
|
||||
* @param string $countFromStartOrEnd
|
||||
*/
|
||||
public function __construct($weekday, $weekdaynum = null, $countFromStartOrEnd = null)
|
||||
{
|
||||
parent::__construct($weekday);
|
||||
|
||||
$this->validateWeekdayNum($weekdaynum);
|
||||
$this->validateCountFromStartOrEnd($countFromStartOrEnd);
|
||||
|
||||
$this->weekdaynum = $weekdaynum;
|
||||
$this->countFromStartOrEnd = $countFromStartOrEnd;
|
||||
}
|
||||
|
||||
/* (non-PHPdoc)
|
||||
* @see Jsvrcek\ICS\Model\Recurrence\DataType.Weekday::__toString()
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
return $this->countFromStartOrEnd.$this->weekdaynum.parent::__toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $countFromStartOrEnd
|
||||
* @throws CalendarRecurrenceException
|
||||
*/
|
||||
private function validateCountFromStartOrEnd($countFromStartOrEnd)
|
||||
{
|
||||
if ($countFromStartOrEnd !== self::COUNT_FROM_START && $countFromStartOrEnd !== self::COUNT_FROM_END)
|
||||
{
|
||||
throw new CalendarRecurrenceException('You must use WeekdayNum::COUNT_FROM_START or WeekdayNum::COUNT_FROM_END');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param integer $weekdaynum
|
||||
* @throws CalendarRecurrenceException
|
||||
*/
|
||||
private function validateWeekdayNum($weekdaynum)
|
||||
{
|
||||
if (!is_int($weekdaynum) || $weekdaynum < 1 || $weekdaynum > 53)
|
||||
{
|
||||
throw new CalendarRecurrenceException('$weekdaynum must be an integer between 1 and 53');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,536 @@
|
||||
<?php
|
||||
|
||||
namespace Jsvrcek\ICS\Model\Recurrence;
|
||||
|
||||
|
||||
use Jsvrcek\ICS\Utility\Formatter;
|
||||
|
||||
use Jsvrcek\ICS\Model\Recurrence\DataType\Frequency;
|
||||
use Jsvrcek\ICS\Model\Recurrence\DataType\Weekday;
|
||||
use Jsvrcek\ICS\Model\Recurrence\DataType\WeekdayNum;
|
||||
use Jsvrcek\ICS\Exception\CalendarRecurrenceException;
|
||||
|
||||
/**
|
||||
* @todo BYSECOND, BYMINUTE, BYHOUR, BYMONTHDAY, BYYEARDAY, BYWEEKNO, BYMONTH, BYSETPOS, and WKST
|
||||
* are not implemented in the __toString function yet
|
||||
*
|
||||
* @author justinsvrcek
|
||||
* http://tools.ietf.org/html/rfc5545#page-37
|
||||
*/
|
||||
class RecurrenceRule
|
||||
{
|
||||
const KEY = 'RRULE:';
|
||||
|
||||
/**
|
||||
*
|
||||
* @var Frequency
|
||||
*/
|
||||
private $frequency;
|
||||
|
||||
/**
|
||||
*
|
||||
* @var \DateTime
|
||||
*/
|
||||
private $until;
|
||||
|
||||
/**
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
private $count;
|
||||
|
||||
/**
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
private $interval;
|
||||
|
||||
/**
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $bySecondList = array();
|
||||
|
||||
/**
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $byMinuteList = array();
|
||||
|
||||
/**
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $byHourList = array();
|
||||
|
||||
/**
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $byDayList = array();
|
||||
|
||||
/**
|
||||
* @todo need to add to RecurrenceRule::__toString()
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $byMonthDayList = array();
|
||||
|
||||
/**
|
||||
* @todo need to add to RecurrenceRule::__toString()
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $byYearDayList = array();
|
||||
|
||||
/**
|
||||
* @todo need to add to RecurrenceRule::__toString()
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $byWeekNumberList = array();
|
||||
|
||||
/**
|
||||
* @todo need to add to RecurrenceRule::__toString()
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $byMonthList = array();
|
||||
|
||||
/**
|
||||
* @todo need to add to RecurrenceRule::__toString()
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $bySetPosYearDayList = array();
|
||||
|
||||
/**
|
||||
* @todo need to add to RecurrenceRule::__toString()
|
||||
*
|
||||
* @var Weekday
|
||||
*/
|
||||
private $weekStart;
|
||||
|
||||
/**
|
||||
*
|
||||
* @var Formatter
|
||||
*/
|
||||
private $formatter;
|
||||
|
||||
/**
|
||||
* @param Formatter $formatter
|
||||
*/
|
||||
public function __construct(Formatter $formatter)
|
||||
{
|
||||
$this->formatter = $formatter;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return \Jsvrcek\ICS\Model\Recurrence\Frequency
|
||||
*/
|
||||
public function getFrequency()
|
||||
{
|
||||
return $this->frequency;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Frequency $frequency
|
||||
* @return \Jsvrcek\ICS\Model\Recurrence\RecurrenceRule
|
||||
*/
|
||||
public function setFrequency(Frequency $frequency)
|
||||
{
|
||||
$this->frequency = $frequency;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return \DateTime
|
||||
*/
|
||||
public function getUntil()
|
||||
{
|
||||
return $this->until;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param \DateTime $until = null
|
||||
* @return \Jsvrcek\ICS\Model\Recurrence\RecurrenceRule
|
||||
*/
|
||||
public function setUntil(\DateTime $until = null)
|
||||
{
|
||||
$this->until = $until;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function getCount()
|
||||
{
|
||||
return $this->count;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param integer $count
|
||||
* @return \Jsvrcek\ICS\Model\Recurrence\RecurrenceRule
|
||||
*/
|
||||
public function setCount($count)
|
||||
{
|
||||
$this->validateInteger($count);
|
||||
|
||||
$this->count = $count;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return integer
|
||||
*/
|
||||
public function getInterval()
|
||||
{
|
||||
return $this->interval;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param integer $interval
|
||||
* @return \Jsvrcek\ICS\Model\Recurrence\RecurrenceRule
|
||||
*/
|
||||
public function setInterval($interval)
|
||||
{
|
||||
$this->validateInteger($interval);
|
||||
|
||||
$this->interval = $interval;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getBySecondList()
|
||||
{
|
||||
return $this->bySecondList;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $bySecondList
|
||||
* @return \Jsvrcek\ICS\Model\Recurrence\RecurrenceRule
|
||||
*/
|
||||
public function setBySecondList(array $bySecondList)
|
||||
{
|
||||
$this->bySecondList = $bySecondList;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param integer $integer 0-60
|
||||
* @return \Jsvrcek\ICS\Model\Recurrence\RecurrenceRule
|
||||
*/
|
||||
public function addBySecond($integer)
|
||||
{
|
||||
$this->validateInteger($integer);
|
||||
|
||||
$this->bySecondList[] = $integer;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getByMinuteList()
|
||||
{
|
||||
return $this->byMinuteList;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $byMinuteList
|
||||
* @return \Jsvrcek\ICS\Model\Recurrence\RecurrenceRule
|
||||
*/
|
||||
public function setByMinuteList(array $byMinuteList)
|
||||
{
|
||||
$this->byMinuteList = $byMinuteList;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param integer $integer 0-59
|
||||
* @return \Jsvrcek\ICS\Model\Recurrence\RecurrenceRule
|
||||
*/
|
||||
public function addByMinute($integer)
|
||||
{
|
||||
$this->validateInteger($integer);
|
||||
|
||||
$this->byMinuteList[] = $integer;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getByHourList()
|
||||
{
|
||||
return $this->byHourList;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $byHourList
|
||||
* @return \Jsvrcek\ICS\Model\Recurrence\RecurrenceRule
|
||||
*/
|
||||
public function setByHourList(array $byHourList)
|
||||
{
|
||||
$this->byHourList = $byHourList;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param integer $integer 0-23
|
||||
* @return \Jsvrcek\ICS\Model\Recurrence\RecurrenceRule
|
||||
*/
|
||||
public function addByHour($integer)
|
||||
{
|
||||
$this->validateInteger($integer);
|
||||
|
||||
$this->byHourList[] = $integer;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getByDayList()
|
||||
{
|
||||
return $this->byDayList;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $byDayList
|
||||
* @return \Jsvrcek\ICS\Model\Recurrence\RecurrenceRule
|
||||
*/
|
||||
public function setByDayList(array $byDayList)
|
||||
{
|
||||
$this->byDayList = $byDayList;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param WeekdayNum $weekdaynum
|
||||
* @return \Jsvrcek\ICS\Model\Recurrence\RecurrenceRule
|
||||
*/
|
||||
public function addByDay(WeekdayNum $weekdaynum)
|
||||
{
|
||||
$this->byDayList[] = $weekdaynum;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getByMonthDayList()
|
||||
{
|
||||
return $this->byMonthDayList;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $byMonthDayList
|
||||
* @return \Jsvrcek\ICS\Model\Recurrence\RecurrenceRule
|
||||
*/
|
||||
public function setByMonthDayList(array $byMonthDayList)
|
||||
{
|
||||
$this->byMonthDayList = $byMonthDayList;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param integer $integer
|
||||
* @return \Jsvrcek\ICS\Model\Recurrence\RecurrenceRule
|
||||
*/
|
||||
public function addByMonthDay($integer)
|
||||
{
|
||||
$this->validateInteger($integer);
|
||||
|
||||
$this->byMonthDayList[] = $bySecond;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getByYearDayList()
|
||||
{
|
||||
return $this->byYearDayList;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $byYearDayList
|
||||
* @return \Jsvrcek\ICS\Model\Recurrence\RecurrenceRule
|
||||
*/
|
||||
public function setByYearDayList(array $byYearDayList)
|
||||
{
|
||||
$this->byYearDayList = $byYearDayList;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getByWeekNumberList()
|
||||
{
|
||||
return $this->byWeekNumberList;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $byWeekNumberList
|
||||
* @return \Jsvrcek\ICS\Model\Recurrence\RecurrenceRule
|
||||
*/
|
||||
public function setByWeekNumberList(array $byWeekNumberList)
|
||||
{
|
||||
$this->byWeekNumberList = $byWeekNumberList;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getByMonthList()
|
||||
{
|
||||
return $this->byMonthList;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $byMonthList
|
||||
* @return \Jsvrcek\ICS\Model\Recurrence\RecurrenceRule
|
||||
*/
|
||||
public function setByMonthList(array $byMonthList)
|
||||
{
|
||||
$this->byMonthList = $byMonthList;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getBySetPosYearDayList()
|
||||
{
|
||||
return $this->bySetPosYearDayList;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $bySetPosYearDayList
|
||||
* @return \Jsvrcek\ICS\Model\Recurrence\RecurrenceRule
|
||||
*/
|
||||
public function setBySetPosYearDayList(array $bySetPosYearDayList)
|
||||
{
|
||||
$this->bySetPosYearDayList = $bySetPosYearDayList;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @return Weekday
|
||||
*/
|
||||
public function getWeekStart()
|
||||
{
|
||||
return $this->weekStart;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Weekday $weekStart
|
||||
* @return \Jsvrcek\ICS\Model\Recurrence\RecurrenceRule
|
||||
*/
|
||||
public function setWeekStart(Weekday $weekStart)
|
||||
{
|
||||
$this->weekStart = $weekStart;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* parses an RRULE string, hydrates self with values
|
||||
*
|
||||
* @param string $rRuleString
|
||||
* @return \Jsvrcek\ICS\Model\Recurrence\RecurrenceRule
|
||||
*/
|
||||
public function parse($rRuleString)
|
||||
{
|
||||
//remove RRULE:
|
||||
$string = str_replace(self::KEY, null, $rRuleString);
|
||||
|
||||
$attributes = explode(';', $string);
|
||||
|
||||
foreach ($attributes as $attribute)
|
||||
{
|
||||
list($key, $value) = explode('=', $attribute);
|
||||
|
||||
switch ($key)
|
||||
{
|
||||
case Frequency::KEY:
|
||||
if ($valueStringKey = array_search($value, Frequency::$values))
|
||||
{
|
||||
$this->setFrequency(new Frequency($valueStringKey));
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new CalendarRecurrenceException('Unsupported FREQ value in Recurrence Rule (RRULE) string: '.$value);
|
||||
}
|
||||
break;
|
||||
|
||||
case 'INTERVAL':
|
||||
$this->setInterval((int)$value);
|
||||
break;
|
||||
|
||||
case 'UNTIL':
|
||||
$untilDate = new \DateTime(str_replace('Z', '', $value), new \DateTimeZone('UTC'));
|
||||
$this->setUntil($untilDate);
|
||||
break;
|
||||
|
||||
default:
|
||||
throw new CalendarRecurrenceException('Unsupported attribute in Recurrence Rule (RRULE) string: '.$key);
|
||||
}
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
$items = array($this->getFrequency()->__toString());
|
||||
|
||||
if ($this->interval)
|
||||
$items[] = 'INTERVAL='.$this->interval;
|
||||
|
||||
if ($this->until)
|
||||
$items[] = 'UNTIL='.$this->formatter->getFormattedUTCDateTime($this->until);
|
||||
|
||||
if ($this->count)
|
||||
$items[] = 'COUNT='.$this->count;
|
||||
|
||||
if ($this->byDayList)
|
||||
$items[] = 'BYDAY='.implode(',', $this->byDayList);
|
||||
|
||||
return self::KEY.implode(';', $items);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param integer $integer
|
||||
* @throws CalendarRecurrenceException
|
||||
*/
|
||||
private function validateInteger($integer)
|
||||
{
|
||||
if (!is_int($integer))
|
||||
{
|
||||
throw new CalendarRecurrenceException('Value must be an integer');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,438 @@
|
||||
<?php
|
||||
|
||||
namespace Jsvrcek\ICS\Model\Relationship;
|
||||
|
||||
use Jsvrcek\ICS\Utility\Formatter;
|
||||
|
||||
class Attendee
|
||||
{
|
||||
/**
|
||||
*
|
||||
* @var Formatter
|
||||
*/
|
||||
private $formatter;
|
||||
|
||||
/**
|
||||
* RFC 5545 cal-address
|
||||
* @var string $value
|
||||
*/
|
||||
private $value;
|
||||
|
||||
/**
|
||||
* RFC 5545 cutypeparam
|
||||
* @var string $calendarUserType
|
||||
*/
|
||||
private $calendarUserType;
|
||||
|
||||
/**
|
||||
* RFC 5545 memberparam
|
||||
* @var array $calendarMember array of uri values
|
||||
*/
|
||||
private $calendarMembers = array();
|
||||
|
||||
/**
|
||||
* RFC 5545 roleparam
|
||||
* @var string $role
|
||||
*/
|
||||
private $role;
|
||||
|
||||
/**
|
||||
* RFC 5545 partstatparam
|
||||
* @var string $participationStatus
|
||||
*/
|
||||
private $participationStatus;
|
||||
|
||||
/**
|
||||
* RFC 5545 rsvpparam
|
||||
* @var string $rsvp
|
||||
*/
|
||||
private $rsvp;
|
||||
|
||||
/**
|
||||
* RFC 5545 deltoparam
|
||||
* @var array $delegatedTo array of uri values
|
||||
*/
|
||||
private $delegatedTo = array();
|
||||
|
||||
/**
|
||||
* RFC 5545 delfromparam
|
||||
* @var array $delegatedFrom array of uri values
|
||||
*/
|
||||
private $delegatedFrom = array();
|
||||
|
||||
/**
|
||||
* RFC 5545 sentbyparam
|
||||
* @var string $sentBy
|
||||
*/
|
||||
private $sentBy;
|
||||
|
||||
/**
|
||||
* RFC 5545 cnparam
|
||||
* @var string $name
|
||||
*/
|
||||
private $name;
|
||||
|
||||
/**
|
||||
* RFC 5545 dirparam
|
||||
* @var string $directory
|
||||
*/
|
||||
private $directory;
|
||||
|
||||
/**
|
||||
* RFC 5545 languageparam
|
||||
* @var string $language
|
||||
*/
|
||||
private $language;
|
||||
|
||||
/**
|
||||
* @param Formatter $formatter
|
||||
*/
|
||||
public function __construct(Formatter $formatter)
|
||||
{
|
||||
$this->formatter = $formatter;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getValue()
|
||||
{
|
||||
return $this->value;
|
||||
}
|
||||
|
||||
/**
|
||||
* RFC 5545 cal-address http://tools.ietf.org/html/rfc5545#section-3.3.3
|
||||
* @param string $uri
|
||||
* @return \Jsvrcek\ICS\Model\Relationship\Attendee
|
||||
*/
|
||||
public function setValue($uri)
|
||||
{
|
||||
$this->value = $this->formatter->getFormattedUri($uri);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getCalendarUserType()
|
||||
{
|
||||
return $this->calendarUserType;
|
||||
}
|
||||
|
||||
/**
|
||||
* RFC 5545 cutypeparam http://tools.ietf.org/html/rfc5545#section-3.2.3
|
||||
*
|
||||
* @param string $calendarUserType
|
||||
* "INDIVIDUAL" ; An individual<br>
|
||||
* "GROUP" ; A group of individuals<br>
|
||||
* "RESOURCE" ; A physical resource<br>
|
||||
* "ROOM" ; A room resource<br>
|
||||
* "UNKNOWN" ; Otherwise not known<br>
|
||||
* x-name ; Experimental type<br>
|
||||
* iana-token) ; Other IANA-registered type
|
||||
* @return \Jsvrcek\ICS\Model\Relationship\Attendee
|
||||
*/
|
||||
public function setCalendarUserType($calendarUserType)
|
||||
{
|
||||
$this->calendarUserType = $calendarUserType;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getCalendarMembers()
|
||||
{
|
||||
return $this->calendarMembers;
|
||||
}
|
||||
|
||||
/**
|
||||
* RFC 5545 memberparam http://tools.ietf.org/html/rfc5545#section-3.2.11
|
||||
* @param array $calendarMemberUris array of uri values for calendar users ex. array('sue@example.com', 'joe@example.com')
|
||||
* @return \Jsvrcek\ICS\Model\Relationship\Attendee
|
||||
*/
|
||||
public function setCalendarMembers($calendarMemberUris)
|
||||
{
|
||||
foreach ($calendarMemberUris as &$uri)
|
||||
{
|
||||
$uri = $this->formatter->getFormattedUri($uri);
|
||||
}
|
||||
|
||||
$this->calendarMembers = $calendarMemberUris;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* RFC 5545 memberparam http://tools.ietf.org/html/rfc5545#section-3.2.11
|
||||
* @param string $uri
|
||||
* @return \Jsvrcek\ICS\Model\Relationship\Attendee
|
||||
*/
|
||||
public function addCalendarMember($uri)
|
||||
{
|
||||
$this->calendarMembers[] = $this->formatter->getFormattedUri($uri);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getRole()
|
||||
{
|
||||
return $this->role;
|
||||
}
|
||||
|
||||
/**
|
||||
* RFC 5545 roleparam http://tools.ietf.org/html/rfc5545#section-3.2.16
|
||||
* @param string $role
|
||||
* "CHAIR" ; Indicates chair of the calendar entity <br>
|
||||
* "REQ-PARTICIPANT" ; Indicates a participant whose participation is required <br>
|
||||
* "OPT-PARTICIPANT" ; Indicates a participant whose participation is optional <br>
|
||||
* "NON-PARTICIPANT" ; Indicates a participant who is copied for information purposes only <br>
|
||||
* x-name ; Experimental role
|
||||
* iana-token ; Other IANA role
|
||||
* @return \Jsvrcek\ICS\Model\Relationship\Attendee
|
||||
*/
|
||||
public function setRole($role)
|
||||
{
|
||||
$this->role = $role;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getParticipationStatus()
|
||||
{
|
||||
return $this->participationStatus;
|
||||
}
|
||||
|
||||
/**
|
||||
* RFC 5545 partstatparam http://tools.ietf.org/html/rfc5545#section-3.2.12
|
||||
* @param string $participationStatus
|
||||
* Example values for an Event: <br>
|
||||
* "NEEDS-ACTION" ; Event needs action <br>
|
||||
* "ACCEPTED" ; Event accepted <br>
|
||||
* "DECLINED" ; Event declined <br>
|
||||
* "TENTATIVE" ; Event tentatively accepted <br>
|
||||
* "DELEGATED" ; Event delegated
|
||||
*
|
||||
* @return \Jsvrcek\ICS\Model\Relationship\Attendee
|
||||
*/
|
||||
public function setParticipationStatus($participationStatus)
|
||||
{
|
||||
$this->participationStatus = $participationStatus;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getRsvp()
|
||||
{
|
||||
return $this->rsvp;
|
||||
}
|
||||
|
||||
/**
|
||||
* RFC 5545 rsvpparam http://tools.ietf.org/html/rfc5545#section-3.2.17
|
||||
* @param string $rsvp "TRUE" or "FALSE"
|
||||
* @return \Jsvrcek\ICS\Model\Relationship\Attendee
|
||||
*/
|
||||
public function setRsvp($rsvp)
|
||||
{
|
||||
$this->rsvp = $rsvp;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getDelegatedTo()
|
||||
{
|
||||
return $this->delegatedTo;
|
||||
}
|
||||
|
||||
/**
|
||||
* RFC 5545 deltoparam http://tools.ietf.org/html/rfc5545#section-3.2.5
|
||||
* @param array $delegatedToUris array of uri values for calendar users ex. array('sue@example.com', 'joe@example.com')
|
||||
* @return \Jsvrcek\ICS\Model\Relationship\Attendee
|
||||
*/
|
||||
public function setDelegatedTo(array $delegatedToUris)
|
||||
{
|
||||
foreach ($delegatedToUris as &$uri)
|
||||
{
|
||||
$uri = $this->formatter->getFormattedUri($uri);
|
||||
}
|
||||
|
||||
$this->delegatedTo = $delegatedToUris;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $uri uri value for calendar users ex. 'mary@example.com'
|
||||
* @return \Jsvrcek\ICS\Model\Relationship\Attendee
|
||||
*/
|
||||
public function addDelegatedTo($uri)
|
||||
{
|
||||
$this->delegatedTo[] = $this->formatter->getFormattedUri($uri);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getDelegatedFrom()
|
||||
{
|
||||
return $this->delegatedFrom;
|
||||
}
|
||||
|
||||
/**
|
||||
* RFC 5545 delfromparam http://tools.ietf.org/html/rfc5545#section-3.2.4
|
||||
* @param array $delegatedFromUris array of uri values for calendar users ex. array('sue@example.com', 'joe@example.com')
|
||||
* @return \Jsvrcek\ICS\Model\Relationship\Attendee
|
||||
*/
|
||||
public function setDelegatedFrom(array $delegatedFromUris)
|
||||
{
|
||||
foreach ($delegatedFromUris as &$uri)
|
||||
{
|
||||
$uri = $this->formatter->getFormattedUri($uri);
|
||||
}
|
||||
|
||||
$this->delegatedFrom = $delegatedFromUris;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $uri uri value for calendar users ex. 'mary@example.com'
|
||||
* @return \Jsvrcek\ICS\Model\Relationship\Attendee
|
||||
*/
|
||||
public function addDelegatedFrom($uri)
|
||||
{
|
||||
$this->delegatedFrom[] = $this->formatter->getFormattedUri($uri);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getSentBy()
|
||||
{
|
||||
return $this->sentBy;
|
||||
}
|
||||
|
||||
/**
|
||||
* RFC 5545 sentbyparam http://tools.ietf.org/html/rfc5545#section-3.2.18
|
||||
* @param string $sentBy email address
|
||||
* @return \Jsvrcek\ICS\Model\Relationship\Attendee
|
||||
*/
|
||||
public function setSentBy($sentBy)
|
||||
{
|
||||
$this->sentBy = $sentBy;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @return \Jsvrcek\ICS\Model\Relationship\Attendee
|
||||
*/
|
||||
public function setName($name)
|
||||
{
|
||||
$this->name = $name;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getDirectory()
|
||||
{
|
||||
return $this->directory;
|
||||
}
|
||||
|
||||
/**
|
||||
* RFC 5545 dirparam http://tools.ietf.org/html/rfc5545#section-3.2.6
|
||||
* @param string $directory uri directory entry associated with the calendar user
|
||||
* @return \Jsvrcek\ICS\Model\Relationship\Attendee
|
||||
*/
|
||||
public function setDirectory($uri)
|
||||
{
|
||||
$this->directory = $uri;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getLanguage()
|
||||
{
|
||||
return $this->language;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $language RFC 1766 language identifier
|
||||
* @return \Jsvrcek\ICS\Model\Relationship\Attendee
|
||||
*/
|
||||
public function setLanguage($language)
|
||||
{
|
||||
$this->language = $language;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
$string = 'ATTENDEE';
|
||||
|
||||
if ($this->calendarUserType)
|
||||
$string .= ';CUTYPE='.$this->calendarUserType;
|
||||
|
||||
if (count($this->calendarMembers))
|
||||
{
|
||||
$string .= ';MEMBER="'.implode('","', $this->calendarMembers).'"';
|
||||
}
|
||||
|
||||
if ($this->role)
|
||||
$string .= ';ROLE='.$this->role;
|
||||
|
||||
if ($this->participationStatus)
|
||||
$string .= ';PARTSTAT='.$this->participationStatus;
|
||||
|
||||
if ($this->rsvp)
|
||||
$string .= ';RSVP='.$this->rsvp;
|
||||
|
||||
if (count($this->delegatedTo))
|
||||
{
|
||||
$string .= ';DELEGATED-TO="'.implode('","', $this->delegatedTo).'"';
|
||||
}
|
||||
|
||||
if (count($this->delegatedFrom))
|
||||
{
|
||||
$string .= ';DELEGATED-FROM="'.implode('","', $this->delegatedFrom).'"';
|
||||
}
|
||||
|
||||
if ($this->sentBy)
|
||||
$string .= ';SENT-BY="'.$this->sentBy.'"';
|
||||
|
||||
if ($this->name)
|
||||
$string .= ';CN='.$this->name;
|
||||
|
||||
if ($this->directory)
|
||||
$string .= ';DIR="'.$this->directory.'"';
|
||||
|
||||
if ($this->language)
|
||||
$string .= ';LANGUAGE='.$this->language;
|
||||
|
||||
$string .= ':'.$this->value;
|
||||
|
||||
return $string;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,166 @@
|
||||
<?php
|
||||
|
||||
namespace Jsvrcek\ICS\Model\Relationship;
|
||||
|
||||
use Jsvrcek\ICS\Utility\Formatter;
|
||||
|
||||
class Organizer
|
||||
{
|
||||
/**
|
||||
*
|
||||
* @var Formatter
|
||||
*/
|
||||
private $formatter;
|
||||
|
||||
/**
|
||||
* RFC 5545 cal-address
|
||||
* @var string $value
|
||||
*/
|
||||
private $value;
|
||||
|
||||
/**
|
||||
* RFC 5545 cnparam
|
||||
* @var string $name
|
||||
*/
|
||||
private $name;
|
||||
|
||||
/**
|
||||
* RFC 5545 dirparam
|
||||
* @var string $directory
|
||||
*/
|
||||
private $directory;
|
||||
|
||||
/**
|
||||
* RFC 5545 sentbyparam
|
||||
* @var string $sentBy
|
||||
*/
|
||||
private $sentBy;
|
||||
|
||||
/**
|
||||
* RFC 5545 languageparam
|
||||
* @var string $language
|
||||
*/
|
||||
private $language;
|
||||
|
||||
/**
|
||||
* @param Formatter $formatter
|
||||
*/
|
||||
public function __construct(Formatter $formatter)
|
||||
{
|
||||
$this->formatter = $formatter;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getValue()
|
||||
{
|
||||
return $this->value;
|
||||
}
|
||||
|
||||
/**
|
||||
* RFC 5545 cal-address http://tools.ietf.org/html/rfc5545#section-3.3.3
|
||||
* @param string $uri
|
||||
* @return \Jsvrcek\ICS\Model\Relationship\Organizer
|
||||
*/
|
||||
public function setValue($uri)
|
||||
{
|
||||
$this->value = $this->formatter->getFormattedUri($uri);
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getName()
|
||||
{
|
||||
return $this->name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $name
|
||||
* @return \Jsvrcek\ICS\Model\Relationship\Organizer
|
||||
*/
|
||||
public function setName($name)
|
||||
{
|
||||
$this->name = $name;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getDirectory()
|
||||
{
|
||||
return $this->directory;
|
||||
}
|
||||
|
||||
/**
|
||||
* RFC 5545 dirparam http://tools.ietf.org/html/rfc5545#section-3.2.6
|
||||
* @param string $directory uri directory entry associated with the calendar user
|
||||
* @return \Jsvrcek\ICS\Model\Relationship\Organizer
|
||||
*/
|
||||
public function setDirectory($uri)
|
||||
{
|
||||
$this->directory = $uri;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getSentBy()
|
||||
{
|
||||
return $this->sentBy;
|
||||
}
|
||||
|
||||
/**
|
||||
* RFC 5545 sentbyparam http://tools.ietf.org/html/rfc5545#section-3.2.18
|
||||
* @param string $sentBy email address
|
||||
* @return \Jsvrcek\ICS\Model\Relationship\Organizer
|
||||
*/
|
||||
public function setSentBy($sentBy)
|
||||
{
|
||||
$this->sentBy = $sentBy;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getLanguage()
|
||||
{
|
||||
return $this->language;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $language RFC 1766 language identifier
|
||||
* @return \Jsvrcek\ICS\Model\Relationship\Organizer
|
||||
*/
|
||||
public function setLanguage($language)
|
||||
{
|
||||
$this->language = $language;
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function __toString()
|
||||
{
|
||||
$string = 'ORGANIZER';
|
||||
|
||||
if ($this->sentBy)
|
||||
$string .= ';SENT-BY="'.$this->sentBy.'"';
|
||||
|
||||
if ($this->name)
|
||||
$string .= ';CN='.$this->name;
|
||||
|
||||
if ($this->directory)
|
||||
$string .= ';DIR="'.$this->directory.'"';
|
||||
|
||||
if ($this->language)
|
||||
$string .= ';LANGUAGE='.$this->language;
|
||||
|
||||
$string .= ':'.$this->value;
|
||||
|
||||
return $string;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
<?php
|
||||
|
||||
namespace Jsvrcek\ICS\Utility;
|
||||
|
||||
class Formatter
|
||||
{
|
||||
const DATE_TIME = 'Ymd\THis';
|
||||
const DATE_TIME_UTC = 'Ymd\THis\Z';
|
||||
const DATE = 'Ymd';
|
||||
|
||||
/**
|
||||
* @param \DateTime $dateTime
|
||||
* @return string
|
||||
*/
|
||||
public function getFormattedDateTime(\DateTime $dateTime)
|
||||
{
|
||||
return $dateTime->format(self::DATE_TIME);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $offset
|
||||
* @return string
|
||||
*/
|
||||
public function getFormattedTimeOffset($offset)
|
||||
{
|
||||
$prefix = ($offset < 0) ? '-' : '+';
|
||||
|
||||
return $prefix.gmdate('Hi', abs($offset));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \DateTime $dateTime
|
||||
* @return string
|
||||
*/
|
||||
public function getFormattedUTCDateTime(\DateTime $dateTime)
|
||||
{
|
||||
return $dateTime->setTimezone(new \DateTimeZone('UTC'))
|
||||
->format(self::DATE_TIME_UTC);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \DateTime $dateTime
|
||||
* @return string
|
||||
*/
|
||||
public function getFormattedDate(\DateTime $dateTime)
|
||||
{
|
||||
return $dateTime->format(self::DATE);
|
||||
}
|
||||
|
||||
/**
|
||||
* converts email addresses into mailto: uri
|
||||
* @param string $uri
|
||||
* @return string
|
||||
*/
|
||||
public function getFormattedUri($uri)
|
||||
{
|
||||
if (strpos($uri, '@') && stripos($uri, 'mailto:') === false)
|
||||
$uri = 'mailto:'.$uri;
|
||||
|
||||
return $uri;
|
||||
}
|
||||
|
||||
/**
|
||||
* converts DateInterval object to string that can be used for a VALARM DURATION
|
||||
* @param \DateInterval $interval
|
||||
* @return string
|
||||
*/
|
||||
public function getFormattedDateInterval(\DateInterval $interval)
|
||||
{
|
||||
$format = "P";
|
||||
|
||||
if ($interval->y) { $format .= '%yY'; }
|
||||
if ($interval->m) { $format .= '%mM'; }
|
||||
if ($interval->d) { $format .= '%dD'; }
|
||||
|
||||
if ($interval->h || $interval->i || $interval->s) {
|
||||
$format .= "T";
|
||||
}
|
||||
|
||||
if ($interval->h) { $format .= '%hH'; }
|
||||
if ($interval->i) { $format .= '%iM'; }
|
||||
if ($interval->s) { $format .= '%sS'; }
|
||||
|
||||
return $interval->format($format);
|
||||
}
|
||||
}
|
||||
+110
@@ -0,0 +1,110 @@
|
||||
<?php
|
||||
|
||||
namespace Jsvrcek\ICS\Utility;
|
||||
|
||||
class Provider implements \Iterator
|
||||
{
|
||||
/**
|
||||
*
|
||||
* @var \Closure
|
||||
*/
|
||||
private $provider;
|
||||
|
||||
/**
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $data = array();
|
||||
|
||||
/**
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $manuallyAddedData = array();
|
||||
|
||||
/**
|
||||
*
|
||||
* @var integer
|
||||
*/
|
||||
private $key;
|
||||
|
||||
/**
|
||||
* @param \Closure $provider An optional closure for adding items in batches during iteration. The closure will be
|
||||
* called each time the end of the internal data array is reached during iteration, and the current data
|
||||
* array key value will be passed as an argument. The closure should return an array containing the next
|
||||
* batch of items.
|
||||
*/
|
||||
public function __construct(\Closure $provider = null)
|
||||
{
|
||||
$this->provider = $provider;
|
||||
}
|
||||
|
||||
/**
|
||||
* for manually adding items, rather than using a provider closure to add items in batches during iteration
|
||||
* Cannot be used in conjunction with a provider closure!
|
||||
*
|
||||
* @param mixed $item
|
||||
*/
|
||||
public function add($item)
|
||||
{
|
||||
$this->manuallyAddedData[] = $item;
|
||||
}
|
||||
|
||||
/* (non-PHPdoc)
|
||||
* @see Iterator::current()
|
||||
*/
|
||||
public function current()
|
||||
{
|
||||
return current($this->data);
|
||||
}
|
||||
|
||||
/* (non-PHPdoc)
|
||||
* @see Iterator::key()
|
||||
*/
|
||||
public function key()
|
||||
{
|
||||
return $this->key;
|
||||
}
|
||||
|
||||
/* (non-PHPdoc)
|
||||
* @see Iterator::next()
|
||||
*/
|
||||
public function next()
|
||||
{
|
||||
array_shift($this->data);
|
||||
$this->key++;
|
||||
}
|
||||
|
||||
/* (non-PHPdoc)
|
||||
* @see Iterator::rewind()
|
||||
*/
|
||||
public function rewind()
|
||||
{
|
||||
$this->data = array();
|
||||
$this->key = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* get next batch from provider if data array is at the end
|
||||
*
|
||||
* (non-PHPdoc)
|
||||
* @see Iterator::valid()
|
||||
*/
|
||||
public function valid()
|
||||
{
|
||||
if (count($this->data) < 1)
|
||||
{
|
||||
if ($this->provider instanceof \Closure)
|
||||
{
|
||||
$this->data = $this->provider->__invoke($this->key);
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->data = $this->manuallyAddedData;
|
||||
$this->manuallyAddedData = array();
|
||||
}
|
||||
}
|
||||
|
||||
return count($this->data) > 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,154 @@
|
||||
<?php
|
||||
|
||||
namespace Jsvrcek\ICS\Tests;
|
||||
|
||||
use Jsvrcek\ICS\Model\CalendarAlarm;
|
||||
use Jsvrcek\ICS\Model\Recurrence\DataType\Weekday;
|
||||
|
||||
use Jsvrcek\ICS\Model\Recurrence\DataType\WeekdayNum;
|
||||
|
||||
use Jsvrcek\ICS\Model\Recurrence\DataType\Frequency;
|
||||
|
||||
use Jsvrcek\ICS\Model\Recurrence\RecurrenceRule;
|
||||
|
||||
use Jsvrcek\ICS\Model\Relationship\Organizer;
|
||||
|
||||
use Jsvrcek\ICS\Utility\Formatter;
|
||||
|
||||
use Jsvrcek\ICS\CalendarStream;
|
||||
|
||||
use Jsvrcek\ICS\Model\Relationship\Attendee;
|
||||
|
||||
use Jsvrcek\ICS\CalendarExport;
|
||||
use Jsvrcek\ICS\Model\Calendar;
|
||||
use Jsvrcek\ICS\Model\CalendarEvent;
|
||||
|
||||
class CalendarExportTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
/**
|
||||
* @covers Jsvrcek\ICS\CalendarExport::getStream
|
||||
*/
|
||||
public function testGetStream()
|
||||
{
|
||||
$timezone = new \DateTimeZone('Antarctica/McMurdo');
|
||||
|
||||
$organizer = new Organizer(new Formatter());
|
||||
$organizer->setValue('sue@example.com')
|
||||
->setName('Sue Jones')
|
||||
->setSentBy('mary@example.com')
|
||||
->setLanguage('en');
|
||||
|
||||
$attendee = new Attendee(new Formatter());
|
||||
$attendee->setName('Jane Smith')
|
||||
->setCalendarUserType('INDIVIDUAL')
|
||||
->setParticipationStatus('ACCEPTED')
|
||||
->setRole('REQ-PARTICIPANT')
|
||||
->setSentBy('joe@example')
|
||||
->addCalendarMember('list@example.com')
|
||||
->setValue('jane-smith@example.com');
|
||||
|
||||
$event = new CalendarEvent();
|
||||
$event->setUid('lLKjd89283oja89282lkjd8@example.com')
|
||||
->setStart(new \DateTime('4 October 2013 12:00:00', $timezone))
|
||||
->setEnd(new \DateTime('4 October 2013 22:00:00', $timezone))
|
||||
->setSummary('Poker night at the South Pole')
|
||||
->addAttendee($attendee)
|
||||
->setOrganizer($organizer)
|
||||
->setSequence(3)
|
||||
->setTimestamp(new \DateTime('1 September 2013', $timezone));
|
||||
|
||||
$rrule = new RecurrenceRule(new Formatter());
|
||||
$rrule->setFrequency(new Frequency(Frequency::MONTHLY))
|
||||
->setInterval(2)
|
||||
->setCount(40)
|
||||
->addByDay(new WeekdayNum(Weekday::SATURDAY, 1))
|
||||
->addByDay(new WeekdayNum(Weekday::SATURDAY, 2))
|
||||
->addByDay(new WeekdayNum(Weekday::SATURDAY, 3))
|
||||
->addByDay(new WeekdayNum(Weekday::SATURDAY, 4))
|
||||
->addByDay(new WeekdayNum(Weekday::FRIDAY, 1));
|
||||
$event->setRecurrenceRule($rrule);
|
||||
|
||||
//add an alarms to this event
|
||||
$alarmAudio = new CalendarAlarm();
|
||||
$alarmAudio->setAction("audio");
|
||||
$alarmAudio->setTrigger($event->getStart());
|
||||
$alarmAudio->addAttachment("FMTTYPE=audio/basic:ftp://example.com/pub/sounds/bell-01.aud");
|
||||
$event->addAlarm($alarmAudio);
|
||||
|
||||
$alarmDisplay = new CalendarAlarm();
|
||||
$alarmDisplay->setAction("display");
|
||||
$alarmDisplay->setTrigger($event->getStart());
|
||||
$alarmDisplay->setRepeat(3);
|
||||
$alarmDisplay->setDuration(new \DateInterval('PT15M'));
|
||||
$alarmDisplay->setDescription("DESCRIPTION");
|
||||
$event->addAlarm($alarmDisplay);
|
||||
|
||||
$alarmEmail = new CalendarAlarm();
|
||||
$alarmEmail->setAction('email');
|
||||
$alarmEmail->setTrigger($event->getStart());
|
||||
$alarmEmail->addAttendee($attendee);
|
||||
$alarmEmail->setSummary("EMAIL SUBJECT");
|
||||
$alarmEmail->setDescription("EMAIL BODY");
|
||||
$alarmEmail->addAttachment("FMTTYPE=application/msword:http://example.com/agenda.docx");
|
||||
$alarmEmail->addAttachment("FMTTYPE=application/pdf:http://example.com/agenda.pdf");
|
||||
$event->addAlarm($alarmEmail);
|
||||
|
||||
//test exception dates
|
||||
$eventTwo = new CalendarEvent();
|
||||
$eventTwo->setUid('eventtwo@example.com')
|
||||
->setStart(new \DateTime('2 October 2013', $timezone))
|
||||
->setSummary('Every Wednesday event')
|
||||
->setTimestamp(new \DateTime('1 September 2013', $timezone));
|
||||
|
||||
$rrule = new RecurrenceRule(new Formatter());
|
||||
$rrule->setFrequency(new Frequency(Frequency::WEEKLY));
|
||||
|
||||
$eventTwo->setRecurrenceRule($rrule);
|
||||
|
||||
//add exception dates to the event recurrence
|
||||
$eventTwo->addExceptionDate(new \DateTime('16 October 2013', $timezone))
|
||||
->addExceptionDate(new \DateTime('30 October 2013', $timezone));
|
||||
|
||||
$cal = new Calendar();
|
||||
$cal->setProdId('-//Jsvrcek//ICS//EN')
|
||||
->setTimezone($timezone)
|
||||
->addEvent($event)
|
||||
->addEvent($eventTwo);
|
||||
|
||||
//create second calendar using batch event provider
|
||||
$timezone = new \DateTimeZone('Arctic/Longyearbyen');
|
||||
$calTwo = new Calendar();
|
||||
$calTwo->setProdId('-//Jsvrcek//ICS//EN2')
|
||||
->setTimezone($timezone);
|
||||
|
||||
$calTwo->setEventsProvider(function($start) use ($timezone){
|
||||
$eventOne = new CalendarEvent();
|
||||
$eventOne->setUid('asdfasdf@example.com')
|
||||
->setStart(new \DateTime('2016-01-01 01:01:01', $timezone))
|
||||
->setEnd(new \DateTime('2016-01-02 01:01:01', $timezone))
|
||||
->setSummary('A long day')
|
||||
->setTimestamp(new \DateTime('1 September 2013', $timezone));
|
||||
|
||||
$eventTwo = new CalendarEvent();
|
||||
$eventTwo->setUid('asdfasdf@example.com')
|
||||
->setStart(new \DateTime('2016-01-02 01:01:01', $timezone))
|
||||
->setEnd(new \DateTime('2016-01-03 01:01:01', $timezone))
|
||||
->setSummary('Another long day')
|
||||
->setTimestamp(new \DateTime('1 September 2013', $timezone));
|
||||
|
||||
return ($start > 0) ? array() : array($eventOne, $eventTwo);
|
||||
});
|
||||
|
||||
$ce = new CalendarExport(new CalendarStream(), new Formatter());
|
||||
$ce->addCalendar($cal)
|
||||
->addCalendar($calTwo);
|
||||
|
||||
$stream = $ce->getStream();
|
||||
|
||||
//file_put_contents(__DIR__.'/test.ics', $stream);
|
||||
|
||||
$expected = file_get_contents(__DIR__.'/test.ics');
|
||||
|
||||
$this->assertEquals($expected, $stream);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
|
||||
namespace Jsvrcek\ICS\Tests;
|
||||
|
||||
use Jsvrcek\ICS\CalendarStream;
|
||||
use Jsvrcek\ICS\Constants;
|
||||
|
||||
class CalendarStreamTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
public function testGetStream()
|
||||
{
|
||||
$s = new CalendarStream();
|
||||
$this->assertEquals('', $s->getStream());
|
||||
}
|
||||
|
||||
public function testAddItemToStream()
|
||||
{
|
||||
//simple test
|
||||
$s = new CalendarStream();
|
||||
$item = 'TEST';
|
||||
$expected = 'TEST'.Constants::CRLF;
|
||||
$s->addItem($item);
|
||||
$this->assertEquals($expected, $s->getStream());
|
||||
|
||||
//long string test
|
||||
$s = new CalendarStream();
|
||||
$item = ' aaaaaaa10 aaaaaaa20 aaaaaaa30 aaaaaaa40 aaaaaaa50 aaaaaaa60 aaaaaaa70 aaaaaaa80 aaaaaaa90';
|
||||
$expected = ' aaaaaaa10 aaaaaaa20 aaaaaaa30 aaaaaaa40 aaaaaaa50 aaaaaaa60 aaaaaaa70'.Constants::CRLF.' '.' aaaaaaa80 aaaaaaa90'.Constants::CRLF;
|
||||
$s->addItem($item);
|
||||
$this->assertEquals($expected, $s->getStream());
|
||||
|
||||
$s = new CalendarStream();
|
||||
$item = ' ëëëë1 ëëëë2 ëëëë3 ëëëë4 ëëëë5 ëëëë6 ëëëëëëëëë8 ëëëë9';
|
||||
$expected = ' ëëëë1 ëëëë2 ëëëë3 ëëëë4 ëëëë5 ëëëë6 ëëëë'.Constants::CRLF.' '.'ëëëëë8 ëëëë9'.Constants::CRLF;
|
||||
$s->addItem($item);
|
||||
$this->assertEquals($expected, $s->getStream());
|
||||
}
|
||||
|
||||
public function testReset()
|
||||
{
|
||||
$s = new CalendarStream();
|
||||
$item = 'TEST';
|
||||
$s->addItem($item);
|
||||
$s->reset();
|
||||
$this->assertEquals('', $s->getStream());
|
||||
}
|
||||
|
||||
public function test__toString()
|
||||
{
|
||||
$s = new CalendarStream();
|
||||
$item = 'TEST';
|
||||
$s->addItem($item);
|
||||
$expected = 'TEST'.Constants::CRLF;
|
||||
$this->assertEquals($expected, $s->__toString());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
<?php
|
||||
|
||||
namespace Jsvrcek\ICS\Tests\Model;
|
||||
|
||||
use Jsvrcek\ICS\Model\CalendarEvent;
|
||||
use Jsvrcek\ICS\Exception\CalendarEventException;
|
||||
|
||||
/**
|
||||
* Generated by PHPUnit_SkeletonGenerator on 2013-10-20 at 12:03:54.
|
||||
*/
|
||||
class CalendarEventTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
/**
|
||||
* @var CalendarEvent
|
||||
*/
|
||||
protected $object;
|
||||
|
||||
/**
|
||||
* Sets up the fixture, for example, opens a network connection.
|
||||
* This method is called before a test is executed.
|
||||
* @return CalendarEvent
|
||||
*/
|
||||
protected function setUp()
|
||||
{
|
||||
$this->object = new CalendarEvent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Tears down the fixture, for example, closes a network connection.
|
||||
* This method is called after a test is executed.
|
||||
*/
|
||||
protected function tearDown()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers Jsvrcek\ICS\Model\CalendarEvent::setStart
|
||||
*/
|
||||
public function testSetStart()
|
||||
{
|
||||
$start = new \DateTime();
|
||||
|
||||
$this->object->setStart($start);
|
||||
|
||||
// test start
|
||||
$this->assertEquals($start, $this->object->getStart());
|
||||
|
||||
//test default end
|
||||
$this->assertEquals($start->add(\DateInterval::createFromDateString('30 minutes')), $this->object->getEnd());
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers Jsvrcek\ICS\Model\CalendarEvent::setEnd
|
||||
* @expectedException Jsvrcek\ICS\Exception\CalendarEventException
|
||||
* @expectedExceptionMessage End DateTime must be greater than Start DateTime
|
||||
*/
|
||||
public function testSetEndDateEarlierThanStart()
|
||||
{
|
||||
$start = new \DateTime('now');
|
||||
$end = new \DateTime('yesterday');
|
||||
|
||||
$this->object->setStart($start);
|
||||
$this->object->setEnd($end);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers Jsvrcek\ICS\Model\CalendarEvent::setEnd
|
||||
* @expectedException Jsvrcek\ICS\Exception\CalendarEventException
|
||||
* @expectedExceptionMessage You must set the Start time before setting the End Time of a CalendarEvent
|
||||
*/
|
||||
public function testSetEndWithoutStart()
|
||||
{
|
||||
$end = new \DateTime('yesterday');
|
||||
|
||||
$this->object->setEnd($end);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace Jsvrcek\ICS\Tests\Model;
|
||||
|
||||
use Jsvrcek\ICS\Model\Calendar;
|
||||
|
||||
/**
|
||||
* Generated by PHPUnit_SkeletonGenerator on 2013-10-20 at 15:24:14.
|
||||
*/
|
||||
class CalendarTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
/**
|
||||
* @covers Jsvrcek\ICS\Model\Calendar::__construct
|
||||
*/
|
||||
public function testConstruct()
|
||||
{
|
||||
$c = new Calendar();
|
||||
|
||||
//test defaults
|
||||
$this->assertEquals('America/New_York', $c->getTimezone()->getName());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,83 @@
|
||||
<?php
|
||||
|
||||
namespace Jsvrcek\ICS\Tests\Model\Recurrence;
|
||||
|
||||
use Jsvrcek\ICS\Model\Recurrence\DataType\Weekday;
|
||||
use Jsvrcek\ICS\Model\Recurrence\DataType\WeekdayNum;
|
||||
use Jsvrcek\ICS\Model\Recurrence\DataType\Frequency;
|
||||
|
||||
use Jsvrcek\ICS\Utility\Formatter;
|
||||
use Jsvrcek\ICS\Model\Recurrence\RecurrenceRule;
|
||||
|
||||
class RecurrenceRuleTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
/**
|
||||
* @var RecurrenceRule
|
||||
*/
|
||||
protected $object;
|
||||
|
||||
/**
|
||||
* Sets up the fixture, for example, opens a network connection.
|
||||
* This method is called before a test is executed.
|
||||
* @return Rule
|
||||
*/
|
||||
protected function setUp()
|
||||
{
|
||||
$this->object = new RecurrenceRule(new Formatter());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tears down the fixture, for example, closes a network connection.
|
||||
* This method is called after a test is executed.
|
||||
*/
|
||||
protected function tearDown()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers Jsvrcek\ICS\Model\Recurrence\RecurrentRule::__toString()
|
||||
*/
|
||||
public function testToString()
|
||||
{
|
||||
$this->object
|
||||
->setFrequency(new Frequency(Frequency::YEARLY))
|
||||
->setInterval(2)
|
||||
->setCount(10)
|
||||
->addByDay(new WeekdayNum(Weekday::MONDAY, 10, WeekdayNum::COUNT_FROM_START))
|
||||
->addByDay(new WeekdayNum(Weekday::TUESDAY, 10, WeekdayNum::COUNT_FROM_END))
|
||||
->setUntil(new \DateTime('2050-01-01 00:00:00', new \DateTimeZone('UTC')))
|
||||
;
|
||||
|
||||
$expected = 'RRULE:FREQ=YEARLY;INTERVAL=2;UNTIL=20500101T000000Z;COUNT=10;BYDAY=10MO,-10TU';
|
||||
|
||||
$this->assertEquals($expected, $this->object->__toString());
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers Jsvrcek\ICS\Model\Recurrence\RecurrentRule::parse()
|
||||
* @depends testToString
|
||||
*/
|
||||
public function testParse()
|
||||
{
|
||||
//reset instance
|
||||
$this->setUp();
|
||||
|
||||
$rRuleString = 'RRULE:FREQ=YEARLY;INTERVAL=2';
|
||||
$this->object->parse($rRuleString);
|
||||
$this->assertEquals($rRuleString, $this->object->__toString());
|
||||
|
||||
$rRuleString = 'RRULE:FREQ=WEEKLY;INTERVAL=4';
|
||||
$this->object->parse($rRuleString);
|
||||
$this->assertEquals($rRuleString, $this->object->__toString());
|
||||
|
||||
$rRuleString = 'RRULE:FREQ=WEEKLY;INTERVAL=4;UNTIL=20500101T000000Z';
|
||||
$this->object->parse($rRuleString);
|
||||
$this->assertEquals($rRuleString, $this->object->__toString());
|
||||
|
||||
/*
|
||||
$rRuleString = 'RRULE:FREQ=YEARLY;INTERVAL=2;COUNT=10;BYDAY=10MO,-10TU';
|
||||
$this->object->parse($rRuleString);
|
||||
$this->assertEquals($rRuleString, $this->object->__toString());
|
||||
*/
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
|
||||
namespace Jsvrcek\ICS\Tests\Model\Relationship;
|
||||
|
||||
use Jsvrcek\ICS\Utility\Formatter;
|
||||
use Jsvrcek\ICS\Model\Relationship\Attendee;
|
||||
|
||||
class AttendeeTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
/**
|
||||
* @var Attendee
|
||||
*/
|
||||
protected $object;
|
||||
|
||||
/**
|
||||
* Sets up the fixture, for example, opens a network connection.
|
||||
* This method is called before a test is executed.
|
||||
* @return Attendee
|
||||
*/
|
||||
protected function setUp()
|
||||
{
|
||||
$this->object = new Attendee(new Formatter());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tears down the fixture, for example, closes a network connection.
|
||||
* This method is called after a test is executed.
|
||||
*/
|
||||
protected function tearDown()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers Jsvrcek\ICS\Model\Attendee::__toString()
|
||||
*/
|
||||
public function testToString()
|
||||
{
|
||||
$this->object
|
||||
->setValue('joe-smith@example.com')
|
||||
->setName('Joe Smith')
|
||||
->setCalendarUserType('INDIVIDUAL')
|
||||
->addCalendarMember('list@example.com')
|
||||
->addDelegatedFrom('mary@example.com')
|
||||
->addDelegatedTo('sue@example.com')
|
||||
->addDelegatedTo('jane@example.com')
|
||||
->setParticipationStatus('ACCEPTED')
|
||||
->setRole('REQ-PARTICIPANT')
|
||||
->setRsvp('TRUE')
|
||||
->setSentBy('jack@example.com')
|
||||
->setLanguage('en');
|
||||
|
||||
$expected = 'ATTENDEE;CUTYPE=INDIVIDUAL;MEMBER="mailto:list@example.com";ROLE=REQ-PARTICIPANT;PARTSTAT=ACCEPTED;RSVP=TRUE;DELEGATED-TO="mailto:sue@example.com","mailto:jane@example.com";DELEGATED-FROM="mailto:mary@example.com";SENT-BY="jack@example.com";CN=Joe Smith;LANGUAGE=en:mailto:joe-smith@example.com';
|
||||
|
||||
$this->assertEquals($expected, $this->object->__toString());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
namespace Jsvrcek\ICS\Tests\Model\Relationship;
|
||||
|
||||
use Jsvrcek\ICS\Utility\Formatter;
|
||||
use Jsvrcek\ICS\Model\Relationship\Organizer;
|
||||
|
||||
class OrganizerTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
/**
|
||||
* @var Organizer
|
||||
*/
|
||||
protected $object;
|
||||
|
||||
/**
|
||||
* Sets up the fixture, for example, opens a network connection.
|
||||
* This method is called before a test is executed.
|
||||
* @return Organizer
|
||||
*/
|
||||
protected function setUp()
|
||||
{
|
||||
$this->object = new Organizer(new Formatter());
|
||||
}
|
||||
|
||||
/**
|
||||
* Tears down the fixture, for example, closes a network connection.
|
||||
* This method is called after a test is executed.
|
||||
*/
|
||||
protected function tearDown()
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers Jsvrcek\ICS\Model\Organizer::__toString()
|
||||
*/
|
||||
public function testToString()
|
||||
{
|
||||
$this->object
|
||||
->setValue('leonardo@example.it')
|
||||
->setName('Leonardo Da Vinci')
|
||||
->setLanguage('it')
|
||||
->setDirectory('http://en.wikipedia.org/wiki/Leonardo_da_Vinci')
|
||||
->setSentBy('piero@example.com');
|
||||
|
||||
$expected = 'ORGANIZER;SENT-BY="piero@example.com";CN=Leonardo Da Vinci;DIR="http://en.wikipedia.org/wiki/Leonardo_da_Vinci";LANGUAGE=it:mailto:leonardo@example.it';
|
||||
|
||||
$this->assertEquals($expected, $this->object->__toString());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
<?php
|
||||
|
||||
namespace Jsvrcek\ICS\Tests\Utility;
|
||||
|
||||
use Jsvrcek\ICS\Utility\Formatter;
|
||||
|
||||
class FormatterTest extends \PHPUnit_Framework_TestCase
|
||||
{
|
||||
/**
|
||||
* @covers Jsvrcek\ICS\Formatter::getFormattedDateTime
|
||||
*/
|
||||
public function testGetFormattedDateTime()
|
||||
{
|
||||
$ce = new Formatter();
|
||||
|
||||
$dateTime = new \DateTime('1998-01-18 23:00:00');
|
||||
$expected = '19980118T230000';
|
||||
$actual = $ce->getFormattedDateTime($dateTime);
|
||||
$this->assertEquals($expected, $actual);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers Jsvrcek\ICS\Formatter::getFormattedTimeOffset
|
||||
*/
|
||||
public function testGetFormattedTimeOffset()
|
||||
{
|
||||
$ce = new Formatter();
|
||||
|
||||
$offset = -18000;
|
||||
$expected = '-0500';
|
||||
$actual = $ce->getFormattedTimeOffset($offset);
|
||||
$this->assertEquals($expected, $actual);
|
||||
|
||||
$offset = -14400;
|
||||
$expected = '-0400';
|
||||
$actual = $ce->getFormattedTimeOffset($offset);
|
||||
$this->assertEquals($expected, $actual);
|
||||
|
||||
$offset = 14400;
|
||||
$expected = '+0400';
|
||||
$actual = $ce->getFormattedTimeOffset($offset);
|
||||
$this->assertEquals($expected, $actual);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers Jsvrcek\ICS\Formatter::getFormattedUTCDateTime
|
||||
*/
|
||||
public function testGetFormattedUTCDateTime()
|
||||
{
|
||||
$ce = new Formatter();
|
||||
|
||||
$dateTime = new \DateTime('1998-01-18 23:00:00', new \DateTimeZone('America/New_York'));
|
||||
$expected = '19980119T040000Z';
|
||||
$actual = $ce->getFormattedUTCDateTime($dateTime);
|
||||
$this->assertEquals($expected, $actual);
|
||||
$ce = new Formatter();
|
||||
|
||||
$dateTime = new \DateTime('1998-01-18 11:00:00', new \DateTimeZone('America/New_York'));
|
||||
$expected = '19980118T160000Z';
|
||||
$actual = $ce->getFormattedUTCDateTime($dateTime);
|
||||
$this->assertEquals($expected, $actual);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers Jsvrcek\ICS\Formatter::getFormattedUri
|
||||
*/
|
||||
public function testGetFormattedUri()
|
||||
{
|
||||
$ce = new Formatter();
|
||||
|
||||
$expected = 'mailto:test@example.com';
|
||||
$actual = $ce->getFormattedUri('test@example.com');
|
||||
$this->assertEquals($expected, $actual);
|
||||
}
|
||||
|
||||
/**
|
||||
* @covers Jsvrcek\ICS\Formatter::getFormattedDateInterval
|
||||
*/
|
||||
public function testGetFormattedDateInterval()
|
||||
{
|
||||
$ce = new Formatter();
|
||||
|
||||
$tests = array(
|
||||
"PT15M",
|
||||
"PT1H",
|
||||
"P345D",
|
||||
"P1Y6M29DT4H34M23S"
|
||||
);
|
||||
|
||||
foreach ($tests as $test) {
|
||||
$this->assertEquals(
|
||||
$test,
|
||||
$ce->getFormattedDateInterval(new \DateInterval($test)),
|
||||
$test
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
+97
@@ -0,0 +1,97 @@
|
||||
BEGIN:VCALENDAR
|
||||
VERSION:2.0
|
||||
PRODID:-//Jsvrcek//ICS//EN
|
||||
CALSCALE:GREGORIAN
|
||||
METHOD:PUBLISH
|
||||
BEGIN:VTIMEZONE
|
||||
TZID:Antarctica/McMurdo
|
||||
BEGIN:STANDARD
|
||||
DTSTART:19700101T000000
|
||||
TZOFFSETTO:+1200
|
||||
TZOFFSETFROM:+1200
|
||||
END:STANDARD
|
||||
END:VTIMEZONE
|
||||
BEGIN:VEVENT
|
||||
UID:lLKjd89283oja89282lkjd8@example.com
|
||||
DTSTART:20131004T120000
|
||||
DTEND:20131004T220000
|
||||
RRULE:FREQ=MONTHLY;INTERVAL=2;COUNT=40;BYDAY=1SA,2SA,3SA,4SA,1FR
|
||||
SEQUENCE:3
|
||||
STATUS:
|
||||
SUMMARY:Poker night at the South Pole
|
||||
DESCRIPTION:
|
||||
DTSTAMP:20130831T120000Z
|
||||
ATTENDEE;CUTYPE=INDIVIDUAL;MEMBER="mailto:list@example.com";ROLE=REQ-P
|
||||
ARTICIPANT;PARTSTAT=ACCEPTED;SENT-BY="joe@example";CN=Jane Smith:mailt
|
||||
o:jane-smith@example.com
|
||||
ORGANIZER;SENT-BY="mary@example.com";CN=Sue Jones;LANGUAGE=en:mailto:s
|
||||
ue@example.com
|
||||
BEGIN:VALARM
|
||||
TRIGGER;VALUE=DATE-TIME:20131003T230000Z
|
||||
ACTION:AUDIO
|
||||
ATTACH;FMTTYPE=audio/basic:ftp://example.com/pub/sounds/bell-01.aud
|
||||
END:VALARM
|
||||
BEGIN:VALARM
|
||||
TRIGGER;VALUE=DATE-TIME:20131003T230000Z
|
||||
ACTION:DISPLAY
|
||||
REPEAT:3
|
||||
DURATION:PT15M
|
||||
DESCRIPTION:DESCRIPTION
|
||||
END:VALARM
|
||||
BEGIN:VALARM
|
||||
TRIGGER;VALUE=DATE-TIME:20131003T230000Z
|
||||
ACTION:EMAIL
|
||||
SUMMARY:EMAIL SUBJECT
|
||||
DESCRIPTION:EMAIL BODY
|
||||
ATTENDEE;CUTYPE=INDIVIDUAL;MEMBER="mailto:list@example.com";ROLE=REQ-P
|
||||
ARTICIPANT;PARTSTAT=ACCEPTED;SENT-BY="joe@example";CN=Jane Smith:mailt
|
||||
o:jane-smith@example.com
|
||||
ATTACH;FMTTYPE=application/msword:http://example.com/agenda.docx
|
||||
ATTACH;FMTTYPE=application/pdf:http://example.com/agenda.pdf
|
||||
END:VALARM
|
||||
END:VEVENT
|
||||
BEGIN:VEVENT
|
||||
UID:eventtwo@example.com
|
||||
DTSTART:20131002T000000
|
||||
DTEND:20131002T003000
|
||||
RRULE:FREQ=WEEKLY
|
||||
EXDATE:20131016T000000
|
||||
EXDATE:20131030T000000
|
||||
STATUS:
|
||||
SUMMARY:Every Wednesday event
|
||||
DESCRIPTION:
|
||||
DTSTAMP:20130831T120000Z
|
||||
END:VEVENT
|
||||
END:VCALENDAR
|
||||
BEGIN:VCALENDAR
|
||||
VERSION:2.0
|
||||
PRODID:-//Jsvrcek//ICS//EN2
|
||||
CALSCALE:GREGORIAN
|
||||
METHOD:PUBLISH
|
||||
BEGIN:VTIMEZONE
|
||||
TZID:Arctic/Longyearbyen
|
||||
BEGIN:STANDARD
|
||||
DTSTART:19700101T000000
|
||||
TZOFFSETTO:+0100
|
||||
TZOFFSETFROM:+0100
|
||||
END:STANDARD
|
||||
END:VTIMEZONE
|
||||
BEGIN:VEVENT
|
||||
UID:asdfasdf@example.com
|
||||
DTSTART:20160101T010101
|
||||
DTEND:20160102T010101
|
||||
STATUS:
|
||||
SUMMARY:A long day
|
||||
DESCRIPTION:
|
||||
DTSTAMP:20130831T220000Z
|
||||
END:VEVENT
|
||||
BEGIN:VEVENT
|
||||
UID:asdfasdf@example.com
|
||||
DTSTART:20160102T010101
|
||||
DTEND:20160103T010101
|
||||
STATUS:
|
||||
SUMMARY:Another long day
|
||||
DESCRIPTION:
|
||||
DTSTAMP:20130831T220000Z
|
||||
END:VEVENT
|
||||
END:VCALENDAR
|
||||
Reference in new issue
Block a user