new ics lib
This commit is contained in:
parent
67b6a332f2
commit
f97daa514b
@ -4,5 +4,15 @@
|
|||||||
<content url="file://$MODULE_DIR$" />
|
<content url="file://$MODULE_DIR$" />
|
||||||
<orderEntry type="inheritedJdk" />
|
<orderEntry type="inheritedJdk" />
|
||||||
<orderEntry type="sourceFolder" forTests="false" />
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
<orderEntry type="module-library">
|
||||||
|
<library name="PHARS">
|
||||||
|
<CLASSES>
|
||||||
|
<root url="phar://$MODULE_DIR$/php/composer.phar" />
|
||||||
|
</CLASSES>
|
||||||
|
<SOURCES>
|
||||||
|
<root url="phar://$MODULE_DIR$/php/composer.phar" />
|
||||||
|
</SOURCES>
|
||||||
|
</library>
|
||||||
|
</orderEntry>
|
||||||
</component>
|
</component>
|
||||||
</module>
|
</module>
|
5
php/.gitignore
vendored
Normal file
5
php/.gitignore
vendored
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
composer.phar
|
||||||
|
.composer.lock
|
||||||
|
composer.lock
|
||||||
|
vendor
|
||||||
|
vendor/*
|
5
php/composer.json
Normal file
5
php/composer.json
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"require": {
|
||||||
|
"kigkonsult/icalcreator": "dev-master"
|
||||||
|
}
|
||||||
|
}
|
@ -1,9 +1,10 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* download.php, zarafa calender to ics im/exporter
|
* download.php, zarafa calendar to ics im/exporter
|
||||||
*
|
*
|
||||||
* Author: Christoph Haas <christoph.h@sprinternet.at>
|
* Author: Christoph Haas <christoph.h@sprinternet.at>
|
||||||
* Copyright (C) 2012-2014 Christoph Haas
|
* Copyright (C) 2012-2016 Christoph Haas
|
||||||
*
|
*
|
||||||
* This library is free software; you can redistribute it and/or
|
* This library is free software; you can redistribute it and/or
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
@ -20,25 +21,52 @@
|
|||||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
$basedir = $_GET["basedir"];
|
class DownloadHandler
|
||||||
$secid = $_GET["secid"];
|
{
|
||||||
$fileid = $_GET["fileid"];
|
/**
|
||||||
$realname = $_GET["realname"];
|
* Download the given vcf file.
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public static function doDownload()
|
||||||
|
{
|
||||||
|
if (isset($_GET["token"])) {
|
||||||
|
$token = $_GET["token"];
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
$secfile = $basedir . "/secid." . $secid;
|
if (isset($_GET["filename"])) {
|
||||||
$icsfile = $basedir . "/" . $fileid . "." . $secid;
|
$filename = $_GET["filename"];
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// if the secid file exists -> download!
|
// validate token
|
||||||
if(file_exists($secfile)) {
|
if (!ctype_alnum($token)) { // token is a md5 hash
|
||||||
@header("Last-Modified: " . @gmdate("D, d M Y H:i:s",time()) . " GMT");
|
return false;
|
||||||
@header("Content-type: text/calendar");
|
}
|
||||||
header("Content-Length: " . filesize($icsfile));
|
|
||||||
header("Content-Disposition: attachment; filename=" . $realname . ".ics");
|
|
||||||
|
|
||||||
//write ics
|
$file = PLUGIN_CALENDARIMPORTER_TMP_UPLOAD . "ics_" . $token . ".ics";
|
||||||
readfile($icsfile);
|
|
||||||
unlink($secfile);
|
if (!file_exists($file)) { // invalid token
|
||||||
unlink($icsfile);
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// set headers here
|
||||||
|
header('Content-Disposition: attachment; filename="' . $filename . '"');
|
||||||
|
|
||||||
|
// no caching
|
||||||
|
header('Expires: 0'); // set expiration time
|
||||||
|
header('Content-Description: File Transfer');
|
||||||
|
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
|
||||||
|
header('Content-Length: ' . filesize($file));
|
||||||
|
header('Content-Type: application/octet-stream');
|
||||||
|
header('Pragma: public');
|
||||||
|
flush();
|
||||||
|
|
||||||
|
// print the downloaded file
|
||||||
|
readfile($file);
|
||||||
|
ignore_user_abort(true);
|
||||||
|
unlink($file);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
?>
|
|
@ -1,64 +0,0 @@
|
|||||||
<?php
|
|
||||||
/*********************************************************************************/
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* A PHP implementation of rfc2445/rfc5545.
|
|
||||||
*
|
|
||||||
* @copyright Copyright (c) 2007-2015 Kjell-Inge Gustafsson, kigkonsult, All rights reserved
|
|
||||||
* @link http://kigkonsult.se/iCalcreator/index.php
|
|
||||||
* @license http://kigkonsult.se/downloads/dl.php?f=LGPL
|
|
||||||
* @package iCalcreator
|
|
||||||
* @version 2.22.1
|
|
||||||
*/
|
|
||||||
/**
|
|
||||||
* This library is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
|
||||||
* License as published by the Free Software Foundation; either
|
|
||||||
* version 2.1 of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This library is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
|
||||||
* License along with this library; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*/
|
|
||||||
/**
|
|
||||||
* iCalcreator.php
|
|
||||||
*
|
|
||||||
* iCalcreator (class) files includes
|
|
||||||
*
|
|
||||||
* @package icalcreator
|
|
||||||
* @copyright Copyright (c) 2007-2015 Kjell-Inge Gustafsson, kigkonsult, All rights reserved
|
|
||||||
* @since 2.22.1 - 2015-06-06
|
|
||||||
*/
|
|
||||||
/*********************************************************************************/
|
|
||||||
/**
|
|
||||||
* Do NOT remove or change version!!
|
|
||||||
*/
|
|
||||||
define( 'ICALCREATOR_VERSION', 'iCalcreator 2.22.1' );
|
|
||||||
/*********************************************************************************/
|
|
||||||
if( !defined( 'ICALCREATOR_LIB_DIR' ))
|
|
||||||
define( 'ICALCREATOR_LIB_DIR', __DIR__ . DIRECTORY_SEPARATOR . 'lib' . DIRECTORY_SEPARATOR );
|
|
||||||
/**
|
|
||||||
* iCalLoader
|
|
||||||
*
|
|
||||||
* load iCalcreator src and util classes
|
|
||||||
*
|
|
||||||
* @param string $class
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
function iCalLoader( $class ) {
|
|
||||||
$file = ICALCREATOR_LIB_DIR . $class . '.class.php';
|
|
||||||
if( file_exists( $file ))
|
|
||||||
include $file;
|
|
||||||
}
|
|
||||||
spl_autoload_register( 'iCalLoader' );
|
|
||||||
/**
|
|
||||||
* iCalcreator add-on functionality functions
|
|
||||||
*/
|
|
||||||
include ICALCREATOR_LIB_DIR . 'iCal.XML.inc.php';
|
|
||||||
include ICALCREATOR_LIB_DIR . 'iCal.vCard.inc.php';
|
|
||||||
include ICALCREATOR_LIB_DIR . 'iCal.tz.inc.php';
|
|
@ -1,751 +0,0 @@
|
|||||||
<?php
|
|
||||||
/**
|
|
||||||
* This PHP class should only read an iCal file (*.ics), parse it and return an
|
|
||||||
* array with its content.
|
|
||||||
*
|
|
||||||
* PHP Version 5
|
|
||||||
*
|
|
||||||
* @category Parser
|
|
||||||
* @package ics-parser
|
|
||||||
* @author Martin Thoma <info@martin-thoma.de>
|
|
||||||
* @license http://www.opensource.org/licenses/mit-license.php MIT License
|
|
||||||
* @link https://github.com/MartinThoma/ics-parser/
|
|
||||||
* @link https://github.com/johngrogg/ics-parser
|
|
||||||
* @version 1.0.3
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This is the ICal class
|
|
||||||
*
|
|
||||||
* @param {string} filename The name of the file which should be parsed
|
|
||||||
* @constructor
|
|
||||||
*/
|
|
||||||
class ICal
|
|
||||||
{
|
|
||||||
/* How many ToDos are in this iCal? */
|
|
||||||
public /** @type {int} */ $todo_count = 0;
|
|
||||||
|
|
||||||
/* How many events are in this iCal? */
|
|
||||||
public /** @type {int} */ $event_count = 0;
|
|
||||||
|
|
||||||
/* How many freebusy are in this iCal? */
|
|
||||||
public /** @type {int} */ $freebusy_count = 0;
|
|
||||||
|
|
||||||
/* The parsed calendar */
|
|
||||||
public /** @type {Array} */ $cal;
|
|
||||||
|
|
||||||
/* Which keyword has been added to cal at last? */
|
|
||||||
private /** @type {string} */ $last_keyword;
|
|
||||||
|
|
||||||
/* The value in years to use for indefinite, recurring events */
|
|
||||||
public /** @type {int} */ $default_span = 2;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates the iCal Object
|
|
||||||
*
|
|
||||||
* @param {mixed} $filename The path to the iCal-file or an array of lines from an iCal file
|
|
||||||
*
|
|
||||||
* @return Object The iCal Object
|
|
||||||
*/
|
|
||||||
public function __construct($filename=false)
|
|
||||||
{
|
|
||||||
if (!$filename) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (is_array($filename)) {
|
|
||||||
$lines = $filename;
|
|
||||||
} else {
|
|
||||||
$lines = file($filename, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->initLines($lines);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initializes lines from a URL
|
|
||||||
*
|
|
||||||
* @url {string} $url The url of the ical file to download and initialize. Unless you know what you're doing, it should begin with "http://"
|
|
||||||
*
|
|
||||||
* @return Object The iCal Object
|
|
||||||
*/
|
|
||||||
public function initURL($url)
|
|
||||||
{
|
|
||||||
$contents = file_get_contents($url);
|
|
||||||
|
|
||||||
$lines = explode("\n", $contents);
|
|
||||||
|
|
||||||
return $this->initLines($lines);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initializes lines from a string
|
|
||||||
*
|
|
||||||
* @param {string} $contents The contents of the ical file to initialize
|
|
||||||
*
|
|
||||||
* @return Object The iCal Object
|
|
||||||
*/
|
|
||||||
public function initString($contents)
|
|
||||||
{
|
|
||||||
$lines = explode("\n", $contents);
|
|
||||||
|
|
||||||
return $this->initLines($lines);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Initializes lines from file
|
|
||||||
*
|
|
||||||
* @param {array} $lines The lines to initialize
|
|
||||||
*
|
|
||||||
* @return Object The iCal Object
|
|
||||||
*/
|
|
||||||
public function initLines($lines)
|
|
||||||
{
|
|
||||||
if (stristr($lines[0], 'BEGIN:VCALENDAR') === false) {
|
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
foreach ($lines as $line) {
|
|
||||||
$line = rtrim($line); // Trim trailing whitespace
|
|
||||||
$add = $this->keyValueFromString($line);
|
|
||||||
|
|
||||||
if ($add === false) {
|
|
||||||
$this->addCalendarComponentWithKeyAndValue($component, false, $line);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
$keyword = $add[0];
|
|
||||||
$values = $add[1]; // Could be an array containing multiple values
|
|
||||||
|
|
||||||
if (!is_array($values)) {
|
|
||||||
if (!empty($values)) {
|
|
||||||
$values = array($values); // Make an array as not already
|
|
||||||
$blank_array = array(); // Empty placeholder array
|
|
||||||
array_push($values, $blank_array);
|
|
||||||
} else {
|
|
||||||
$values = array(); // Use blank array to ignore this line
|
|
||||||
}
|
|
||||||
} else if (empty($values[0])) {
|
|
||||||
$values = array(); // Use blank array to ignore this line
|
|
||||||
}
|
|
||||||
|
|
||||||
$values = array_reverse($values); // Reverse so that our array of properties is processed first
|
|
||||||
|
|
||||||
foreach ($values as $value) {
|
|
||||||
switch ($line) {
|
|
||||||
// http://www.kanzaki.com/docs/ical/vtodo.html
|
|
||||||
case 'BEGIN:VTODO':
|
|
||||||
$this->todo_count++;
|
|
||||||
$component = 'VTODO';
|
|
||||||
break;
|
|
||||||
|
|
||||||
// http://www.kanzaki.com/docs/ical/vevent.html
|
|
||||||
case 'BEGIN:VEVENT':
|
|
||||||
if (!is_array($value)) {
|
|
||||||
$this->event_count++;
|
|
||||||
}
|
|
||||||
$component = 'VEVENT';
|
|
||||||
break;
|
|
||||||
|
|
||||||
// http://www.kanzaki.com/docs/ical/vfreebusy.html
|
|
||||||
case 'BEGIN:VFREEBUSY':
|
|
||||||
$this->freebusy_count++;
|
|
||||||
$component = 'VFREEBUSY';
|
|
||||||
break;
|
|
||||||
|
|
||||||
// All other special strings
|
|
||||||
case 'BEGIN:VCALENDAR':
|
|
||||||
case 'BEGIN:DAYLIGHT':
|
|
||||||
// http://www.kanzaki.com/docs/ical/vtimezone.html
|
|
||||||
case 'BEGIN:VTIMEZONE':
|
|
||||||
case 'BEGIN:STANDARD':
|
|
||||||
case 'BEGIN:VALARM':
|
|
||||||
$component = $value;
|
|
||||||
break;
|
|
||||||
case 'END:VALARM':
|
|
||||||
case 'END:VTODO': // End special text - goto VCALENDAR key
|
|
||||||
case 'END:VEVENT':
|
|
||||||
case 'END:VFREEBUSY':
|
|
||||||
case 'END:VCALENDAR':
|
|
||||||
case 'END:DAYLIGHT':
|
|
||||||
case 'END:VTIMEZONE':
|
|
||||||
case 'END:STANDARD':
|
|
||||||
$component = 'VCALENDAR';
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
$this->addCalendarComponentWithKeyAndValue($component, $keyword, $value);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$this->process_recurrences();
|
|
||||||
return $this->cal;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add to $this->ical array one value and key.
|
|
||||||
*
|
|
||||||
* @param {string} $component This could be VTODO, VEVENT, VCALENDAR, ...
|
|
||||||
* @param {string} $keyword The keyword, for example DTSTART
|
|
||||||
* @param {string} $value The value, for example 20110105T090000Z
|
|
||||||
*
|
|
||||||
* @return {None}
|
|
||||||
*/
|
|
||||||
public function addCalendarComponentWithKeyAndValue($component, $keyword, $value)
|
|
||||||
{
|
|
||||||
if ($keyword == false) {
|
|
||||||
$keyword = $this->last_keyword;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch ($component) {
|
|
||||||
case 'VTODO':
|
|
||||||
$this->cal[$component][$this->todo_count - 1][$keyword] = $value;
|
|
||||||
break;
|
|
||||||
case 'VEVENT':
|
|
||||||
if (!isset($this->cal[$component][$this->event_count - 1][$keyword . '_array'])) {
|
|
||||||
$this->cal[$component][$this->event_count - 1][$keyword . '_array'] = array(); // Create array()
|
|
||||||
}
|
|
||||||
|
|
||||||
if (is_array($value)) {
|
|
||||||
array_push($this->cal[$component][$this->event_count - 1][$keyword . '_array'], $value); // Add array of properties to the end
|
|
||||||
} else {
|
|
||||||
if (!isset($this->cal[$component][$this->event_count - 1][$keyword])) {
|
|
||||||
$this->cal[$component][$this->event_count - 1][$keyword] = $value;
|
|
||||||
}
|
|
||||||
|
|
||||||
$this->cal[$component][$this->event_count - 1][$keyword . '_array'][] = $value;
|
|
||||||
|
|
||||||
// Glue back together for multi-line content
|
|
||||||
if ($this->cal[$component][$this->event_count - 1][$keyword] != $value) {
|
|
||||||
$ord = (isset($value[0])) ? ord($value[0]) : NULL; // First char
|
|
||||||
|
|
||||||
if (in_array($ord, array(9, 32))) { // Is space or tab?
|
|
||||||
$value = substr($value, 1); // Only trim the first character
|
|
||||||
}
|
|
||||||
|
|
||||||
if (is_array($this->cal[$component][$this->event_count - 1][$keyword . '_array'][1])) { // Account for multiple definitions of current keyword (e.g. ATTENDEE)
|
|
||||||
$this->cal[$component][$this->event_count - 1][$keyword] .= ';' . $value; // Concat value *with separator* as content spans multiple lines
|
|
||||||
} else {
|
|
||||||
if ($keyword === 'EXDATE') {
|
|
||||||
// This will give out a comma separated EXDATE string as per RFC2445
|
|
||||||
// Example: EXDATE:19960402T010000Z,19960403T010000Z,19960404T010000Z
|
|
||||||
// Usage: $event['EXDATE'] will print out 19960402T010000Z,19960403T010000Z,19960404T010000Z
|
|
||||||
$this->cal[$component][$this->event_count - 1][$keyword] .= ',' . $value;
|
|
||||||
} else {
|
|
||||||
// Concat value as content spans multiple lines
|
|
||||||
$this->cal[$component][$this->event_count - 1][$keyword] .= $value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'VFREEBUSY':
|
|
||||||
$this->cal[$component][$this->freebusy_count - 1][$keyword] = $value;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
$this->cal[$component][$keyword] = $value;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
$this->last_keyword = $keyword;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get a key-value pair of a string.
|
|
||||||
*
|
|
||||||
* @param {string} $text which is like "VCALENDAR:Begin" or "LOCATION:"
|
|
||||||
*
|
|
||||||
* @return {array} array("VCALENDAR", "Begin")
|
|
||||||
*/
|
|
||||||
public function keyValueFromString($text)
|
|
||||||
{
|
|
||||||
// Match colon separator outside of quoted substrings
|
|
||||||
// Fallback to nearest semicolon outside of quoted substrings, if colon cannot be found
|
|
||||||
// Do not try and match within the value paired with the keyword
|
|
||||||
preg_match('/(.*?)(?::(?=(?:[^"]*"[^"]*")*[^"]*$)|;(?=[^:]*$))([\w\W]*)/', htmlspecialchars($text, ENT_QUOTES, 'UTF-8'), $matches);
|
|
||||||
|
|
||||||
if (count($matches) == 0) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (preg_match('/^([A-Z-]+)([;][\w\W]*)?$/', $matches[1])) {
|
|
||||||
$matches = array_splice($matches, 1, 2); // Remove first match and re-align ordering
|
|
||||||
|
|
||||||
// Process properties
|
|
||||||
if (preg_match('/([A-Z-]+)[;]([\w\W]*)/', $matches[0], $properties)) {
|
|
||||||
array_shift($properties); // Remove first match
|
|
||||||
$matches[0] = $properties[0]; // Fix to ignore everything in keyword after a ; (e.g. Language, TZID, etc.)
|
|
||||||
array_shift($properties); // Repeat removing first match
|
|
||||||
|
|
||||||
$formatted = array();
|
|
||||||
foreach ($properties as $property) {
|
|
||||||
preg_match_all('~[^\r\n";]+(?:"[^"\\\]*(?:\\\.[^"\\\]*)*"[^\r\n";]*)*~', $property, $attributes); // Match semicolon separator outside of quoted substrings
|
|
||||||
$attributes = (sizeof($attributes) == 0) ? array($property) : reset($attributes); // Remove multi-dimensional array and use the first key
|
|
||||||
|
|
||||||
foreach ($attributes as $attribute) {
|
|
||||||
preg_match_all('~[^\r\n"=]+(?:"[^"\\\]*(?:\\\.[^"\\\]*)*"[^\r\n"=]*)*~', $attribute, $values); // Match equals sign separator outside of quoted substrings
|
|
||||||
$value = (sizeof($values) == 0) ? NULL : reset($values); // Remove multi-dimensional array and use the first key
|
|
||||||
|
|
||||||
if (is_array($value) && isset($value[1])) {
|
|
||||||
$formatted[$value[0]] = trim($value[1], '"'); // Remove double quotes from beginning and end only
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$properties[0] = $formatted; // Assign the keyword property information
|
|
||||||
|
|
||||||
array_unshift($properties, $matches[1]); // Add match to beginning of array
|
|
||||||
$matches[1] = $properties;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $matches;
|
|
||||||
} else {
|
|
||||||
return false; // Ignore this match
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return Unix timestamp from iCal date time format
|
|
||||||
*
|
|
||||||
* @param {string} $icalDate A Date in the format YYYYMMDD[T]HHMMSS[Z] or
|
|
||||||
* YYYYMMDD[T]HHMMSS
|
|
||||||
*
|
|
||||||
* @return {int}
|
|
||||||
*/
|
|
||||||
public static function iCalDateToUnixTimestamp($icalDate)
|
|
||||||
{
|
|
||||||
$icalDate = str_replace('T', '', $icalDate);
|
|
||||||
$icalDate = str_replace('Z', '', $icalDate);
|
|
||||||
|
|
||||||
$pattern = '/([0-9]{4})'; // 1: YYYY
|
|
||||||
$pattern .= '([0-9]{2})'; // 2: MM
|
|
||||||
$pattern .= '([0-9]{2})'; // 3: DD
|
|
||||||
$pattern .= '([0-9]{0,2})'; // 4: HH
|
|
||||||
$pattern .= '([0-9]{0,2})'; // 5: MM
|
|
||||||
$pattern .= '([0-9]{0,2})/'; // 6: SS
|
|
||||||
preg_match($pattern, $icalDate, $date);
|
|
||||||
|
|
||||||
// Unix timestamp can't represent dates before 1970
|
|
||||||
if ($date[1] <= 1970) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// Unix timestamps after 03:14:07 UTC 2038-01-19 might cause an overflow
|
|
||||||
// if 32 bit integers are used.
|
|
||||||
$timestamp = mktime((int)$date[4], (int)$date[5], (int)$date[6], (int)$date[2], (int)$date[3], (int)$date[1]);
|
|
||||||
return $timestamp;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Processes recurrences
|
|
||||||
*
|
|
||||||
* @author John Grogg <john.grogg@gmail.com>
|
|
||||||
* @return {array}
|
|
||||||
*/
|
|
||||||
public function process_recurrences()
|
|
||||||
{
|
|
||||||
$array = $this->cal;
|
|
||||||
$events = $array['VEVENT'];
|
|
||||||
if (empty($events))
|
|
||||||
return false;
|
|
||||||
foreach ($array['VEVENT'] as $anEvent) {
|
|
||||||
if (isset($anEvent['RRULE']) && $anEvent['RRULE'] != '') {
|
|
||||||
// Recurring event, parse RRULE and add appropriate duplicate events
|
|
||||||
$rrules = array();
|
|
||||||
$rrule_strings = explode(';', $anEvent['RRULE']);
|
|
||||||
foreach ($rrule_strings as $s) {
|
|
||||||
list($k, $v) = explode('=', $s);
|
|
||||||
$rrules[$k] = $v;
|
|
||||||
}
|
|
||||||
// Get frequency
|
|
||||||
$frequency = $rrules['FREQ'];
|
|
||||||
// Get Start timestamp
|
|
||||||
$start_timestamp = $this->iCalDateToUnixTimestamp($anEvent['DTSTART']);
|
|
||||||
$end_timestamp = $this->iCalDateToUnixTimestamp($anEvent['DTEND']);
|
|
||||||
$event_timestamp_offset = $end_timestamp - $start_timestamp;
|
|
||||||
// Get Interval
|
|
||||||
$interval = (isset($rrules['INTERVAL']) && $rrules['INTERVAL'] != '') ? $rrules['INTERVAL'] : 1;
|
|
||||||
|
|
||||||
if (in_array($frequency, array('MONTHLY', 'YEARLY')) && isset($rrules['BYDAY']) && $rrules['BYDAY'] != '') {
|
|
||||||
// Deal with BYDAY
|
|
||||||
$day_number = intval($rrules['BYDAY']);
|
|
||||||
if (empty($day_number)) { // Returns 0 when no number defined in BYDAY
|
|
||||||
if (!isset($rrules['BYSETPOS'])) {
|
|
||||||
$day_number = 1; // Set first as default
|
|
||||||
} else if (is_numeric($rrules['BYSETPOS'])) {
|
|
||||||
$day_number = $rrules['BYSETPOS'];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$day_number = ($day_number == -1) ? 6 : $day_number; // Override for our custom key (6 => 'last')
|
|
||||||
$week_day = substr($rrules['BYDAY'], -2);
|
|
||||||
$day_ordinals = array(1 => 'first', 2 => 'second', 3 => 'third', 4 => 'fourth', 5 => 'fifth', 6 => 'last');
|
|
||||||
$weekdays = array('SU' => 'sunday', 'MO' => 'monday', 'TU' => 'tuesday', 'WE' => 'wednesday', 'TH' => 'thursday', 'FR' => 'friday', 'SA' => 'saturday');
|
|
||||||
}
|
|
||||||
|
|
||||||
$until_default = date_create('now');
|
|
||||||
$until_default->modify($this->default_span . ' year');
|
|
||||||
$until_default->setTime(23, 59, 59); // End of the day
|
|
||||||
$until_default = date_format($until_default, 'Ymd\THis');
|
|
||||||
|
|
||||||
if (isset($rrules['UNTIL'])) {
|
|
||||||
// Get Until
|
|
||||||
$until = $this->iCalDateToUnixTimestamp($rrules['UNTIL']);
|
|
||||||
} else if (isset($rrules['COUNT'])) {
|
|
||||||
$frequency_conversion = array('DAILY' => 'day', 'WEEKLY' => 'week', 'MONTHLY' => 'month', 'YEARLY' => 'year');
|
|
||||||
$count_orig = (is_numeric($rrules['COUNT']) && $rrules['COUNT'] > 1) ? $rrules['COUNT'] : 0;
|
|
||||||
$count = ($count_orig - 1); // Remove one to exclude the occurrence that initialises the rule
|
|
||||||
$count += ($count > 0) ? $count * ($interval - 1) : 0;
|
|
||||||
$offset = "+$count " . $frequency_conversion[$frequency];
|
|
||||||
$until = strtotime($offset, $start_timestamp);
|
|
||||||
|
|
||||||
if (in_array($frequency, array('MONTHLY', 'YEARLY')) && isset($rrules['BYDAY']) && $rrules['BYDAY'] != '') {
|
|
||||||
$dtstart = date_create($anEvent['DTSTART']);
|
|
||||||
for ($i = 1; $i <= $count; $i++) {
|
|
||||||
$dtstart_clone = clone $dtstart;
|
|
||||||
$dtstart_clone->modify('next ' . $frequency_conversion[$frequency]);
|
|
||||||
$offset = "{$day_ordinals[$day_number]} {$weekdays[$week_day]} of " . $dtstart_clone->format('F Y H:i:01');
|
|
||||||
$dtstart->modify($offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Jumping X months forwards doesn't mean the end date will fall on the same day defined in BYDAY
|
|
||||||
// Use the largest of these to ensure we are going far enough in the future to capture our final end day
|
|
||||||
$until = max($until, $dtstart->format('U'));
|
|
||||||
}
|
|
||||||
|
|
||||||
unset($offset);
|
|
||||||
} else {
|
|
||||||
$until = $this->iCalDateToUnixTimestamp($until_default);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!isset($anEvent['EXDATE_array'])) {
|
|
||||||
$anEvent['EXDATE_array'] = array();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Decide how often to add events and do so
|
|
||||||
switch ($frequency) {
|
|
||||||
case 'DAILY':
|
|
||||||
// Simply add a new event each interval of days until UNTIL is reached
|
|
||||||
$offset = "+$interval day";
|
|
||||||
$recurring_timestamp = strtotime($offset, $start_timestamp);
|
|
||||||
|
|
||||||
while ($recurring_timestamp <= $until) {
|
|
||||||
// Add event
|
|
||||||
$anEvent['DTSTART'] = date('Ymd\THis', $recurring_timestamp);
|
|
||||||
$anEvent['DTEND'] = date('Ymd\THis', $recurring_timestamp + $event_timestamp_offset);
|
|
||||||
|
|
||||||
$search_date = $anEvent['DTSTART'];
|
|
||||||
$is_excluded = array_filter($anEvent['EXDATE_array'], function($val) use ($search_date) {
|
|
||||||
return is_string($val) && strpos($search_date, $val) === 0;
|
|
||||||
});
|
|
||||||
|
|
||||||
if (!$is_excluded) {
|
|
||||||
$events[] = $anEvent;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Move forwards
|
|
||||||
$recurring_timestamp = strtotime($offset, $recurring_timestamp);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'WEEKLY':
|
|
||||||
// Create offset
|
|
||||||
$offset = "+$interval week";
|
|
||||||
// Build list of days of week to add events
|
|
||||||
$weekdays = array('SU', 'MO', 'TU', 'WE', 'TH', 'FR', 'SA');
|
|
||||||
|
|
||||||
if (isset($rrules['BYDAY']) && $rrules['BYDAY'] != '') {
|
|
||||||
$bydays = explode(',', $rrules['BYDAY']);
|
|
||||||
} else {
|
|
||||||
$weekTemp = array('SU', 'MO', 'TU', 'WE', 'TH', 'FR', 'SA');
|
|
||||||
$findDay = $weekTemp[date('w', $start_timestamp)];
|
|
||||||
$bydays = array($findDay);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get timestamp of first day of start week
|
|
||||||
$week_recurring_timestamp = (date('w', $start_timestamp) == 0) ? $start_timestamp : strtotime('last Sunday ' . date('H:i:s', $start_timestamp), $start_timestamp);
|
|
||||||
|
|
||||||
// Step through weeks
|
|
||||||
while ($week_recurring_timestamp <= $until) {
|
|
||||||
// Add events for bydays
|
|
||||||
$day_recurring_timestamp = $week_recurring_timestamp;
|
|
||||||
|
|
||||||
foreach ($weekdays as $day) {
|
|
||||||
// Check if day should be added
|
|
||||||
|
|
||||||
if (in_array($day, $bydays) && $day_recurring_timestamp > $start_timestamp && $day_recurring_timestamp <= $until) {
|
|
||||||
// Add event to day
|
|
||||||
$anEvent['DTSTART'] = date('Ymd\THis', $day_recurring_timestamp);
|
|
||||||
$anEvent['DTEND'] = date('Ymd\THis', $day_recurring_timestamp + $event_timestamp_offset);
|
|
||||||
|
|
||||||
$search_date = $anEvent['DTSTART'];
|
|
||||||
$is_excluded = array_filter($anEvent['EXDATE_array'], function($val) use ($search_date) { return is_string($val) && strpos($search_date, $val) === 0; });
|
|
||||||
|
|
||||||
if (!$is_excluded) {
|
|
||||||
$events[] = $anEvent;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Move forwards a day
|
|
||||||
$day_recurring_timestamp = strtotime('+1 day', $day_recurring_timestamp);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Move forwards $interval weeks
|
|
||||||
$week_recurring_timestamp = strtotime($offset, $week_recurring_timestamp);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'MONTHLY':
|
|
||||||
// Create offset
|
|
||||||
$offset = "+$interval month";
|
|
||||||
$recurring_timestamp = strtotime($offset, $start_timestamp);
|
|
||||||
|
|
||||||
if (isset($rrules['BYMONTHDAY']) && $rrules['BYMONTHDAY'] != '') {
|
|
||||||
// Deal with BYMONTHDAY
|
|
||||||
$monthdays = explode(',', $rrules['BYMONTHDAY']);
|
|
||||||
|
|
||||||
while ($recurring_timestamp <= $until) {
|
|
||||||
foreach ($monthdays as $monthday) {
|
|
||||||
// Add event
|
|
||||||
$anEvent['DTSTART'] = date('Ym' . sprintf('%02d', $monthday) . '\THis', $recurring_timestamp);
|
|
||||||
$anEvent['DTEND'] = date('Ymd\THis', $this->iCalDateToUnixTimestamp($anEvent['DTSTART']) + $event_timestamp_offset);
|
|
||||||
|
|
||||||
$search_date = $anEvent['DTSTART'];
|
|
||||||
$is_excluded = array_filter($anEvent['EXDATE_array'], function($val) use ($search_date) { return is_string($val) && strpos($search_date, $val) === 0; });
|
|
||||||
|
|
||||||
if (!$is_excluded) {
|
|
||||||
$events[] = $anEvent;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Move forwards
|
|
||||||
$recurring_timestamp = strtotime($offset, $recurring_timestamp);
|
|
||||||
}
|
|
||||||
} else if (isset($rrules['BYDAY']) && $rrules['BYDAY'] != '') {
|
|
||||||
$start_time = date('His', $start_timestamp);
|
|
||||||
|
|
||||||
while ($recurring_timestamp <= $until) {
|
|
||||||
$event_start_desc = "{$day_ordinals[$day_number]} {$weekdays[$week_day]} of " . date('F Y H:i:s', $recurring_timestamp);
|
|
||||||
$event_start_timestamp = strtotime($event_start_desc);
|
|
||||||
|
|
||||||
if ($event_start_timestamp > $start_timestamp && $event_start_timestamp < $until) {
|
|
||||||
$anEvent['DTSTART'] = date('Ymd\T', $event_start_timestamp) . $start_time;
|
|
||||||
$anEvent['DTEND'] = date('Ymd\THis', $this->iCalDateToUnixTimestamp($anEvent['DTSTART']) + $event_timestamp_offset);
|
|
||||||
|
|
||||||
$search_date = $anEvent['DTSTART'];
|
|
||||||
$is_excluded = array_filter($anEvent['EXDATE_array'], function($val) use ($search_date) { return is_string($val) && strpos($search_date, $val) === 0; });
|
|
||||||
|
|
||||||
if (!$is_excluded) {
|
|
||||||
$events[] = $anEvent;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Move forwards
|
|
||||||
$recurring_timestamp = strtotime($offset, $recurring_timestamp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'YEARLY':
|
|
||||||
// Create offset
|
|
||||||
$offset = "+$interval year";
|
|
||||||
$recurring_timestamp = strtotime($offset, $start_timestamp);
|
|
||||||
$month_names = array(1 => 'January', 2 => 'February', 3 => 'March', 4 => 'April', 5 => 'May', 6 => 'June', 7 => 'July', 8 => 'August', 9 => 'September', 10 => 'October', 11 => 'November', 12 => 'December');
|
|
||||||
|
|
||||||
// Check if BYDAY rule exists
|
|
||||||
if (isset($rrules['BYDAY']) && $rrules['BYDAY'] != '') {
|
|
||||||
$start_time = date('His', $start_timestamp);
|
|
||||||
|
|
||||||
while ($recurring_timestamp <= $until) {
|
|
||||||
$event_start_desc = "{$day_ordinals[$day_number]} {$weekdays[$week_day]} of {$month_names[$rrules['BYMONTH']]} " . date('Y H:i:s', $recurring_timestamp);
|
|
||||||
$event_start_timestamp = strtotime($event_start_desc);
|
|
||||||
|
|
||||||
if ($event_start_timestamp > $start_timestamp && $event_start_timestamp < $until) {
|
|
||||||
$anEvent['DTSTART'] = date('Ymd\T', $event_start_timestamp) . $start_time;
|
|
||||||
$anEvent['DTEND'] = date('Ymd\THis', $this->iCalDateToUnixTimestamp($anEvent['DTSTART']) + $event_timestamp_offset);
|
|
||||||
|
|
||||||
$search_date = $anEvent['DTSTART'];
|
|
||||||
$is_excluded = array_filter($anEvent['EXDATE_array'], function($val) use ($search_date) { return is_string($val) && strpos($search_date, $val) === 0; });
|
|
||||||
|
|
||||||
if (!$is_excluded) {
|
|
||||||
$events[] = $anEvent;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Move forwards
|
|
||||||
$recurring_timestamp = strtotime($offset, $recurring_timestamp);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
$day = date('d', $start_timestamp);
|
|
||||||
$start_time = date('His', $start_timestamp);
|
|
||||||
|
|
||||||
// Step through years
|
|
||||||
while ($recurring_timestamp <= $until) {
|
|
||||||
// Add specific month dates
|
|
||||||
if (isset($rrules['BYMONTH']) && $rrules['BYMONTH'] != '') {
|
|
||||||
$event_start_desc = "$day {$month_names[$rrules['BYMONTH']]} " . date('Y H:i:s', $recurring_timestamp);
|
|
||||||
} else {
|
|
||||||
$event_start_desc = $day . date('F Y H:i:s', $recurring_timestamp);
|
|
||||||
}
|
|
||||||
|
|
||||||
$event_start_timestamp = strtotime($event_start_desc);
|
|
||||||
|
|
||||||
if ($event_start_timestamp > $start_timestamp && $event_start_timestamp < $until) {
|
|
||||||
$anEvent['DTSTART'] = date('Ymd\T', $event_start_timestamp) . $start_time;
|
|
||||||
$anEvent['DTEND'] = date('Ymd\THis', $this->iCalDateToUnixTimestamp($anEvent['DTSTART']) + $event_timestamp_offset);
|
|
||||||
|
|
||||||
$search_date = $anEvent['DTSTART'];
|
|
||||||
$is_excluded = array_filter($anEvent['EXDATE_array'], function($val) use ($search_date) { return is_string($val) && strpos($search_date, $val) === 0; });
|
|
||||||
|
|
||||||
if (!$is_excluded) {
|
|
||||||
$events[] = $anEvent;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Move forwards
|
|
||||||
$recurring_timestamp = strtotime($offset, $recurring_timestamp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
$events = (isset($count_orig) && sizeof($events) > $count_orig) ? array_slice($events, 0, $count_orig) : $events; // Ensure we abide by COUNT if defined
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$this->cal['VEVENT'] = $events;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns an array of arrays with all events. Every event is an associative
|
|
||||||
* array and each property is an element it.
|
|
||||||
*
|
|
||||||
* @return {array}
|
|
||||||
*/
|
|
||||||
public function events()
|
|
||||||
{
|
|
||||||
$array = $this->cal;
|
|
||||||
return $array['VEVENT'];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the calendar name
|
|
||||||
*
|
|
||||||
* @return {calendar name}
|
|
||||||
*/
|
|
||||||
public function calendarName()
|
|
||||||
{
|
|
||||||
return $this->cal['VCALENDAR']['X-WR-CALNAME'];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns the calendar description
|
|
||||||
*
|
|
||||||
* @return {calendar description}
|
|
||||||
*/
|
|
||||||
public function calendarDescription()
|
|
||||||
{
|
|
||||||
return $this->cal['VCALENDAR']['X-WR-CALDESC'];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns an array of arrays with all free/busy events. Every event is
|
|
||||||
* an associative array and each property is an element it.
|
|
||||||
*
|
|
||||||
* @return {array}
|
|
||||||
*/
|
|
||||||
public function freeBusyEvents()
|
|
||||||
{
|
|
||||||
$array = $this->cal;
|
|
||||||
return $array['VFREEBUSY'];
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a boolean value whether the current calendar has events or not
|
|
||||||
*
|
|
||||||
* @return {boolean}
|
|
||||||
*/
|
|
||||||
public function hasEvents()
|
|
||||||
{
|
|
||||||
return (count($this->events()) > 0) ? true : false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns false when the current calendar has no events in range, else the
|
|
||||||
* events.
|
|
||||||
*
|
|
||||||
* Note that this function makes use of a UNIX timestamp. This might be a
|
|
||||||
* problem on January the 29th, 2038.
|
|
||||||
* See http://en.wikipedia.org/wiki/Unix_time#Representing_the_number
|
|
||||||
*
|
|
||||||
* @param {boolean} $rangeStart Either true or false
|
|
||||||
* @param {boolean} $rangeEnd Either true or false
|
|
||||||
*
|
|
||||||
* @return {mixed}
|
|
||||||
*/
|
|
||||||
public function eventsFromRange($rangeStart = false, $rangeEnd = false)
|
|
||||||
{
|
|
||||||
$events = $this->sortEventsWithOrder($this->events(), SORT_ASC);
|
|
||||||
|
|
||||||
if (!$events) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
$extendedEvents = array();
|
|
||||||
|
|
||||||
if ($rangeStart === false) {
|
|
||||||
$rangeStart = new DateTime();
|
|
||||||
} else {
|
|
||||||
$rangeStart = new DateTime($rangeStart);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($rangeEnd === false or $rangeEnd <= 0) {
|
|
||||||
$rangeEnd = new DateTime('2038/01/18');
|
|
||||||
} else {
|
|
||||||
$rangeEnd = new DateTime($rangeEnd);
|
|
||||||
}
|
|
||||||
|
|
||||||
$rangeStart = $rangeStart->format('U');
|
|
||||||
$rangeEnd = $rangeEnd->format('U');
|
|
||||||
|
|
||||||
// Loop through all events by adding two new elements
|
|
||||||
foreach ($events as $anEvent) {
|
|
||||||
$timestamp = $this->iCalDateToUnixTimestamp($anEvent['DTSTART']);
|
|
||||||
if ($timestamp >= $rangeStart && $timestamp <= $rangeEnd) {
|
|
||||||
$extendedEvents[] = $anEvent;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $extendedEvents;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns a boolean value whether the current calendar has events or not
|
|
||||||
*
|
|
||||||
* @param {array} $events An array with events.
|
|
||||||
* @param {array} $sortOrder Either SORT_ASC, SORT_DESC, SORT_REGULAR,
|
|
||||||
* SORT_NUMERIC, SORT_STRING
|
|
||||||
*
|
|
||||||
* @return {boolean}
|
|
||||||
*/
|
|
||||||
public function sortEventsWithOrder($events, $sortOrder = SORT_ASC)
|
|
||||||
{
|
|
||||||
$extendedEvents = array();
|
|
||||||
|
|
||||||
// Loop through all events by adding two new elements
|
|
||||||
foreach ($events as $anEvent) {
|
|
||||||
if (!array_key_exists('UNIX_TIMESTAMP', $anEvent)) {
|
|
||||||
$anEvent['UNIX_TIMESTAMP'] = $this->iCalDateToUnixTimestamp($anEvent['DTSTART']);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!array_key_exists('REAL_DATETIME', $anEvent)) {
|
|
||||||
$anEvent['REAL_DATETIME'] = date('d.m.Y', $anEvent['UNIX_TIMESTAMP']);
|
|
||||||
}
|
|
||||||
|
|
||||||
$extendedEvents[] = $anEvent;
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach ($extendedEvents as $key => $value) {
|
|
||||||
$timestamp[$key] = $value['UNIX_TIMESTAMP'];
|
|
||||||
}
|
|
||||||
array_multisort($timestamp, $sortOrder, $extendedEvents);
|
|
||||||
|
|
||||||
return $extendedEvents;
|
|
||||||
}
|
|
||||||
}
|
|
File diff suppressed because it is too large
Load Diff
@ -1,897 +0,0 @@
|
|||||||
<?php
|
|
||||||
/*********************************************************************************/
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* iCalcreator, a PHP rfc2445/rfc5545 solution.
|
|
||||||
*
|
|
||||||
* @copyright Copyright (c) 2007-2015 Kjell-Inge Gustafsson, kigkonsult, All rights reserved
|
|
||||||
* @link http://kigkonsult.se/iCalcreator/index.php
|
|
||||||
* @license http://kigkonsult.se/downloads/dl.php?f=LGPL
|
|
||||||
* @package iCalcreator
|
|
||||||
* @version 2.22
|
|
||||||
*/
|
|
||||||
/**
|
|
||||||
* This library is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
|
||||||
* License as published by the Free Software Foundation; either
|
|
||||||
* version 2.1 of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This library is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
|
||||||
* License along with this library; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*/
|
|
||||||
/*********************************************************************************/
|
|
||||||
/* iCalcreator XML (rfc6321) helper functions */
|
|
||||||
/*********************************************************************************/
|
|
||||||
/**
|
|
||||||
* format iCal XML output, rfc6321, using PHP SimpleXMLElement
|
|
||||||
*
|
|
||||||
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
|
||||||
* @since 2.18.1 - 2013-08-18
|
|
||||||
* @param object $calendar iCalcreator vcalendar instance reference
|
|
||||||
* @uses ICALCREATOR_VERSION
|
|
||||||
* @uses vcalendar::getProperty()
|
|
||||||
* @uses _addXMLchild()
|
|
||||||
* @uses vcalendar::getConfig()
|
|
||||||
* @uses vcalendar::getComponent()
|
|
||||||
* @uses calendarComponent::$objName
|
|
||||||
* @uses calendarComponent::getProperty()
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
function iCal2XML( $calendar ) {
|
|
||||||
/** fix an SimpleXMLElement instance and create root element */
|
|
||||||
$xmlstr = '<?xml version="1.0" encoding="utf-8"?><icalendar xmlns="urn:ietf:params:xml:ns:icalendar-2.0">';
|
|
||||||
$xmlstr .= '<!-- created '.gmdate( 'Ymd\THis\Z' );
|
|
||||||
$xmlstr .= ' using kigkonsult.se '.ICALCREATOR_VERSION.' iCal2XMl (rfc6321) -->';
|
|
||||||
$xmlstr .= '</icalendar>';
|
|
||||||
$xml = new SimpleXMLElement( $xmlstr );
|
|
||||||
$vcalendar = $xml->addChild( 'vcalendar' );
|
|
||||||
/** fix calendar properties */
|
|
||||||
$properties = $vcalendar->addChild( 'properties' );
|
|
||||||
$calProps = array( 'version', 'prodid', 'calscale', 'method' );
|
|
||||||
foreach( $calProps as $calProp ) {
|
|
||||||
if( FALSE !== ( $content = $calendar->getProperty( $calProp )))
|
|
||||||
_addXMLchild( $properties, $calProp, 'text', $content );
|
|
||||||
}
|
|
||||||
while( FALSE !== ( $content = $calendar->getProperty( FALSE, FALSE, TRUE )))
|
|
||||||
_addXMLchild( $properties, $content[0], 'unknown', $content[1]['value'], $content[1]['params'] );
|
|
||||||
$langCal = $calendar->getConfig( 'language' );
|
|
||||||
/** prepare to fix components with properties */
|
|
||||||
$components = $vcalendar->addChild( 'components' );
|
|
||||||
/** fix component properties */
|
|
||||||
while( FALSE !== ( $component = $calendar->getComponent())) {
|
|
||||||
$compName = $component->objName;
|
|
||||||
$child = $components->addChild( $compName );
|
|
||||||
$properties = $child->addChild( 'properties' );
|
|
||||||
$langComp = $component->getConfig( 'language' );
|
|
||||||
$props = $component->getConfig( 'setPropertyNames' );
|
|
||||||
foreach( $props as $prop ) {
|
|
||||||
switch( strtolower( $prop )) {
|
|
||||||
case 'attach': // may occur multiple times, below
|
|
||||||
while( FALSE !== ( $content = $component->getProperty( $prop, FALSE, TRUE ))) {
|
|
||||||
$type = ( isset( $content['params']['VALUE'] ) && ( 'BINARY' == $content['params']['VALUE'] )) ? 'binary' : 'uri';
|
|
||||||
unset( $content['params']['VALUE'] );
|
|
||||||
_addXMLchild( $properties, $prop, $type, $content['value'], $content['params'] );
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'attendee':
|
|
||||||
while( FALSE !== ( $content = $component->getProperty( $prop, FALSE, TRUE ))) {
|
|
||||||
if( isset( $content['params']['CN'] ) && !isset( $content['params']['LANGUAGE'] )) {
|
|
||||||
if( $langComp )
|
|
||||||
$content['params']['LANGUAGE'] = $langComp;
|
|
||||||
elseif( $langCal )
|
|
||||||
$content['params']['LANGUAGE'] = $langCal;
|
|
||||||
}
|
|
||||||
_addXMLchild( $properties, $prop, 'cal-address', $content['value'], $content['params'] );
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'exdate':
|
|
||||||
while( FALSE !== ( $content = $component->getProperty( $prop, FALSE, TRUE ))) {
|
|
||||||
$type = ( isset( $content['params']['VALUE'] ) && ( 'DATE' == $content['params']['VALUE'] )) ? 'date' : 'date-time';
|
|
||||||
unset( $content['params']['VALUE'] );
|
|
||||||
_addXMLchild( $properties, $prop, $type, $content['value'], $content['params'] );
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'freebusy':
|
|
||||||
while( FALSE !== ( $content = $component->getProperty( $prop, FALSE, TRUE ))) {
|
|
||||||
if( is_array( $content ) && isset( $content['value']['fbtype'] )) {
|
|
||||||
$content['params']['FBTYPE'] = $content['value']['fbtype'];
|
|
||||||
unset( $content['value']['fbtype'] );
|
|
||||||
}
|
|
||||||
_addXMLchild( $properties, $prop, 'period', $content['value'], $content['params'] );
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'request-status':
|
|
||||||
while( FALSE !== ( $content = $component->getProperty( $prop, FALSE, TRUE ))) {
|
|
||||||
if( !isset( $content['params']['LANGUAGE'] )) {
|
|
||||||
if( $langComp )
|
|
||||||
$content['params']['LANGUAGE'] = $langComp;
|
|
||||||
elseif( $langCal )
|
|
||||||
$content['params']['LANGUAGE'] = $langCal;
|
|
||||||
}
|
|
||||||
_addXMLchild( $properties, $prop, 'rstatus', $content['value'], $content['params'] );
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'rdate':
|
|
||||||
while( FALSE !== ( $content = $component->getProperty( $prop, FALSE, TRUE ))) {
|
|
||||||
$type = 'date-time';
|
|
||||||
if( isset( $content['params']['VALUE'] )) {
|
|
||||||
if( 'DATE' == $content['params']['VALUE'] )
|
|
||||||
$type = 'date';
|
|
||||||
elseif( 'PERIOD' == $content['params']['VALUE'] )
|
|
||||||
$type = 'period';
|
|
||||||
}
|
|
||||||
unset( $content['params']['VALUE'] );
|
|
||||||
_addXMLchild( $properties, $prop, $type, $content['value'], $content['params'] );
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'categories':
|
|
||||||
case 'comment':
|
|
||||||
case 'contact':
|
|
||||||
case 'description':
|
|
||||||
case 'related-to':
|
|
||||||
case 'resources':
|
|
||||||
while( FALSE !== ( $content = $component->getProperty( $prop, FALSE, TRUE ))) {
|
|
||||||
if(( 'related-to' != $prop ) && !isset( $content['params']['LANGUAGE'] )) {
|
|
||||||
if( $langComp )
|
|
||||||
$content['params']['LANGUAGE'] = $langComp;
|
|
||||||
elseif( $langCal )
|
|
||||||
$content['params']['LANGUAGE'] = $langCal;
|
|
||||||
}
|
|
||||||
_addXMLchild( $properties, $prop, 'text', $content['value'], $content['params'] );
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'x-prop':
|
|
||||||
while( FALSE !== ( $content = $component->getProperty( $prop, FALSE, TRUE )))
|
|
||||||
_addXMLchild( $properties, $content[0], 'unknown', $content[1]['value'], $content[1]['params'] );
|
|
||||||
break;
|
|
||||||
case 'created': // single occurence below, if set
|
|
||||||
case 'completed':
|
|
||||||
case 'dtstamp':
|
|
||||||
case 'last-modified':
|
|
||||||
$utcDate = TRUE;
|
|
||||||
case 'dtstart':
|
|
||||||
case 'dtend':
|
|
||||||
case 'due':
|
|
||||||
case 'recurrence-id':
|
|
||||||
if( FALSE !== ( $content = $component->getProperty( $prop, FALSE, TRUE ))) {
|
|
||||||
$type = ( isset( $content['params']['VALUE'] ) && ( 'DATE' == $content['params']['VALUE'] )) ? 'date' : 'date-time';
|
|
||||||
unset( $content['params']['VALUE'] );
|
|
||||||
if(( isset( $content['params']['TZID'] ) && empty( $content['params']['TZID'] )) || @is_null( $content['params']['TZID'] ))
|
|
||||||
unset( $content['params']['TZID'] );
|
|
||||||
_addXMLchild( $properties, $prop, $type, $content['value'], $content['params'] );
|
|
||||||
}
|
|
||||||
unset( $utcDate );
|
|
||||||
break;
|
|
||||||
case 'duration':
|
|
||||||
if( FALSE !== ( $content = $component->getProperty( $prop, FALSE, TRUE )))
|
|
||||||
_addXMLchild( $properties, $prop, 'duration', $content['value'], $content['params'] );
|
|
||||||
break;
|
|
||||||
case 'exrule':
|
|
||||||
case 'rrule':
|
|
||||||
while( FALSE !== ( $content = $component->getProperty( $prop, FALSE, TRUE )))
|
|
||||||
_addXMLchild( $properties, $prop, 'recur', $content['value'], $content['params'] );
|
|
||||||
break;
|
|
||||||
case 'class':
|
|
||||||
case 'location':
|
|
||||||
case 'status':
|
|
||||||
case 'summary':
|
|
||||||
case 'transp':
|
|
||||||
case 'tzid':
|
|
||||||
case 'uid':
|
|
||||||
if( FALSE !== ( $content = $component->getProperty( $prop, FALSE, TRUE ))) {
|
|
||||||
if((( 'location' == $prop ) || ( 'summary' == $prop )) && !isset( $content['params']['LANGUAGE'] )) {
|
|
||||||
if( $langComp )
|
|
||||||
$content['params']['LANGUAGE'] = $langComp;
|
|
||||||
elseif( $langCal )
|
|
||||||
$content['params']['LANGUAGE'] = $langCal;
|
|
||||||
}
|
|
||||||
_addXMLchild( $properties, $prop, 'text', $content['value'], $content['params'] );
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'geo':
|
|
||||||
if( FALSE !== ( $content = $component->getProperty( $prop, FALSE, TRUE )))
|
|
||||||
_addXMLchild( $properties, $prop, 'geo', $content['value'], $content['params'] );
|
|
||||||
break;
|
|
||||||
case 'organizer':
|
|
||||||
if( FALSE !== ( $content = $component->getProperty( $prop, FALSE, TRUE ))) {
|
|
||||||
if( isset( $content['params']['CN'] ) && !isset( $content['params']['LANGUAGE'] )) {
|
|
||||||
if( $langComp )
|
|
||||||
$content['params']['LANGUAGE'] = $langComp;
|
|
||||||
elseif( $langCal )
|
|
||||||
$content['params']['LANGUAGE'] = $langCal;
|
|
||||||
}
|
|
||||||
_addXMLchild( $properties, $prop, 'cal-address', $content['value'], $content['params'] );
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'percent-complete':
|
|
||||||
case 'priority':
|
|
||||||
case 'sequence':
|
|
||||||
if( FALSE !== ( $content = $component->getProperty( $prop, FALSE, TRUE )))
|
|
||||||
_addXMLchild( $properties, $prop, 'integer', $content['value'], $content['params'] );
|
|
||||||
break;
|
|
||||||
case 'tzurl':
|
|
||||||
case 'url':
|
|
||||||
if( FALSE !== ( $content = $component->getProperty( $prop, FALSE, TRUE )))
|
|
||||||
_addXMLchild( $properties, $prop, 'uri', $content['value'], $content['params'] );
|
|
||||||
break;
|
|
||||||
} // end switch( $prop )
|
|
||||||
} // end foreach( $props as $prop )
|
|
||||||
/** fix subComponent properties, if any */
|
|
||||||
while( FALSE !== ( $subcomp = $component->getComponent())) {
|
|
||||||
$subCompName = $subcomp->objName;
|
|
||||||
$child2 = $child->addChild( $subCompName );
|
|
||||||
$properties = $child2->addChild( 'properties' );
|
|
||||||
$langComp = $subcomp->getConfig( 'language' );
|
|
||||||
$subCompProps = $subcomp->getConfig( 'setPropertyNames' );
|
|
||||||
foreach( $subCompProps as $prop ) {
|
|
||||||
switch( strtolower( $prop )) {
|
|
||||||
case 'attach': // may occur multiple times, below
|
|
||||||
while( FALSE !== ( $content = $subcomp->getProperty( $prop, FALSE, TRUE ))) {
|
|
||||||
$type = ( isset( $content['params']['VALUE'] ) && ( 'BINARY' == $content['params']['VALUE'] )) ? 'binary' : 'uri';
|
|
||||||
unset( $content['params']['VALUE'] );
|
|
||||||
_addXMLchild( $properties, $prop, $type, $content['value'], $content['params'] );
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'attendee':
|
|
||||||
while( FALSE !== ( $content = $subcomp->getProperty( $prop, FALSE, TRUE ))) {
|
|
||||||
if( isset( $content['params']['CN'] ) && !isset( $content['params']['LANGUAGE'] )) {
|
|
||||||
if( $langComp )
|
|
||||||
$content['params']['LANGUAGE'] = $langComp;
|
|
||||||
elseif( $langCal )
|
|
||||||
$content['params']['LANGUAGE'] = $langCal;
|
|
||||||
}
|
|
||||||
_addXMLchild( $properties, $prop, 'cal-address', $content['value'], $content['params'] );
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'comment':
|
|
||||||
case 'tzname':
|
|
||||||
while( FALSE !== ( $content = $subcomp->getProperty( $prop, FALSE, TRUE ))) {
|
|
||||||
if( !isset( $content['params']['LANGUAGE'] )) {
|
|
||||||
if( $langComp )
|
|
||||||
$content['params']['LANGUAGE'] = $langComp;
|
|
||||||
elseif( $langCal )
|
|
||||||
$content['params']['LANGUAGE'] = $langCal;
|
|
||||||
}
|
|
||||||
_addXMLchild( $properties, $prop, 'text', $content['value'], $content['params'] );
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'rdate':
|
|
||||||
while( FALSE !== ( $content = $subcomp->getProperty( $prop, FALSE, TRUE ))) {
|
|
||||||
$type = 'date-time';
|
|
||||||
if( isset( $content['params']['VALUE'] )) {
|
|
||||||
if( 'DATE' == $content['params']['VALUE'] )
|
|
||||||
$type = 'date';
|
|
||||||
elseif( 'PERIOD' == $content['params']['VALUE'] )
|
|
||||||
$type = 'period';
|
|
||||||
}
|
|
||||||
unset( $content['params']['VALUE'] );
|
|
||||||
_addXMLchild( $properties, $prop, $type, $content['value'], $content['params'] );
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'x-prop':
|
|
||||||
while( FALSE !== ( $content = $subcomp->getProperty( $prop, FALSE, TRUE )))
|
|
||||||
_addXMLchild( $properties, $content[0], 'unknown', $content[1]['value'], $content[1]['params'] );
|
|
||||||
break;
|
|
||||||
case 'action': // single occurence below, if set
|
|
||||||
case 'description':
|
|
||||||
case 'summary':
|
|
||||||
if( FALSE !== ( $content = $subcomp->getProperty( $prop, FALSE, TRUE ))) {
|
|
||||||
if(( 'action' != $prop ) && !isset( $content['params']['LANGUAGE'] )) {
|
|
||||||
if( $langComp )
|
|
||||||
$content['params']['LANGUAGE'] = $langComp;
|
|
||||||
elseif( $langCal )
|
|
||||||
$content['params']['LANGUAGE'] = $langCal;
|
|
||||||
}
|
|
||||||
_addXMLchild( $properties, $prop, 'text', $content['value'], $content['params'] );
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'dtstart':
|
|
||||||
if( FALSE !== ( $content = $subcomp->getProperty( $prop, FALSE, TRUE ))) {
|
|
||||||
unset( $content['value']['tz'], $content['params']['VALUE'] ); // always local time
|
|
||||||
_addXMLchild( $properties, $prop, 'date-time', $content['value'], $content['params'] );
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'duration':
|
|
||||||
if( FALSE !== ( $content = $subcomp->getProperty( $prop, FALSE, TRUE )))
|
|
||||||
_addXMLchild( $properties, $prop, 'duration', $content['value'], $content['params'] );
|
|
||||||
break;
|
|
||||||
case 'repeat':
|
|
||||||
if( FALSE !== ( $content = $subcomp->getProperty( $prop, FALSE, TRUE )))
|
|
||||||
_addXMLchild( $properties, $prop, 'integer', $content['value'], $content['params'] );
|
|
||||||
break;
|
|
||||||
case 'trigger':
|
|
||||||
if( FALSE !== ( $content = $subcomp->getProperty( $prop, FALSE, TRUE ))) {
|
|
||||||
if( isset( $content['value']['year'] ) &&
|
|
||||||
isset( $content['value']['month'] ) &&
|
|
||||||
isset( $content['value']['day'] ))
|
|
||||||
$type = 'date-time';
|
|
||||||
else {
|
|
||||||
$type = 'duration';
|
|
||||||
if( !isset( $content['value']['relatedStart'] ) || ( TRUE !== $content['value']['relatedStart'] ))
|
|
||||||
$content['params']['RELATED'] = 'END';
|
|
||||||
}
|
|
||||||
_addXMLchild( $properties, $prop, $type, $content['value'], $content['params'] );
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'tzoffsetto':
|
|
||||||
case 'tzoffsetfrom':
|
|
||||||
if( FALSE !== ( $content = $subcomp->getProperty( $prop, FALSE, TRUE )))
|
|
||||||
_addXMLchild( $properties, $prop, 'utc-offset', $content['value'], $content['params'] );
|
|
||||||
break;
|
|
||||||
case 'rrule':
|
|
||||||
while( FALSE !== ( $content = $subcomp->getProperty( $prop, FALSE, TRUE )))
|
|
||||||
_addXMLchild( $properties, $prop, 'recur', $content['value'], $content['params'] );
|
|
||||||
break;
|
|
||||||
} // switch( $prop )
|
|
||||||
} // end foreach( $subCompProps as $prop )
|
|
||||||
} // end while( FALSE !== ( $subcomp = $component->getComponent()))
|
|
||||||
} // end while( FALSE !== ( $component = $calendar->getComponent()))
|
|
||||||
return $xml->asXML();
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Add children to a SimpleXMLelement
|
|
||||||
*
|
|
||||||
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
|
||||||
* @since 2.18.10 - 2013-09-04
|
|
||||||
* @param object $parent reference to a SimpleXMLelement node
|
|
||||||
* @param string $name new element node name
|
|
||||||
* @param string $type content type, subelement(-s) name
|
|
||||||
* @param string $content new subelement content
|
|
||||||
* @param array $params new element 'attributes'
|
|
||||||
* @uses iCalUtilityFunctions::_duration2str()
|
|
||||||
* @uses iCalUtilityFunctions::_geo2str2()
|
|
||||||
* @uses iCalUtilityFunctions::$geoLatFmt
|
|
||||||
* @uses iCalUtilityFunctions::$geoLongFmt
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
function _addXMLchild( & $parent, $name, $type, $content, $params=array()) {
|
|
||||||
static $fmtYmd = '%04d-%02d-%02d';
|
|
||||||
static $fmtYmdHis = '%04d-%02d-%02dT%02d:%02d:%02d';
|
|
||||||
/** create new child node */
|
|
||||||
$name = strtolower( $name );
|
|
||||||
$child = $parent->addChild( $name );
|
|
||||||
if( !empty( $params )) {
|
|
||||||
$parameters = $child->addChild( 'parameters' );
|
|
||||||
foreach( $params as $param => $parVal ) {
|
|
||||||
if( 'VALUE' == $param )
|
|
||||||
continue;
|
|
||||||
$param = strtolower( $param );
|
|
||||||
if( 'x-' == substr( $param, 0, 2 )) {
|
|
||||||
$p1 = $parameters->addChild( $param );
|
|
||||||
$p2 = $p1->addChild( 'unknown', htmlspecialchars( $parVal ));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$p1 = $parameters->addChild( $param );
|
|
||||||
switch( $param ) {
|
|
||||||
case 'altrep':
|
|
||||||
case 'dir': $ptype = 'uri'; break;
|
|
||||||
case 'delegated-from':
|
|
||||||
case 'delegated-to':
|
|
||||||
case 'member':
|
|
||||||
case 'sent-by': $ptype = 'cal-address'; break;
|
|
||||||
case 'rsvp': $ptype = 'boolean'; break ;
|
|
||||||
default: $ptype = 'text'; break;
|
|
||||||
}
|
|
||||||
if( is_array( $parVal )) {
|
|
||||||
foreach( $parVal as $pV )
|
|
||||||
$p2 = $p1->addChild( $ptype, htmlspecialchars( $pV ));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
$p2 = $p1->addChild( $ptype, htmlspecialchars( $parVal ));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} // end if( !empty( $params ))
|
|
||||||
if(( empty( $content ) && ( '0' != $content )) || ( !is_array( $content) && ( '-' != substr( $content, 0, 1 ) && ( 0 > $content ))))
|
|
||||||
return;
|
|
||||||
/** store content */
|
|
||||||
switch( $type ) {
|
|
||||||
case 'binary':
|
|
||||||
$v = $child->addChild( $type, $content );
|
|
||||||
break;
|
|
||||||
case 'boolean':
|
|
||||||
break;
|
|
||||||
case 'cal-address':
|
|
||||||
$v = $child->addChild( $type, $content );
|
|
||||||
break;
|
|
||||||
case 'date':
|
|
||||||
if( array_key_exists( 'year', $content ))
|
|
||||||
$content = array( $content );
|
|
||||||
foreach( $content as $date ) {
|
|
||||||
$str = sprintf( $fmtYmd, (int) $date['year'], (int) $date['month'], (int) $date['day'] );
|
|
||||||
$v = $child->addChild( $type, $str );
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'date-time':
|
|
||||||
if( array_key_exists( 'year', $content ))
|
|
||||||
$content = array( $content );
|
|
||||||
foreach( $content as $dt ) {
|
|
||||||
if( !isset( $dt['hour'] )) $dt['hour'] = 0;
|
|
||||||
if( !isset( $dt['min'] )) $dt['min'] = 0;
|
|
||||||
if( !isset( $dt['sec'] )) $dt['sec'] = 0;
|
|
||||||
$str = sprintf( $fmtYmdHis, (int) $dt['year'], (int) $dt['month'], (int) $dt['day'], (int) $dt['hour'], (int) $dt['min'], (int) $dt['sec'] );
|
|
||||||
if( isset( $dt['tz'] ) && ( 'Z' == $dt['tz'] ))
|
|
||||||
$str .= 'Z';
|
|
||||||
$v = $child->addChild( $type, $str );
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'duration':
|
|
||||||
$output = (( 'trigger' == $name ) && ( FALSE !== $content['before'] )) ? '-' : '';
|
|
||||||
$v = $child->addChild( $type, $output.iCalUtilityFunctions::_duration2str( $content ) );
|
|
||||||
break;
|
|
||||||
case 'geo':
|
|
||||||
if( !empty( $content )) {
|
|
||||||
$v1 = $child->addChild( 'latitude', iCalUtilityFunctions::_geo2str2( $content['latitude'], iCalUtilityFunctions::$geoLatFmt ));
|
|
||||||
$v1 = $child->addChild( 'longitude', iCalUtilityFunctions::_geo2str2( $content['longitude'], iCalUtilityFunctions::$geoLongFmt ));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'integer':
|
|
||||||
$v = $child->addChild( $type, (string) $content );
|
|
||||||
break;
|
|
||||||
case 'period':
|
|
||||||
if( !is_array( $content ))
|
|
||||||
break;
|
|
||||||
foreach( $content as $period ) {
|
|
||||||
$v1 = $child->addChild( $type );
|
|
||||||
$str = sprintf( $fmtYmdHis, (int) $period[0]['year'], (int) $period[0]['month'], (int) $period[0]['day'], (int) $period[0]['hour'], (int) $period[0]['min'], (int) $period[0]['sec'] );
|
|
||||||
if( isset( $period[0]['tz'] ) && ( 'Z' == $period[0]['tz'] ))
|
|
||||||
$str .= 'Z';
|
|
||||||
$v2 = $v1->addChild( 'start', $str );
|
|
||||||
if( array_key_exists( 'year', $period[1] )) {
|
|
||||||
$str = sprintf( $fmtYmdHis, (int) $period[1]['year'], (int) $period[1]['month'], (int) $period[1]['day'], (int) $period[1]['hour'], (int) $period[1]['min'], (int) $period[1]['sec'] );
|
|
||||||
if( isset($period[1]['tz'] ) && ( 'Z' == $period[1]['tz'] ))
|
|
||||||
$str .= 'Z';
|
|
||||||
$v2 = $v1->addChild( 'end', $str );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
$v2 = $v1->addChild( 'duration', iCalUtilityFunctions::_duration2str( $period[1] ));
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'recur':
|
|
||||||
$content = array_change_key_case( $content );
|
|
||||||
foreach( $content as $rulelabel => $rulevalue ) {
|
|
||||||
switch( $rulelabel ) {
|
|
||||||
case 'until':
|
|
||||||
if( isset( $rulevalue['hour'] ))
|
|
||||||
$str = sprintf( $fmtYmdHis, (int) $rulevalue['year'], (int) $rulevalue['month'], (int) $rulevalue['day'], (int) $rulevalue['hour'], (int) $rulevalue['min'], (int) $rulevalue['sec'] ).'Z';
|
|
||||||
else
|
|
||||||
$str = sprintf( $fmtYmd, (int) $rulevalue['year'], (int) $rulevalue['month'], (int) $rulevalue['day'] );
|
|
||||||
$v = $child->addChild( $rulelabel, $str );
|
|
||||||
break;
|
|
||||||
case 'bysecond':
|
|
||||||
case 'byminute':
|
|
||||||
case 'byhour':
|
|
||||||
case 'bymonthday':
|
|
||||||
case 'byyearday':
|
|
||||||
case 'byweekno':
|
|
||||||
case 'bymonth':
|
|
||||||
case 'bysetpos': {
|
|
||||||
if( is_array( $rulevalue )) {
|
|
||||||
foreach( $rulevalue as $vix => $valuePart )
|
|
||||||
$v = $child->addChild( $rulelabel, $valuePart );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
$v = $child->addChild( $rulelabel, $rulevalue );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 'byday': {
|
|
||||||
if( isset( $rulevalue['DAY'] )) {
|
|
||||||
$str = ( isset( $rulevalue[0] )) ? $rulevalue[0] : '';
|
|
||||||
$str .= $rulevalue['DAY'];
|
|
||||||
$p = $child->addChild( $rulelabel, $str );
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
foreach( $rulevalue as $valuePart ) {
|
|
||||||
if( isset( $valuePart['DAY'] )) {
|
|
||||||
$str = ( isset( $valuePart[0] )) ? $valuePart[0] : '';
|
|
||||||
$str .= $valuePart['DAY'];
|
|
||||||
$p = $child->addChild( $rulelabel, $str );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
$p = $child->addChild( $rulelabel, $valuePart );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 'freq':
|
|
||||||
case 'count':
|
|
||||||
case 'interval':
|
|
||||||
case 'wkst':
|
|
||||||
default:
|
|
||||||
$p = $child->addChild( $rulelabel, $rulevalue );
|
|
||||||
break;
|
|
||||||
} // end switch( $rulelabel )
|
|
||||||
} // end foreach( $content as $rulelabel => $rulevalue )
|
|
||||||
break;
|
|
||||||
case 'rstatus':
|
|
||||||
$v = $child->addChild( 'code', number_format( (float) $content['statcode'], 2, '.', ''));
|
|
||||||
$v = $child->addChild( 'description', htmlspecialchars( $content['text'] ));
|
|
||||||
if( isset( $content['extdata'] ))
|
|
||||||
$v = $child->addChild( 'data', htmlspecialchars( $content['extdata'] ));
|
|
||||||
break;
|
|
||||||
case 'text':
|
|
||||||
if( !is_array( $content ))
|
|
||||||
$content = array( $content );
|
|
||||||
foreach( $content as $part )
|
|
||||||
$v = $child->addChild( $type, htmlspecialchars( $part ));
|
|
||||||
break;
|
|
||||||
case 'time':
|
|
||||||
break;
|
|
||||||
case 'uri':
|
|
||||||
$v = $child->addChild( $type, $content );
|
|
||||||
break;
|
|
||||||
case 'utc-offset':
|
|
||||||
if( in_array( substr( $content, 0, 1 ), array( '-', '+' ))) {
|
|
||||||
$str = substr( $content, 0, 1 );
|
|
||||||
$content = substr( $content, 1 );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
$str = '+';
|
|
||||||
$str .= substr( $content, 0, 2 ).':'.substr( $content, 2, 2 );
|
|
||||||
if( 4 < strlen( $content ))
|
|
||||||
$str .= ':'.substr( $content, 4 );
|
|
||||||
$v = $child->addChild( $type, $str );
|
|
||||||
break;
|
|
||||||
case 'unknown':
|
|
||||||
default:
|
|
||||||
if( is_array( $content ))
|
|
||||||
$content = implode( '', $content );
|
|
||||||
$v = $child->addChild( 'unknown', htmlspecialchars( $content ));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* parse xml file into iCalcreator instance
|
|
||||||
*
|
|
||||||
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
|
||||||
* @since 2.16.22 - 2013-06-18
|
|
||||||
* @param string $xmlfile
|
|
||||||
* @param array $iCalcfg iCalcreator config array (opt)
|
|
||||||
* @return mixediCalcreator instance or FALSE on error
|
|
||||||
*/
|
|
||||||
function XMLfile2iCal( $xmlfile, $iCalcfg=array()) {
|
|
||||||
if( FALSE === ( $xmlstr = file_get_contents( $xmlfile )))
|
|
||||||
return FALSE;
|
|
||||||
return xml2iCal( $xmlstr, $iCalcfg );
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* parse xml string into iCalcreator instance, alias of XML2iCal
|
|
||||||
*
|
|
||||||
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
|
||||||
* @since 2.16.22 - 2013-06-18
|
|
||||||
* @param string $xmlstr
|
|
||||||
* @param array $iCalcfg iCalcreator config array (opt)
|
|
||||||
* @return mixed iCalcreator instance or FALSE on error
|
|
||||||
*/
|
|
||||||
function XMLstr2iCal( $xmlstr, $iCalcfg=array()) {
|
|
||||||
return XML2iCal( $xmlstr, $iCalcfg);
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* parse xml string into iCalcreator instance
|
|
||||||
*
|
|
||||||
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
|
||||||
* @since 2.16.22 - 2013-06-20
|
|
||||||
* @param string $xmlstr
|
|
||||||
* @param array $iCalcfg iCalcreator config array (opt)
|
|
||||||
* @uses vcalendar::vcalendar()
|
|
||||||
* @uses XMLgetComps()
|
|
||||||
* @return mixed iCalcreator instance or FALSE on error
|
|
||||||
*/
|
|
||||||
function XML2iCal( $xmlstr, $iCalcfg=array()) {
|
|
||||||
$xmlstr = str_replace( array( "\r\n", "\n\r", "\n", "\r" ), '', $xmlstr );
|
|
||||||
$xml = XMLgetTagContent1( $xmlstr, 'vcalendar', $endIx );
|
|
||||||
$iCal = new vcalendar( $iCalcfg );
|
|
||||||
XMLgetComps( $iCal, $xmlstr );
|
|
||||||
unset( $xmlstr );
|
|
||||||
return $iCal;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* parse XML string into iCalcreator components
|
|
||||||
*
|
|
||||||
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
|
||||||
* @since 2.21.11 - 2015-03-21
|
|
||||||
* @param object $iCal iCalcreator vcalendar or component object instance
|
|
||||||
* @param string $xml
|
|
||||||
* @uses iCalUtilityFunctions::$allComps
|
|
||||||
* @uses XMLgetTagContent1()
|
|
||||||
* @uses XMLgetProps()
|
|
||||||
* @uses XMLgetTagContent2()
|
|
||||||
* @uses vcalendar::newComponent()
|
|
||||||
* @uses iCalUtilityFunctions::$allComps
|
|
||||||
* @uses XMLgetComps()
|
|
||||||
* @return object
|
|
||||||
*/
|
|
||||||
function XMLgetComps( $iCal, $xml ) {
|
|
||||||
$sx = 0;
|
|
||||||
while(( FALSE !== substr( $xml, ( $sx + 11 ), 1 )) &&
|
|
||||||
( '<properties>' != substr( $xml, $sx, 12 )) && ( '<components>' != substr( $xml, $sx, 12 )))
|
|
||||||
$sx += 1;
|
|
||||||
if( FALSE === substr( $xml, ( $sx + 11 ), 1 ))
|
|
||||||
return FALSE;
|
|
||||||
if( '<properties>' == substr( $xml, $sx, 12 )) {
|
|
||||||
$xml2 = XMLgetTagContent1( $xml, 'properties', $endIx );
|
|
||||||
XMLgetProps( $iCal, $xml2 );
|
|
||||||
$xml = substr( $xml, $endIx );
|
|
||||||
}
|
|
||||||
if( '<components>' == substr( $xml, 0, 12 ))
|
|
||||||
$xml = XMLgetTagContent1( $xml, 'components', $endIx );
|
|
||||||
while( ! empty( $xml )) {
|
|
||||||
$xml2 = XMLgetTagContent2( $xml, $tagName, $endIx );
|
|
||||||
if( in_array( strtolower( $tagName ), iCalUtilityFunctions::$allComps ) &&
|
|
||||||
( FALSE !== ( $subComp = $iCal->newComponent( $tagName ))))
|
|
||||||
XMLgetComps( $subComp, $xml2 );
|
|
||||||
$xml = substr( $xml, $endIx);
|
|
||||||
}
|
|
||||||
unset( $xml );
|
|
||||||
return $iCal;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* parse XML into iCalcreator properties
|
|
||||||
*
|
|
||||||
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
|
||||||
* @since 2.21.11 - 2015-03-21
|
|
||||||
* @param array $iCal iCalcreator calendar/component instance
|
|
||||||
* @param string $xml
|
|
||||||
* @uses XMLgetTagContent2()
|
|
||||||
* @uses vcalendar::setProperty()
|
|
||||||
* @uses calendarComponent::setproperty()
|
|
||||||
* @uses XMLgetTagContent1()
|
|
||||||
* @uses vcalendar::setProperty()
|
|
||||||
* @return void
|
|
||||||
*/
|
|
||||||
function XMLgetProps( $iCal, $xml) {
|
|
||||||
while( ! empty( $xml )) {
|
|
||||||
$xml2 = XMLgetTagContent2( $xml, $propName, $endIx );
|
|
||||||
$propName = strtoupper( $propName );
|
|
||||||
if( empty( $xml2 ) && ( '0' != $xml2 )) {
|
|
||||||
$iCal->setProperty( $propName );
|
|
||||||
$xml = substr( $xml, $endIx);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
$params = array();
|
|
||||||
if( '<parameters/>' == substr( $xml2, 0, 13 ))
|
|
||||||
$xml2 = substr( $xml2, 13 );
|
|
||||||
elseif( '<parameters>' == substr( $xml2, 0, 12 )) {
|
|
||||||
$xml3 = XMLgetTagContent1( $xml2, 'parameters', $endIx2 );
|
|
||||||
while( ! empty( $xml3 )) {
|
|
||||||
$xml4 = XMLgetTagContent2( $xml3, $paramKey, $endIx3 );
|
|
||||||
$pType = FALSE; // skip parameter valueType
|
|
||||||
$paramKey = strtoupper( $paramKey );
|
|
||||||
static $mParams = array( 'DELEGATED-FROM', 'DELEGATED-TO', 'MEMBER' );
|
|
||||||
if( in_array( $paramKey, $mParams )) {
|
|
||||||
while( ! empty( $xml4 )) {
|
|
||||||
if( ! isset( $params[$paramKey] ))
|
|
||||||
$params[$paramKey] = array( XMLgetTagContent1( $xml4, 'cal-address', $endIx4 ));
|
|
||||||
else
|
|
||||||
$params[$paramKey][] = XMLgetTagContent1( $xml4, 'cal-address', $endIx4 );
|
|
||||||
$xml4 = substr( $xml4, $endIx4 );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if( ! isset( $params[$paramKey] ))
|
|
||||||
$params[$paramKey] = html_entity_decode( XMLgetTagContent2( $xml4, $pType, $endIx4 ));
|
|
||||||
else
|
|
||||||
$params[$paramKey] .= ','.html_entity_decode( XMLgetTagContent2( $xml4, $pType, $endIx4 ));
|
|
||||||
}
|
|
||||||
$xml3 = substr( $xml3, $endIx3 );
|
|
||||||
}
|
|
||||||
$xml2 = substr( $xml2, $endIx2 );
|
|
||||||
} // if( '<parameters>' == substr( $xml2, 0, 12 ))
|
|
||||||
$valueType = FALSE;
|
|
||||||
$value = ( ! empty( $xml2 ) || ( '0' == $xml2 )) ? XMLgetTagContent2( $xml2, $valueType, $endIx3 ) : '';
|
|
||||||
switch( $propName ) {
|
|
||||||
case 'CATEGORIES':
|
|
||||||
case 'RESOURCES':
|
|
||||||
$tValue = array();
|
|
||||||
while( ! empty( $xml2 )) {
|
|
||||||
$tValue[] = html_entity_decode( XMLgetTagContent2( $xml2, $valueType, $endIx4 ));
|
|
||||||
$xml2 = substr( $xml2, $endIx4 );
|
|
||||||
}
|
|
||||||
$value = $tValue;
|
|
||||||
break;
|
|
||||||
case 'EXDATE': // multiple single-date(-times) may exist
|
|
||||||
case 'RDATE':
|
|
||||||
if( 'period' != $valueType ) {
|
|
||||||
if( 'date' == $valueType )
|
|
||||||
$params['VALUE'] = 'DATE';
|
|
||||||
$t = array();
|
|
||||||
while( ! empty( $xml2 ) && ( '<date' == substr( $xml2, 0, 5 ))) {
|
|
||||||
$t[] = XMLgetTagContent2( $xml2, $pType, $endIx4 );
|
|
||||||
$xml2 = substr( $xml2, $endIx4 );
|
|
||||||
}
|
|
||||||
$value = $t;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case 'FREEBUSY':
|
|
||||||
if( 'RDATE' == $propName )
|
|
||||||
$params['VALUE'] = 'PERIOD';
|
|
||||||
$value = array();
|
|
||||||
while( ! empty( $xml2 ) && ( '<period>' == substr( $xml2, 0, 8 ))) {
|
|
||||||
$xml3 = XMLgetTagContent1( $xml2, 'period', $endIx4 ); // period
|
|
||||||
$t = array();
|
|
||||||
while( ! empty( $xml3 )) {
|
|
||||||
$t[] = XMLgetTagContent2( $xml3, $pType, $endIx5 ); // start - end/duration
|
|
||||||
$xml3 = substr( $xml3, $endIx5 );
|
|
||||||
}
|
|
||||||
$value[] = $t;
|
|
||||||
$xml2 = substr( $xml2, $endIx4 );
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case 'TZOFFSETTO':
|
|
||||||
case 'TZOFFSETFROM':
|
|
||||||
$value = str_replace( ':', '', $value );
|
|
||||||
break;
|
|
||||||
case 'GEO':
|
|
||||||
$tValue = array( 'latitude' => $value );
|
|
||||||
$tValue['longitude'] = XMLgetTagContent1( substr( $xml2, $endIx3 ), 'longitude', $endIx3 );
|
|
||||||
$value = $tValue;
|
|
||||||
break;
|
|
||||||
case 'EXRULE':
|
|
||||||
case 'RRULE':
|
|
||||||
$tValue = array( $valueType => $value );
|
|
||||||
$xml2 = substr( $xml2, $endIx3 );
|
|
||||||
$valueType = FALSE;
|
|
||||||
while( ! empty( $xml2 )) {
|
|
||||||
$t = XMLgetTagContent2( $xml2, $valueType, $endIx4 );
|
|
||||||
switch( $valueType ) {
|
|
||||||
case 'freq':
|
|
||||||
case 'count':
|
|
||||||
case 'until':
|
|
||||||
case 'interval':
|
|
||||||
case 'wkst':
|
|
||||||
$tValue[$valueType] = $t;
|
|
||||||
break;
|
|
||||||
case 'byday':
|
|
||||||
if( 2 == strlen( $t ))
|
|
||||||
$tValue[$valueType][] = array( 'DAY' => $t );
|
|
||||||
else {
|
|
||||||
$day = substr( $t, -2 );
|
|
||||||
$key = substr( $t, 0, ( strlen( $t ) - 2 ));
|
|
||||||
$tValue[$valueType][] = array( $key, 'DAY' => $day );
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
$tValue[$valueType][] = $t;
|
|
||||||
}
|
|
||||||
$xml2 = substr( $xml2, $endIx4 );
|
|
||||||
}
|
|
||||||
$value = $tValue;
|
|
||||||
break;
|
|
||||||
case 'REQUEST-STATUS':
|
|
||||||
$tValue = array();
|
|
||||||
while( ! empty( $xml2 )) {
|
|
||||||
$t = html_entity_decode( XMLgetTagContent2( $xml2, $valueType, $endIx4 ));
|
|
||||||
$tValue[$valueType] = $t;
|
|
||||||
$xml2 = substr( $xml2, $endIx4 );
|
|
||||||
}
|
|
||||||
if( ! empty( $tValue ))
|
|
||||||
$value = $tValue;
|
|
||||||
else
|
|
||||||
$value = array( 'code' => null, 'description' => null );
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
switch( $valueType ) {
|
|
||||||
case 'binary': $params['VALUE'] = 'BINARY'; break;
|
|
||||||
case 'date': $params['VALUE'] = 'DATE'; break;
|
|
||||||
case 'date-time': $params['VALUE'] = 'DATE-TIME'; break;
|
|
||||||
case 'text':
|
|
||||||
case 'unknown': $value = html_entity_decode( $value ); break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
} // end switch( $propName )
|
|
||||||
if( 'FREEBUSY' == $propName ) {
|
|
||||||
$fbtype = $params['FBTYPE'];
|
|
||||||
unset( $params['FBTYPE'] );
|
|
||||||
$iCal->setProperty( $propName, $fbtype, $value, $params );
|
|
||||||
}
|
|
||||||
elseif( 'GEO' == $propName )
|
|
||||||
$iCal->setProperty( $propName, $value['latitude'], $value['longitude'], $params );
|
|
||||||
elseif( 'REQUEST-STATUS' == $propName ) {
|
|
||||||
if( !isset( $value['data'] ))
|
|
||||||
$value['data'] = FALSE;
|
|
||||||
$iCal->setProperty( $propName, $value['code'], $value['description'], $value['data'], $params );
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if( empty( $value ) && ( is_array( $value ) || ( '0' > $value )))
|
|
||||||
$value = '';
|
|
||||||
$iCal->setProperty( $propName, $value, $params );
|
|
||||||
}
|
|
||||||
$xml = substr( $xml, $endIx);
|
|
||||||
} // end while( ! empty( $xml ))
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* fetch a specific XML tag content
|
|
||||||
*
|
|
||||||
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
|
||||||
* @since 2.16.22 - 2013-06-20
|
|
||||||
* @param string $xml
|
|
||||||
* @param string $tagName
|
|
||||||
* @param int $endIx
|
|
||||||
* @return mixed
|
|
||||||
*/
|
|
||||||
function XMLgetTagContent1( $xml, $tagName, & $endIx=0 ) {
|
|
||||||
$strlen = strlen( $tagName );
|
|
||||||
$sx1 = 0;
|
|
||||||
while( FALSE !== substr( $xml, $sx1, 1 )) {
|
|
||||||
if(( FALSE !== substr( $xml, ( $sx1 + $strlen + 1 ), 1 )) &&
|
|
||||||
( strtolower( "<$tagName>" ) == strtolower( substr( $xml, $sx1, ( $strlen + 2 )))))
|
|
||||||
break;
|
|
||||||
if(( FALSE !== substr( $xml, ( $sx1 + $strlen + 3 ), 1 )) &&
|
|
||||||
( strtolower( "<$tagName />" ) == strtolower( substr( $xml, $sx1, ( $strlen + 4 ))))) { // empty tag
|
|
||||||
$endIx = $strlen + 5;
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
if(( FALSE !== substr( $xml, ( $sx1 + $strlen + 2 ), 1 )) &&
|
|
||||||
( strtolower( "<$tagName/>" ) == strtolower( substr( $xml, $sx1, ( $strlen + 3 ))))) { // empty tag
|
|
||||||
$endIx = $strlen + 4;
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
$sx1 += 1;
|
|
||||||
}
|
|
||||||
if( FALSE === substr( $xml, $sx1, 1 )) {
|
|
||||||
$endIx = ( empty( $sx )) ? 0 : $sx - 1;
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
if( FALSE === ( $pos = stripos( $xml, "</$tagName>" ))) { // missing end tag??
|
|
||||||
$endIx = strlen( $xml ) + 1;
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
$endIx = $pos + $strlen + 3;
|
|
||||||
return substr( $xml, ( $sx1 + $strlen + 2 ), ( $pos - $sx1 - 2 - $strlen ));
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* fetch next (unknown) XML tagname AND content
|
|
||||||
*
|
|
||||||
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
|
||||||
* @since 2.16.22 - 2013-06-20
|
|
||||||
* @param string $xml
|
|
||||||
* @param string $tagName
|
|
||||||
* @param int $endIx
|
|
||||||
* @return mixed
|
|
||||||
*/
|
|
||||||
function XMLgetTagContent2( $xml, & $tagName, & $endIx ) {
|
|
||||||
$endIx = strlen( $xml ) + 1; // just in case.. .
|
|
||||||
$sx1 = 0;
|
|
||||||
while( FALSE !== substr( $xml, $sx1, 1 )) {
|
|
||||||
if( '<' == substr( $xml, $sx1, 1 )) {
|
|
||||||
if(( FALSE !== substr( $xml, ( $sx1 + 3 ), 1 )) && ( '<!--' == substr( $xml, $sx1, 4 ))) // skip comment
|
|
||||||
$sx1 += 1;
|
|
||||||
else
|
|
||||||
break; // tagname start here
|
|
||||||
}
|
|
||||||
else
|
|
||||||
$sx1 += 1;
|
|
||||||
}
|
|
||||||
$sx2 = $sx1;
|
|
||||||
while( FALSE !== substr( $xml, $sx2 )) {
|
|
||||||
if(( FALSE !== substr( $xml, ( $sx2 + 1 ), 1 )) && ( '/>' == substr( $xml, $sx2, 2 ))) { // empty tag
|
|
||||||
$tagName = trim( substr( $xml, ( $sx1 + 1 ), ( $sx2 - $sx1 - 1 )));
|
|
||||||
$endIx = $sx2 + 2;
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
if( '>' == substr( $xml, $sx2, 1 )) // tagname ends here
|
|
||||||
break;
|
|
||||||
$sx2 += 1;
|
|
||||||
}
|
|
||||||
$tagName = substr( $xml, ( $sx1 + 1 ), ( $sx2 - $sx1 - 1 ));
|
|
||||||
$endIx = $sx2 + 1;
|
|
||||||
if( FALSE === substr( $xml, $sx2, 1 )) {
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
$strlen = strlen( $tagName );
|
|
||||||
if(( 'duration' == $tagName ) &&
|
|
||||||
( FALSE !== ( $pos1 = stripos( $xml, "<duration>", $sx1+1 ))) &&
|
|
||||||
( FALSE !== ( $pos2 = stripos( $xml, "</duration>", $pos1+1 ))) &&
|
|
||||||
( FALSE !== ( $pos3 = stripos( $xml, "</duration>", $pos2+1 ))) &&
|
|
||||||
( $pos1 < $pos2 ) && ( $pos2 < $pos3 ))
|
|
||||||
$pos = $pos3;
|
|
||||||
elseif( FALSE === ( $pos = stripos( $xml, "</$tagName>", $sx2 )))
|
|
||||||
return '';
|
|
||||||
$endIx = $pos + $strlen + 3;
|
|
||||||
return substr( $xml, ( $sx1 + $strlen + 2 ), ( $pos - $strlen - 2 ));
|
|
||||||
}
|
|
@ -1,292 +0,0 @@
|
|||||||
<?php
|
|
||||||
/*********************************************************************************/
|
|
||||||
/* Additional functions to use with vtimezone components */
|
|
||||||
/*********************************************************************************/
|
|
||||||
/**
|
|
||||||
* For use with
|
|
||||||
* iCalcreator (kigkonsult.se/iCalcreator/index.php)
|
|
||||||
* copyright (c) 2011 Yitzchok Lavi
|
|
||||||
* icalcreator@onebigsystem.com
|
|
||||||
* @version 2.22
|
|
||||||
*
|
|
||||||
* This library is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
|
||||||
* License as published by the Free Software Foundation; either
|
|
||||||
* version 2.1 of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This library is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
|
||||||
* License along with this library; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*/
|
|
||||||
/**
|
|
||||||
* Additional functions to use with vtimezone components
|
|
||||||
*
|
|
||||||
* Before calling the functions, set time zone 'GMT' ('date_default_timezone_set')!
|
|
||||||
*
|
|
||||||
* @author Yitzchok Lavi <icalcreator@onebigsystem.com>
|
|
||||||
* adjusted for iCalcreator Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
|
||||||
* @version 1.0.2 - 2011-02-24
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
/**
|
|
||||||
* Returns array with the offset information from UTC for a (UTC) datetime/timestamp in the
|
|
||||||
* timezone, according to the VTIMEZONE information in the input array.
|
|
||||||
*
|
|
||||||
* @param array $timezonesarray output from function getTimezonesAsDateArrays (below)
|
|
||||||
* @param string $tzid time zone identifier
|
|
||||||
* @param mixed $timestamp timestamp or a UTC datetime (in array format)
|
|
||||||
* @return array time zone data with keys for 'offsetHis', 'offsetSec' and 'tzname'
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
function getTzOffsetForDate($timezonesarray, $tzid, $timestamp) {
|
|
||||||
if( is_array( $timestamp )) {
|
|
||||||
//$disp = sprintf( '%04d%02d%02d %02d%02d%02d', $timestamp['year'], $timestamp['month'], $timestamp['day'], $timestamp['hour'], $timestamp['min'], $timestamp['sec'] ); // test ###
|
|
||||||
$timestamp = gmmktime(
|
|
||||||
$timestamp['hour'],
|
|
||||||
$timestamp['min'],
|
|
||||||
$timestamp['sec'],
|
|
||||||
$timestamp['month'],
|
|
||||||
$timestamp['day'],
|
|
||||||
$timestamp['year']
|
|
||||||
) ;
|
|
||||||
}
|
|
||||||
$tzoffset = array();
|
|
||||||
// something to return if all goes wrong (such as if $tzid doesn't find us an array of dates)
|
|
||||||
$tzoffset['offsetHis'] = '+0000';
|
|
||||||
$tzoffset['offsetSec'] = 0;
|
|
||||||
$tzoffset['tzname'] = '?';
|
|
||||||
if( !isset( $timezonesarray[$tzid] ))
|
|
||||||
return $tzoffset;
|
|
||||||
$tzdatearray = $timezonesarray[$tzid];
|
|
||||||
if ( is_array($tzdatearray) ) {
|
|
||||||
sort($tzdatearray); // just in case
|
|
||||||
if ( $timestamp < $tzdatearray[0]['timestamp'] ) {
|
|
||||||
// our date is before the first change
|
|
||||||
$tzoffset['offsetHis'] = $tzdatearray[0]['tzbefore']['offsetHis'] ;
|
|
||||||
$tzoffset['offsetSec'] = $tzdatearray[0]['tzbefore']['offsetSec'] ;
|
|
||||||
$tzoffset['tzname'] = $tzdatearray[0]['tzbefore']['offsetHis'] ; // we don't know the tzname in this case
|
|
||||||
} elseif ( $timestamp >= $tzdatearray[count($tzdatearray)-1]['timestamp'] ) {
|
|
||||||
// our date is after the last change (we do this so our scan can stop at the last record but one)
|
|
||||||
$tzoffset['offsetHis'] = $tzdatearray[count($tzdatearray)-1]['tzafter']['offsetHis'] ;
|
|
||||||
$tzoffset['offsetSec'] = $tzdatearray[count($tzdatearray)-1]['tzafter']['offsetSec'] ;
|
|
||||||
$tzoffset['tzname'] = $tzdatearray[count($tzdatearray)-1]['tzafter']['tzname'] ;
|
|
||||||
} else {
|
|
||||||
// our date somewhere in between
|
|
||||||
// loop through the list of dates and stop at the one where the timestamp is before our date and the next one is after it
|
|
||||||
// we don't include the last date in our loop as there isn't one after it to check
|
|
||||||
for ( $i = 0 ; $i <= count($tzdatearray)-2 ; $i++ ) {
|
|
||||||
if(( $timestamp >= $tzdatearray[$i]['timestamp'] ) && ( $timestamp < $tzdatearray[$i+1]['timestamp'] )) {
|
|
||||||
$tzoffset['offsetHis'] = $tzdatearray[$i]['tzafter']['offsetHis'] ;
|
|
||||||
$tzoffset['offsetSec'] = $tzdatearray[$i]['tzafter']['offsetSec'] ;
|
|
||||||
$tzoffset['tzname'] = $tzdatearray[$i]['tzafter']['tzname'] ;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return $tzoffset;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Returns an array containing all the timezone data in the vcalendar object
|
|
||||||
*
|
|
||||||
* @param object $vcalendar iCalcreator calendar instance
|
|
||||||
* @return array time zone transition timestamp, array before(offsetHis, offsetSec), array after(offsetHis, offsetSec, tzname)
|
|
||||||
* based on the timezone data in the vcalendar object
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
function getTimezonesAsDateArrays($vcalendar) {
|
|
||||||
$timezonedata = array();
|
|
||||||
while( $vtz = $vcalendar->getComponent( 'vtimezone' )) {
|
|
||||||
$tzid = $vtz->getProperty('tzid');
|
|
||||||
$alltzdates = array();
|
|
||||||
while ( $vtzc = $vtz->getComponent( 'standard' )) {
|
|
||||||
$newtzdates = expandTimezoneDates($vtzc);
|
|
||||||
$alltzdates = array_merge($alltzdates, $newtzdates);
|
|
||||||
}
|
|
||||||
while ( $vtzc = $vtz->getComponent( 'daylight' )) {
|
|
||||||
$newtzdates = expandTimezoneDates($vtzc);
|
|
||||||
$alltzdates = array_merge($alltzdates, $newtzdates);
|
|
||||||
}
|
|
||||||
sort($alltzdates);
|
|
||||||
$timezonedata[$tzid] = $alltzdates;
|
|
||||||
}
|
|
||||||
return $timezonedata;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Returns an array containing time zone data from vtimezone standard/daylight instances
|
|
||||||
*
|
|
||||||
* @param object $vtzc an iCalcreator calendar standard/daylight instance
|
|
||||||
* @return array time zone data; array before(offsetHis, offsetSec), array after(offsetHis, offsetSec, tzname)
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
function expandTimezoneDates($vtzc) {
|
|
||||||
$tzdates = array();
|
|
||||||
// prepare time zone "description" to attach to each change
|
|
||||||
$tzbefore = array();
|
|
||||||
$tzbefore['offsetHis'] = $vtzc->getProperty('tzoffsetfrom') ;
|
|
||||||
$tzbefore['offsetSec'] = iCalUtilityFunctions::_tz2offset($tzbefore['offsetHis']);
|
|
||||||
if(( '-' != substr( (string) $tzbefore['offsetSec'], 0, 1 )) && ( '+' != substr( (string) $tzbefore['offsetSec'], 0, 1 )))
|
|
||||||
$tzbefore['offsetSec'] = '+'.$tzbefore['offsetSec'];
|
|
||||||
$tzafter = array();
|
|
||||||
$tzafter['offsetHis'] = $vtzc->getProperty('tzoffsetto') ;
|
|
||||||
$tzafter['offsetSec'] = iCalUtilityFunctions::_tz2offset($tzafter['offsetHis']);
|
|
||||||
if(( '-' != substr( (string) $tzafter['offsetSec'], 0, 1 )) && ( '+' != substr( (string) $tzafter['offsetSec'], 0, 1 )))
|
|
||||||
$tzafter['offsetSec'] = '+'.$tzafter['offsetSec'];
|
|
||||||
if( FALSE === ( $tzafter['tzname'] = $vtzc->getProperty('tzname')))
|
|
||||||
$tzafter['tzname'] = $tzafter['offsetHis'];
|
|
||||||
// find out where to start from
|
|
||||||
$dtstart = $vtzc->getProperty('dtstart');
|
|
||||||
$dtstarttimestamp = mktime(
|
|
||||||
$dtstart['hour'],
|
|
||||||
$dtstart['min'],
|
|
||||||
$dtstart['sec'],
|
|
||||||
$dtstart['month'],
|
|
||||||
$dtstart['day'],
|
|
||||||
$dtstart['year']
|
|
||||||
) ;
|
|
||||||
if( !isset( $dtstart['unparsedtext'] )) // ??
|
|
||||||
$dtstart['unparsedtext'] = sprintf( '%04d%02d%02dT%02d%02d%02d', $dtstart['year'], $dtstart['month'], $dtstart['day'], $dtstart['hour'], $dtstart['min'], $dtstart['sec'] );
|
|
||||||
if ( $dtstarttimestamp == 0 ) {
|
|
||||||
// it seems that the dtstart string may not have parsed correctly
|
|
||||||
// let's set a timestamp starting from 1902, using the time part of the original string
|
|
||||||
// so that the time will change at the right time of day
|
|
||||||
// at worst we'll get midnight again
|
|
||||||
$origdtstartsplit = explode('T',$dtstart['unparsedtext']) ;
|
|
||||||
$dtstarttimestamp = strtotime("19020101",0);
|
|
||||||
$dtstarttimestamp = strtotime($origdtstartsplit[1],$dtstarttimestamp);
|
|
||||||
}
|
|
||||||
// the date (in dtstart and opt RDATE/RRULE) is ALWAYS LOCAL (not utc!!), adjust from 'utc' to 'local' timestamp
|
|
||||||
$diff = -1 * $tzbefore['offsetSec'];
|
|
||||||
$dtstarttimestamp += $diff;
|
|
||||||
// add this (start) change to the array of changes
|
|
||||||
$tzdates[] = array(
|
|
||||||
'timestamp' => $dtstarttimestamp,
|
|
||||||
'tzbefore' => $tzbefore,
|
|
||||||
'tzafter' => $tzafter
|
|
||||||
);
|
|
||||||
$datearray = getdate($dtstarttimestamp);
|
|
||||||
// save original array to use time parts, because strtotime (used below) apparently loses the time
|
|
||||||
$changetime = $datearray ;
|
|
||||||
// generate dates according to an RRULE line
|
|
||||||
$rrule = $vtzc->getProperty('rrule') ;
|
|
||||||
if ( is_array($rrule) ) {
|
|
||||||
if ( $rrule['FREQ'] == 'YEARLY' ) {
|
|
||||||
// calculate transition dates starting from DTSTART
|
|
||||||
$offsetchangetimestamp = $dtstarttimestamp;
|
|
||||||
// calculate transition dates until 10 years in the future
|
|
||||||
$stoptimestamp = strtotime("+10 year",time());
|
|
||||||
// if UNTIL is set, calculate until then (however far ahead)
|
|
||||||
if ( isset( $rrule['UNTIL'] ) && ( $rrule['UNTIL'] != '' )) {
|
|
||||||
$stoptimestamp = mktime(
|
|
||||||
$rrule['UNTIL']['hour'],
|
|
||||||
$rrule['UNTIL']['min'],
|
|
||||||
$rrule['UNTIL']['sec'],
|
|
||||||
$rrule['UNTIL']['month'],
|
|
||||||
$rrule['UNTIL']['day'],
|
|
||||||
$rrule['UNTIL']['year']
|
|
||||||
) ;
|
|
||||||
}
|
|
||||||
$count = 0 ;
|
|
||||||
$stopcount = isset( $rrule['COUNT'] ) ? $rrule['COUNT'] : 0 ;
|
|
||||||
$daynames = array(
|
|
||||||
'SU' => 'Sunday',
|
|
||||||
'MO' => 'Monday',
|
|
||||||
'TU' => 'Tuesday',
|
|
||||||
'WE' => 'Wednesday',
|
|
||||||
'TH' => 'Thursday',
|
|
||||||
'FR' => 'Friday',
|
|
||||||
'SA' => 'Saturday'
|
|
||||||
);
|
|
||||||
// repeat so long as we're between DTSTART and UNTIL, or we haven't prepared COUNT dates
|
|
||||||
while ( $offsetchangetimestamp < $stoptimestamp && ( $stopcount == 0 || $count < $stopcount ) ) {
|
|
||||||
// break up the timestamp into its parts
|
|
||||||
$datearray = getdate($offsetchangetimestamp);
|
|
||||||
if ( isset( $rrule['BYMONTH'] ) && ( $rrule['BYMONTH'] != 0 )) {
|
|
||||||
// set the month
|
|
||||||
$datearray['mon'] = $rrule['BYMONTH'] ;
|
|
||||||
}
|
|
||||||
if ( isset( $rrule['BYMONTHDAY'] ) && ( $rrule['BYMONTHDAY'] != 0 )) {
|
|
||||||
// set specific day of month
|
|
||||||
$datearray['mday'] = $rrule['BYMONTHDAY'];
|
|
||||||
} elseif ( is_array($rrule['BYDAY']) ) {
|
|
||||||
// find the Xth WKDAY in the month
|
|
||||||
// the starting point for this process is the first of the month set above
|
|
||||||
$datearray['mday'] = 1 ;
|
|
||||||
// turn $datearray as it is now back into a timestamp
|
|
||||||
$offsetchangetimestamp = mktime(
|
|
||||||
$datearray['hours'],
|
|
||||||
$datearray['minutes'],
|
|
||||||
$datearray['seconds'],
|
|
||||||
$datearray['mon'],
|
|
||||||
$datearray['mday'],
|
|
||||||
$datearray['year']
|
|
||||||
);
|
|
||||||
if ($rrule['BYDAY'][0] > 0) {
|
|
||||||
// to find Xth WKDAY in month, we find last WKDAY in month before
|
|
||||||
// we do that by finding first WKDAY in this month and going back one week
|
|
||||||
// then we add X weeks (below)
|
|
||||||
$offsetchangetimestamp = strtotime($daynames[$rrule['BYDAY']['DAY']],$offsetchangetimestamp);
|
|
||||||
$offsetchangetimestamp = strtotime("-1 week",$offsetchangetimestamp);
|
|
||||||
} else {
|
|
||||||
// to find Xth WKDAY before the end of the month, we find the first WKDAY in the following month
|
|
||||||
// we do that by going forward one month and going to WKDAY there
|
|
||||||
// then we subtract X weeks (below)
|
|
||||||
$offsetchangetimestamp = strtotime("+1 month",$offsetchangetimestamp);
|
|
||||||
$offsetchangetimestamp = strtotime($daynames[$rrule['BYDAY']['DAY']],$offsetchangetimestamp);
|
|
||||||
}
|
|
||||||
// now move forward or back the appropriate number of weeks, into the month we want
|
|
||||||
$offsetchangetimestamp = strtotime($rrule['BYDAY'][0] . " week",$offsetchangetimestamp);
|
|
||||||
$datearray = getdate($offsetchangetimestamp);
|
|
||||||
}
|
|
||||||
// convert the date parts back into a timestamp, setting the time parts according to the
|
|
||||||
// original time data which we stored
|
|
||||||
$offsetchangetimestamp = mktime(
|
|
||||||
$changetime['hours'],
|
|
||||||
$changetime['minutes'],
|
|
||||||
$changetime['seconds'] + $diff,
|
|
||||||
$datearray['mon'],
|
|
||||||
$datearray['mday'],
|
|
||||||
$datearray['year']
|
|
||||||
);
|
|
||||||
// add this change to the array of changes
|
|
||||||
$tzdates[] = array(
|
|
||||||
'timestamp' => $offsetchangetimestamp,
|
|
||||||
'tzbefore' => $tzbefore,
|
|
||||||
'tzafter' => $tzafter
|
|
||||||
);
|
|
||||||
// update counters (timestamp and count)
|
|
||||||
$offsetchangetimestamp = strtotime("+" . (( isset( $rrule['INTERVAL'] ) && ( $rrule['INTERVAL'] != 0 )) ? $rrule['INTERVAL'] : 1 ) . " year",$offsetchangetimestamp);
|
|
||||||
$count += 1 ;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// generate dates according to RDATE lines
|
|
||||||
while ($rdates = $vtzc->getProperty('rdate')) {
|
|
||||||
if ( is_array($rdates) ) {
|
|
||||||
|
|
||||||
foreach ( $rdates as $rdate ) {
|
|
||||||
// convert the explicit change date to a timestamp
|
|
||||||
$offsetchangetimestamp = mktime(
|
|
||||||
$rdate['hour'],
|
|
||||||
$rdate['min'],
|
|
||||||
$rdate['sec'] + $diff,
|
|
||||||
$rdate['month'],
|
|
||||||
$rdate['day'],
|
|
||||||
$rdate['year']
|
|
||||||
) ;
|
|
||||||
// add this change to the array of changes
|
|
||||||
$tzdates[] = array(
|
|
||||||
'timestamp' => $offsetchangetimestamp,
|
|
||||||
'tzbefore' => $tzbefore,
|
|
||||||
'tzafter' => $tzafter
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return $tzdates;
|
|
||||||
}
|
|
@ -1,166 +0,0 @@
|
|||||||
<?php
|
|
||||||
/*********************************************************************************/
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* iCalcreator, a PHP rfc2445/rfc5545 solution.
|
|
||||||
*
|
|
||||||
* @copyright Copyright (c) 2007-2015 Kjell-Inge Gustafsson, kigkonsult, All rights reserved
|
|
||||||
* @link http://kigkonsult.se/iCalcreator/index.php
|
|
||||||
* @license http://kigkonsult.se/downloads/dl.php?f=LGPL
|
|
||||||
* @package iCalcreator
|
|
||||||
* @version 2.22
|
|
||||||
*/
|
|
||||||
/**
|
|
||||||
* This library is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
|
||||||
* License as published by the Free Software Foundation; either
|
|
||||||
* version 2.1 of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This library is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
|
||||||
* License along with this library; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*/
|
|
||||||
/*********************************************************************************/
|
|
||||||
/* iCalcreator vCard helper functions */
|
|
||||||
/*********************************************************************************/
|
|
||||||
/**
|
|
||||||
* convert single ATTENDEE, CONTACT or ORGANIZER (in email format) to vCard
|
|
||||||
* returns vCard/TRUE or if directory (if set) or file write is unvalid, FALSE
|
|
||||||
*
|
|
||||||
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
|
||||||
* @since 2.12.2 - 2012-07-11
|
|
||||||
* @param string $email
|
|
||||||
* @param string $version vCard version (default 2.1)
|
|
||||||
* @param string $directory where to save vCards (default FALSE)
|
|
||||||
* @param string $ext vCard file extension (default 'vcf')
|
|
||||||
* @uses ICALCREATOR_VERSION
|
|
||||||
* @return mixed
|
|
||||||
*/
|
|
||||||
function iCal2vCard( $email, $version='2.1', $directory=FALSE, $ext='vcf' ) {
|
|
||||||
if( FALSE === ( $pos = strpos( $email, '@' )))
|
|
||||||
return FALSE;
|
|
||||||
if( $directory ) {
|
|
||||||
if( DIRECTORY_SEPARATOR != substr( $directory, ( 0 - strlen( DIRECTORY_SEPARATOR ))))
|
|
||||||
$directory .= DIRECTORY_SEPARATOR;
|
|
||||||
if( !is_dir( $directory ) || !is_writable( $directory ))
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
/* prepare vCard */
|
|
||||||
$email = str_replace( 'MAILTO:', '', $email );
|
|
||||||
$name = $person = substr( $email, 0, $pos );
|
|
||||||
if( ctype_upper( $name ) || ctype_lower( $name ))
|
|
||||||
$name = array( $name );
|
|
||||||
else {
|
|
||||||
if( FALSE !== ( $pos = strpos( $name, '.' ))) {
|
|
||||||
$name = explode( '.', $name );
|
|
||||||
foreach( $name as $k => $part )
|
|
||||||
$name[$k] = ucfirst( $part );
|
|
||||||
}
|
|
||||||
else { // split camelCase
|
|
||||||
$chars = $name;
|
|
||||||
$name = array( $chars[0] );
|
|
||||||
$k = 0;
|
|
||||||
$x = 1;
|
|
||||||
while( FALSE !== ( $char = substr( $chars, $x, 1 ))) {
|
|
||||||
if( ctype_upper( $char )) {
|
|
||||||
$k += 1;
|
|
||||||
$name[$k] = '';
|
|
||||||
}
|
|
||||||
$name[$k] .= $char;
|
|
||||||
$x++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$nl = "\r\n";
|
|
||||||
$FN = 'FN:'.implode( ' ', $name ).$nl;
|
|
||||||
$name = array_reverse( $name );
|
|
||||||
$N = 'N:'.array_shift( $name );
|
|
||||||
$scCnt = 0;
|
|
||||||
while( NULL != ( $part = array_shift( $name ))) {
|
|
||||||
if(( '4.0' != $version ) || ( 4 > $scCnt ))
|
|
||||||
$scCnt += 1;
|
|
||||||
$N .= ';'.$part;
|
|
||||||
}
|
|
||||||
while(( '4.0' == $version ) && ( 4 > $scCnt )) {
|
|
||||||
$N .= ';';
|
|
||||||
$scCnt += 1;
|
|
||||||
}
|
|
||||||
$N .= $nl;
|
|
||||||
$EMAIL = 'EMAIL:'.$email.$nl;
|
|
||||||
/* create vCard */
|
|
||||||
$vCard = 'BEGIN:VCARD'.$nl;
|
|
||||||
$vCard .= "VERSION:$version$nl";
|
|
||||||
$vCard .= 'PRODID:-//kigkonsult.se '.ICALCREATOR_VERSION."//$nl";
|
|
||||||
$vCard .= $N;
|
|
||||||
$vCard .= $FN;
|
|
||||||
$vCard .= $EMAIL;
|
|
||||||
$vCard .= 'REV:'.gmdate( 'Ymd\THis\Z' ).$nl;
|
|
||||||
$vCard .= 'END:VCARD'.$nl;
|
|
||||||
/* save each vCard as (unique) single file */
|
|
||||||
if( $directory ) {
|
|
||||||
$fname = $directory.preg_replace( '/[^a-z0-9.]/i', '', $email );
|
|
||||||
$cnt = 1;
|
|
||||||
$dbl = '';
|
|
||||||
while( is_file ( $fname.$dbl.'.'.$ext )) {
|
|
||||||
$cnt += 1;
|
|
||||||
$dbl = "_$cnt";
|
|
||||||
}
|
|
||||||
if( FALSE === file_put_contents( $fname, $fname.$dbl.'.'.$ext ))
|
|
||||||
return FALSE;
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
/* return vCard */
|
|
||||||
else
|
|
||||||
return $vCard;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* convert ATTENDEEs, CONTACTs and ORGANIZERs (in email format) to vCards
|
|
||||||
*
|
|
||||||
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
|
||||||
* @since 2.12.2 - 2012-05-07
|
|
||||||
* @param object $calendar iCalcreator vcalendar instance reference
|
|
||||||
* @param string $version vCard version (default 2.1)
|
|
||||||
* @param string $directory where to save vCards (default FALSE)
|
|
||||||
* @param string $ext vCard file extension (default 'vcf')
|
|
||||||
* @uses vcalendar::getProperty()
|
|
||||||
* @return mixed
|
|
||||||
*/
|
|
||||||
function iCal2vCards( & $calendar, $version='2.1', $directory=FALSE, $ext='vcf' ) {
|
|
||||||
$hits = array();
|
|
||||||
$vCardP = array( 'ATTENDEE', 'CONTACT', 'ORGANIZER' );
|
|
||||||
foreach( $vCardP as $prop ) {
|
|
||||||
$hits2 = $calendar->getProperty( $prop );
|
|
||||||
foreach( $hits2 as $propValue => $occCnt ) {
|
|
||||||
if( FALSE === ( $pos = strpos( $propValue, '@' )))
|
|
||||||
continue;
|
|
||||||
$propValue = str_replace( 'MAILTO:', '', $propValue );
|
|
||||||
if( isset( $hits[$propValue] ))
|
|
||||||
$hits[$propValue] += $occCnt;
|
|
||||||
else
|
|
||||||
$hits[$propValue] = $occCnt;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if( empty( $hits ))
|
|
||||||
return FALSE;
|
|
||||||
ksort( $hits );
|
|
||||||
$output = '';
|
|
||||||
foreach( $hits as $email => $skip ) {
|
|
||||||
$res = iCal2vCard( $email, $version, $directory, $ext );
|
|
||||||
if( $directory && !$res )
|
|
||||||
return FALSE;
|
|
||||||
elseif( !$res )
|
|
||||||
return $res;
|
|
||||||
else
|
|
||||||
$output .= $res;
|
|
||||||
}
|
|
||||||
if( $directory )
|
|
||||||
return TRUE;
|
|
||||||
if( !empty( $output ))
|
|
||||||
return $output;
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
@ -1,427 +0,0 @@
|
|||||||
<?php
|
|
||||||
/*********************************************************************************/
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* iCalcreator, a PHP rfc2445/rfc5545 solution.
|
|
||||||
*
|
|
||||||
* @copyright Copyright (c) 2007-2015 Kjell-Inge Gustafsson, kigkonsult, All rights reserved
|
|
||||||
* @link http://kigkonsult.se/iCalcreator/index.php
|
|
||||||
* @license http://kigkonsult.se/downloads/dl.php?f=LGPL
|
|
||||||
* @package iCalcreator
|
|
||||||
* @version 2.22
|
|
||||||
*/
|
|
||||||
/**
|
|
||||||
* This library is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
|
||||||
* License as published by the Free Software Foundation; either
|
|
||||||
* version 2.1 of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This library is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
|
||||||
* License along with this library; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*/
|
|
||||||
/*********************************************************************************/
|
|
||||||
/**
|
|
||||||
* iCalcreator base class
|
|
||||||
*
|
|
||||||
* properties and functions shared by vcalendar and calendarComponents
|
|
||||||
*
|
|
||||||
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
|
||||||
* @since 2.21.11 - 2015-03-31
|
|
||||||
*/
|
|
||||||
abstract class iCalBase {
|
|
||||||
/**
|
|
||||||
* @var array component property X-property value
|
|
||||||
* @access protected
|
|
||||||
*/
|
|
||||||
protected $xprop;
|
|
||||||
/** @var array container for sub-components */
|
|
||||||
public $components;
|
|
||||||
/** @var array $unparsed calendar/components in 'raw' text... */
|
|
||||||
public $unparsed;
|
|
||||||
/**
|
|
||||||
* @var bool $allowEmpty config variable
|
|
||||||
* @var string $language config variable
|
|
||||||
* @var string $nl config variable
|
|
||||||
* @var string $unique_id config variable
|
|
||||||
* @var string $format config variable
|
|
||||||
* @var string $dtzid config variable
|
|
||||||
* @access protected
|
|
||||||
*/
|
|
||||||
protected $allowEmpty;
|
|
||||||
protected $language;
|
|
||||||
protected $nl;
|
|
||||||
protected $unique_id;
|
|
||||||
protected $format;
|
|
||||||
protected $dtzid;
|
|
||||||
/**
|
|
||||||
* @var string $componentStart1 valendar/component internal variable
|
|
||||||
* @var string $componentStart2 valendar/component internal variable
|
|
||||||
* @var string $componentEnd1 valendar/component internal variable
|
|
||||||
* @var string $componentEnd2 valendar/component internal variable
|
|
||||||
* @var string $elementStart1 valendar/component internal variable
|
|
||||||
* @var string $elementStart2 valendar/component internal variable
|
|
||||||
* @var string $elementEnd1 valendar/component internal variable
|
|
||||||
* @var string $elementEnd2 valendar/component internal variable
|
|
||||||
* @var string $intAttrDelimiter valendar/component internal variable
|
|
||||||
* @var string $attributeDelimiter valendar/component internal variable
|
|
||||||
* @var string $valueInit valendar/component internal variable
|
|
||||||
* @access protected
|
|
||||||
*/
|
|
||||||
protected $componentStart1;
|
|
||||||
protected $componentStart2;
|
|
||||||
protected $componentEnd1;
|
|
||||||
protected $componentEnd2;
|
|
||||||
protected $elementStart1;
|
|
||||||
protected $elementStart2;
|
|
||||||
protected $elementEnd1;
|
|
||||||
protected $elementEnd2;
|
|
||||||
protected $intAttrDelimiter;
|
|
||||||
protected $attributeDelimiter;
|
|
||||||
protected $valueInit;
|
|
||||||
/**
|
|
||||||
* @var array $xcaldecl xCal declaration container
|
|
||||||
* @access protected
|
|
||||||
*/
|
|
||||||
protected $xcaldecl;
|
|
||||||
/**
|
|
||||||
* Property Name: x-prop
|
|
||||||
*/
|
|
||||||
/**
|
|
||||||
* creates formatted output for calendar/component property x-prop
|
|
||||||
*
|
|
||||||
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
|
||||||
* @since 2.21.11 - 2015-03-31
|
|
||||||
* @uses iCalBase::$xprop
|
|
||||||
* @uses vcalendar::getConfig()
|
|
||||||
* @uses calendarComponent::getConfig()
|
|
||||||
* @uses iCalBase::_createElement()
|
|
||||||
* @uses iCalBase::_createParams()
|
|
||||||
* @uses iCalUtilityFunctions::_strrep()
|
|
||||||
* @uses iCalBase::$format
|
|
||||||
* @uses iCalBase::$nl
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function createXprop() {
|
|
||||||
if( empty( $this->xprop ) || !is_array( $this->xprop )) return FALSE;
|
|
||||||
$output = null;
|
|
||||||
foreach( $this->xprop as $label => $xpropPart ) {
|
|
||||||
if( ! isset( $xpropPart['value']) || ( empty( $xpropPart['value'] ) && !is_numeric( $xpropPart['value'] ))) {
|
|
||||||
if( $this->getConfig( 'allowEmpty' ))
|
|
||||||
$output .= $this->_createElement( $label );
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
$attributes = $this->_createParams( $xpropPart['params'], array( 'LANGUAGE' ));
|
|
||||||
if( is_array( $xpropPart['value'] )) {
|
|
||||||
foreach( $xpropPart['value'] as $pix => $theXpart )
|
|
||||||
$xpropPart['value'][$pix] = iCalUtilityFunctions::_strrep( $theXpart, $this->format, $this->nl );
|
|
||||||
$xpropPart['value'] = implode( ',', $xpropPart['value'] );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
$xpropPart['value'] = iCalUtilityFunctions::_strrep( $xpropPart['value'], $this->format, $this->nl );
|
|
||||||
$output .= $this->_createElement( $label, $attributes, $xpropPart['value'] );
|
|
||||||
}
|
|
||||||
return $output;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* set calendar property x-prop
|
|
||||||
*
|
|
||||||
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
|
||||||
* @since 2.21.11 - 2015-03-31
|
|
||||||
* @param string $label
|
|
||||||
* @param string $value
|
|
||||||
* @param array $params optional
|
|
||||||
* @uses vcalendar::getConfig()
|
|
||||||
* @uses iCalUtilityFunctions::_setParams()
|
|
||||||
* @uses iCalBase::$xprop
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
public function setXprop( $label, $value, $params=FALSE ) {
|
|
||||||
if( empty( $label ))
|
|
||||||
return FALSE;
|
|
||||||
$label = strtoupper( $label );
|
|
||||||
if( 'X-' != substr( $label, 0, 2 ))
|
|
||||||
return FALSE;
|
|
||||||
if( empty( $value ) && !is_numeric( $value )) if( $this->getConfig( 'allowEmpty' )) $value = ''; else return FALSE;
|
|
||||||
$xprop = array( 'value' => $value );
|
|
||||||
$xprop['params'] = iCalUtilityFunctions::_setParams( $params );
|
|
||||||
if( ! is_array( $this->xprop ))
|
|
||||||
$this->xprop = array();
|
|
||||||
$this->xprop[$label] = $xprop;
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* create element format parts
|
|
||||||
*
|
|
||||||
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
|
||||||
* @since 2.21.11 - 2015-03-31
|
|
||||||
* @uses iCalBase::$format
|
|
||||||
* @uses iCalBase::$objName
|
|
||||||
* @uses iCalBase::$componentStart1
|
|
||||||
* @uses iCalBase::$elementStart1
|
|
||||||
* @uses iCalBase::$componentStart2
|
|
||||||
* @uses iCalBase::$elementStart2
|
|
||||||
* @uses iCalBase::$componentEnd1
|
|
||||||
* @uses iCalBase::$elementEnd1
|
|
||||||
* @uses iCalBase::$componentEnd2
|
|
||||||
* @uses iCalBase::$elementEnd2
|
|
||||||
* @uses iCalBase::$nl;
|
|
||||||
* @uses iCalBase::$intAttrDelimiter
|
|
||||||
* @uses iCalBase::$attributeDelimiter
|
|
||||||
* @uses iCalBase::$valueInit
|
|
||||||
* @return bool
|
|
||||||
*/
|
|
||||||
function _createFormat() {
|
|
||||||
switch( $this->format ) {
|
|
||||||
case 'xcal':
|
|
||||||
$this->componentStart1 = $this->elementStart1 = '<';
|
|
||||||
$this->componentStart2 = $this->elementStart2 = '>';
|
|
||||||
$this->componentEnd1 = $this->elementEnd1 = '</';
|
|
||||||
$this->componentEnd2 = $this->elementEnd2 = '>'.$this->nl;
|
|
||||||
$this->intAttrDelimiter = '<!-- -->';
|
|
||||||
$this->attributeDelimiter = $this->nl;
|
|
||||||
$this->valueInit = null;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
$this->componentStart1 = 'BEGIN:';
|
|
||||||
$this->componentStart2 = null;
|
|
||||||
$this->componentEnd1 = 'END:';
|
|
||||||
$this->componentEnd2 = $this->nl;
|
|
||||||
$this->elementStart1 = null;
|
|
||||||
$this->elementStart2 = null;
|
|
||||||
$this->elementEnd1 = null;
|
|
||||||
$this->elementEnd2 = $this->nl;
|
|
||||||
$this->intAttrDelimiter = '<!-- -->';
|
|
||||||
$this->attributeDelimiter = ';';
|
|
||||||
$this->valueInit = ':';
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* creates formatted output for calendar component property
|
|
||||||
*
|
|
||||||
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
|
||||||
* @since 2.21.11 - 2015-03-31
|
|
||||||
* @param string $label property name
|
|
||||||
* @param string $attributes property attributes
|
|
||||||
* @param string $content property content (optional)
|
|
||||||
* @uses iCalBase::$format
|
|
||||||
* @uses iCalBase::$elementStart1
|
|
||||||
* @uses iCalBase::$xcaldecl
|
|
||||||
* @uses iCalBase::$intAttrDelimiter
|
|
||||||
* @uses iCalBase::$attributeDelimiter
|
|
||||||
* @uses iCalBase::_createElement()
|
|
||||||
* @uses iCalBase::$elementStart2
|
|
||||||
* @uses iCalBase::$nl
|
|
||||||
* @uses iCalBase::$valueInit
|
|
||||||
* @uses iCalUtilityFunctions::_size75()
|
|
||||||
* @uses iCalBase::$elementEnd1
|
|
||||||
* @uses iCalBase::$elementEnd2
|
|
||||||
* @access protected
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
protected function _createElement( $label, $attributes=null, $content=FALSE ) {
|
|
||||||
switch( $this->format ) {
|
|
||||||
case 'xcal':
|
|
||||||
$label = strtolower( $label );
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
$label = strtoupper( $label );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
$output = $this->elementStart1.$label;
|
|
||||||
$categoriesAttrLang = null;
|
|
||||||
$attachInlineBinary = FALSE;
|
|
||||||
$attachfmttype = null;
|
|
||||||
if (( 'xcal' == $this->format) && ( 'x-' == substr( $label, 0, 2 ))) {
|
|
||||||
$this->xcaldecl[] = array( 'xmldecl' => 'ELEMENT'
|
|
||||||
, 'ref' => $label
|
|
||||||
, 'type2' => '(#PCDATA)' );
|
|
||||||
}
|
|
||||||
if( !empty( $attributes )) {
|
|
||||||
$attributes = trim( $attributes );
|
|
||||||
if ( 'xcal' == $this->format ) {
|
|
||||||
$attributes2 = explode( $this->intAttrDelimiter, $attributes );
|
|
||||||
$attributes = null;
|
|
||||||
foreach( $attributes2 as $aix => $attribute ) {
|
|
||||||
$attrKVarr = explode( '=', $attribute );
|
|
||||||
if( empty( $attrKVarr[0] ))
|
|
||||||
continue;
|
|
||||||
if( !isset( $attrKVarr[1] )) {
|
|
||||||
$attrValue = $attrKVarr[0];
|
|
||||||
$attrKey = $aix;
|
|
||||||
}
|
|
||||||
elseif( 2 == count( $attrKVarr)) {
|
|
||||||
$attrKey = strtolower( $attrKVarr[0] );
|
|
||||||
$attrValue = $attrKVarr[1];
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$attrKey = strtolower( $attrKVarr[0] );
|
|
||||||
unset( $attrKVarr[0] );
|
|
||||||
$attrValue = implode( '=', $attrKVarr );
|
|
||||||
}
|
|
||||||
if(( 'attach' == $label ) && ( in_array( $attrKey, array( 'fmttype', 'encoding', 'value' )))) {
|
|
||||||
$attachInlineBinary = TRUE;
|
|
||||||
if( 'fmttype' == $attrKey )
|
|
||||||
$attachfmttype = $attrKey.'='.$attrValue;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
elseif(( 'categories' == $label ) && ( 'language' == $attrKey ))
|
|
||||||
$categoriesAttrLang = $attrKey.'='.$attrValue;
|
|
||||||
else {
|
|
||||||
$attributes .= ( empty( $attributes )) ? ' ' : $this->attributeDelimiter.' ';
|
|
||||||
$attributes .= ( !empty( $attrKey )) ? $attrKey.'=' : null;
|
|
||||||
if(( '"' == substr( $attrValue, 0, 1 )) && ( '"' == substr( $attrValue, -1 ))) {
|
|
||||||
$attrValue = substr( $attrValue, 1, ( strlen( $attrValue ) - 2 ));
|
|
||||||
$attrValue = str_replace( '"', '', $attrValue );
|
|
||||||
}
|
|
||||||
$attributes .= '"'.htmlspecialchars( $attrValue ).'"';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
$attributes = str_replace( $this->intAttrDelimiter, $this->attributeDelimiter, $attributes );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(( 'xcal' == $this->format) &&
|
|
||||||
((( 'attach' == $label ) && !$attachInlineBinary ) || ( in_array( $label, array( 'tzurl', 'url' ))))) {
|
|
||||||
$pos = strrpos( $content, "/" );
|
|
||||||
$docname = ( $pos !== false) ? substr( $content, (1 - strlen( $content ) + $pos )) : $content;
|
|
||||||
$this->xcaldecl[] = array( 'xmldecl' => 'ENTITY'
|
|
||||||
, 'uri' => $docname
|
|
||||||
, 'ref' => 'SYSTEM'
|
|
||||||
, 'external' => $content
|
|
||||||
, 'type' => 'NDATA'
|
|
||||||
, 'type2' => 'BINERY' );
|
|
||||||
$attributes .= ( empty( $attributes )) ? ' ' : $this->attributeDelimiter.' ';
|
|
||||||
$attributes .= 'uri="'.$docname.'"';
|
|
||||||
$content = null;
|
|
||||||
if( 'attach' == $label ) {
|
|
||||||
$attributes = str_replace( $this->attributeDelimiter, $this->intAttrDelimiter, $attributes );
|
|
||||||
$content = $this->nl.$this->_createElement( 'extref', $attributes, null );
|
|
||||||
$attributes = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
elseif(( 'xcal' == $this->format) && ( 'attach' == $label ) && $attachInlineBinary ) {
|
|
||||||
$content = $this->nl.$this->_createElement( 'b64bin', $attachfmttype, $content ); // max one attribute
|
|
||||||
}
|
|
||||||
$output .= $attributes;
|
|
||||||
if( !$content && ( '0' != $content )) {
|
|
||||||
switch( $this->format ) {
|
|
||||||
case 'xcal':
|
|
||||||
$output .= ' /';
|
|
||||||
$output .= $this->elementStart2.$this->nl;
|
|
||||||
return $output;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
$output .= $this->elementStart2.$this->valueInit;
|
|
||||||
return iCalUtilityFunctions::_size75( $output, $this->nl );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$output .= $this->elementStart2;
|
|
||||||
$output .= $this->valueInit.$content;
|
|
||||||
switch( $this->format ) {
|
|
||||||
case 'xcal':
|
|
||||||
return $output.$this->elementEnd1.$label.$this->elementEnd2;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return iCalUtilityFunctions::_size75( $output, $this->nl );
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* creates formatted output for calendar component property parameters
|
|
||||||
*
|
|
||||||
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
|
||||||
* @since 2.21.11 - 2015-03-31
|
|
||||||
* @param array $params optional
|
|
||||||
* @param array $ctrKeys optional
|
|
||||||
* @uses iCalBase::$intAttrDelimiter
|
|
||||||
* @uses vcalendar::getConfig()
|
|
||||||
* @uses calendarComponent::getConfig()
|
|
||||||
* @access protected
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
protected function _createParams( $params=array(), $ctrKeys=array() ) {
|
|
||||||
if( !is_array( $params ) || empty( $params ))
|
|
||||||
$params = array();
|
|
||||||
$attrLANG = $attr1 = $attr2 = $lang = null;
|
|
||||||
$CNattrKey = ( in_array( 'CN', $ctrKeys )) ? TRUE : FALSE ;
|
|
||||||
$LANGattrKey = ( in_array( 'LANGUAGE', $ctrKeys )) ? TRUE : FALSE ;
|
|
||||||
$CNattrExist = $LANGattrExist = FALSE;
|
|
||||||
$xparams = array();
|
|
||||||
$params = array_change_key_case( $params, CASE_UPPER );
|
|
||||||
foreach( $params as $paramKey => $paramValue ) {
|
|
||||||
if(( FALSE !== strpos( $paramValue, ':' )) ||
|
|
||||||
( FALSE !== strpos( $paramValue, ';' )) ||
|
|
||||||
( FALSE !== strpos( $paramValue, ',' )))
|
|
||||||
$paramValue = '"'.$paramValue.'"';
|
|
||||||
if( ctype_digit( (string) $paramKey )) {
|
|
||||||
$xparams[] = $paramValue;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if( !in_array( $paramKey, array( 'ALTREP', 'CN', 'DIR', 'ENCODING', 'FMTTYPE', 'LANGUAGE', 'RANGE', 'RELTYPE', 'SENT-BY', 'TZID', 'VALUE' )))
|
|
||||||
$xparams[$paramKey] = $paramValue;
|
|
||||||
else
|
|
||||||
$params[$paramKey] = $paramValue;
|
|
||||||
}
|
|
||||||
ksort( $xparams, SORT_STRING );
|
|
||||||
foreach( $xparams as $paramKey => $paramValue ) {
|
|
||||||
if( ctype_digit( (string) $paramKey ))
|
|
||||||
$attr2 .= $this->intAttrDelimiter.$paramValue;
|
|
||||||
else
|
|
||||||
$attr2 .= $this->intAttrDelimiter."$paramKey=$paramValue";
|
|
||||||
}
|
|
||||||
if( isset( $params['FMTTYPE'] ) && !in_array( 'FMTTYPE', $ctrKeys )) {
|
|
||||||
$attr1 .= $this->intAttrDelimiter.'FMTTYPE='.$params['FMTTYPE'].$attr2;
|
|
||||||
$attr2 = null;
|
|
||||||
}
|
|
||||||
if( isset( $params['ENCODING'] ) && !in_array( 'ENCODING', $ctrKeys )) {
|
|
||||||
if( !empty( $attr2 )) {
|
|
||||||
$attr1 .= $attr2;
|
|
||||||
$attr2 = null;
|
|
||||||
}
|
|
||||||
$attr1 .= $this->intAttrDelimiter.'ENCODING='.$params['ENCODING'];
|
|
||||||
}
|
|
||||||
if( isset( $params['VALUE'] ) && !in_array( 'VALUE', $ctrKeys ))
|
|
||||||
$attr1 .= $this->intAttrDelimiter.'VALUE='.$params['VALUE'];
|
|
||||||
if( isset( $params['TZID'] ) && !in_array( 'TZID', $ctrKeys )) {
|
|
||||||
$attr1 .= $this->intAttrDelimiter.'TZID='.$params['TZID'];
|
|
||||||
}
|
|
||||||
if( isset( $params['RANGE'] ) && !in_array( 'RANGE', $ctrKeys ))
|
|
||||||
$attr1 .= $this->intAttrDelimiter.'RANGE='.$params['RANGE'];
|
|
||||||
if( isset( $params['RELTYPE'] ) && !in_array( 'RELTYPE', $ctrKeys ))
|
|
||||||
$attr1 .= $this->intAttrDelimiter.'RELTYPE='.$params['RELTYPE'];
|
|
||||||
if( isset( $params['CN'] ) && $CNattrKey ) {
|
|
||||||
$attr1 = $this->intAttrDelimiter.'CN='.$params['CN'];
|
|
||||||
$CNattrExist = TRUE;
|
|
||||||
}
|
|
||||||
if( isset( $params['DIR'] ) && in_array( 'DIR', $ctrKeys )) {
|
|
||||||
$delim = ( FALSE !== strpos( $params['DIR'], '"' )) ? '' : '"';
|
|
||||||
$attr1 .= $this->intAttrDelimiter.'DIR='.$delim.$params['DIR'].$delim;
|
|
||||||
}
|
|
||||||
if( isset( $params['SENT-BY'] ) && in_array( 'SENT-BY', $ctrKeys ))
|
|
||||||
$attr1 .= $this->intAttrDelimiter.'SENT-BY='.$params['SENT-BY'];
|
|
||||||
if( isset( $params['ALTREP'] ) && in_array( 'ALTREP', $ctrKeys )) {
|
|
||||||
$delim = ( FALSE !== strpos( $params['ALTREP'], '"' )) ? '' : '"';
|
|
||||||
$attr1 .= $this->intAttrDelimiter.'ALTREP='.$delim.$params['ALTREP'].$delim;
|
|
||||||
}
|
|
||||||
if( isset( $params['LANGUAGE'] ) && $LANGattrKey ) {
|
|
||||||
$attrLANG .= $this->intAttrDelimiter.'LANGUAGE='.$params['LANGUAGE'];
|
|
||||||
$LANGattrExist = TRUE;
|
|
||||||
}
|
|
||||||
if( !$LANGattrExist ) {
|
|
||||||
$lang = $this->getConfig( 'language' );
|
|
||||||
if(( $CNattrExist || $LANGattrKey ) && $lang )
|
|
||||||
$attrLANG .= $this->intAttrDelimiter.'LANGUAGE='.$lang;
|
|
||||||
}
|
|
||||||
return $attr1.$attrLANG.$attr2;
|
|
||||||
}
|
|
||||||
}
|
|
File diff suppressed because it is too large
Load Diff
@ -1,129 +0,0 @@
|
|||||||
<?php
|
|
||||||
/*********************************************************************************/
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* iCalcreator, a PHP rfc2445/rfc5545 solution.
|
|
||||||
*
|
|
||||||
* @copyright Copyright (c) 2007-2015 Kjell-Inge Gustafsson, kigkonsult, All rights reserved
|
|
||||||
* @link http://kigkonsult.se/iCalcreator/index.php
|
|
||||||
* @license http://kigkonsult.se/downloads/dl.php?f=LGPL
|
|
||||||
* @package iCalcreator
|
|
||||||
* @version 2.22
|
|
||||||
*/
|
|
||||||
/**
|
|
||||||
* This library is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
|
||||||
* License as published by the Free Software Foundation; either
|
|
||||||
* version 2.1 of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This library is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
|
||||||
* License along with this library; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*/
|
|
||||||
/*********************************************************************************/
|
|
||||||
/**
|
|
||||||
* selectComponent help class
|
|
||||||
*
|
|
||||||
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
|
||||||
* @since 2.21.7 - 2015-03-10
|
|
||||||
*/
|
|
||||||
class iCaldateTime extends dateTime {
|
|
||||||
/** @var string default date[-time] format */
|
|
||||||
public $dateFormat = 'Y-m-d H:i:s e';
|
|
||||||
/** @var string default object instance date[-time] 'key' */
|
|
||||||
public $key = null;
|
|
||||||
/** @var array date[-time] origin */
|
|
||||||
public $SCbools = array();
|
|
||||||
/**
|
|
||||||
* return time (His) array
|
|
||||||
*
|
|
||||||
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
|
||||||
* @since 2.21.7 - 2015-03-07
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public function getTime() {
|
|
||||||
return explode( ':', $this->format( 'H:i:s' ));
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* return the timezone name
|
|
||||||
*
|
|
||||||
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
|
||||||
* @since 2.21.7 - 2015-03-07
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function getTimezoneName() {
|
|
||||||
$tz = $this->getTimezone();
|
|
||||||
return $tz->getName();
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* return formatted date
|
|
||||||
*
|
|
||||||
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
|
||||||
* @since 2.21.7 - 2015-03-07
|
|
||||||
* @param string $format
|
|
||||||
* @uses iCaldateTime::$dateFormat
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public function format( $format=null ) {
|
|
||||||
if( empty( $format ) && isset( $this->dateFormat ))
|
|
||||||
$format = $this->dateFormat;
|
|
||||||
return parent::format( $format );
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* return iCaldateTime object instance based on date array and timezone(s)
|
|
||||||
*
|
|
||||||
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
|
||||||
* @since 2.21.11 - 2015-03-28
|
|
||||||
* @param array $date
|
|
||||||
* @param array $params
|
|
||||||
* @param array $tz
|
|
||||||
* @param string $dtstartTz
|
|
||||||
* @uses iCalUtilityFunctions::$fmt
|
|
||||||
* @uses iCaldateTime::getTimezoneName()
|
|
||||||
* @uses iCaldateTime::$dateFormat
|
|
||||||
* @uses iCaldateTime::$key
|
|
||||||
* @return object instance
|
|
||||||
*/
|
|
||||||
public static function factory( array $date, $params=null, $tz=null, $dtstartTz=null ) {
|
|
||||||
if( isset( $params['TZID'] ) && ! empty( $params['TZID'] ))
|
|
||||||
$tz = ( 'Z' == $params['TZID'] ) ? 'UTC' : $params['TZID'];
|
|
||||||
elseif( isset( $tz['tz'] ) && ! empty( $tz['tz'] ))
|
|
||||||
$tz = ( 'Z' == $tz['tz'] ) ? 'UTC' : $tz['tz'];
|
|
||||||
else
|
|
||||||
$tz = ini_get( 'date_default_timezone_set' );
|
|
||||||
$strdate = sprintf( iCalUtilityFunctions::$fmt['Ymd'], (int) $date['year'], (int) $date['month'], (int) $date['day'] );
|
|
||||||
if( isset( $date['hour'] ))
|
|
||||||
$strdate .= 'T'.sprintf( iCalUtilityFunctions::$fmt['His'], (int) $date['hour'], (int) $date['min'], (int) $date['sec'] );
|
|
||||||
try {
|
|
||||||
$timezone = new DateTimeZone( $tz );
|
|
||||||
$d = new iCaldateTime( $strdate, $timezone );
|
|
||||||
}
|
|
||||||
catch( Exception $e ) {
|
|
||||||
$d = new iCaldateTime( $strdate );
|
|
||||||
}
|
|
||||||
if( ! empty( $dtstartTz )) {
|
|
||||||
if( 'Z' == $dtstartTz )
|
|
||||||
$dtstartTz = 'UTC';
|
|
||||||
if( $dtstartTz != $d->getTimezoneName()) { // set the same timezone as dtstart
|
|
||||||
try {
|
|
||||||
$timezone = new DateTimeZone( $dtstartTz );
|
|
||||||
$d->setTimezone( $timezone );
|
|
||||||
}
|
|
||||||
catch( Exception $e ) {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
unset( $timezone, $strdate );
|
|
||||||
if( isset( $params['VALUE'] ) && ( 'DATE' == $params['VALUE'] )) {
|
|
||||||
$d->dateFormat = 'Y-m-d';
|
|
||||||
$d->key = $d->format( 'Ymd' );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
$d->key = $d->format( 'YmdHis' );
|
|
||||||
return $d;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,135 +0,0 @@
|
|||||||
<?php
|
|
||||||
/*********************************************************************************/
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* iCalcreator, a PHP rfc2445/rfc5545 solution.
|
|
||||||
*
|
|
||||||
* @copyright Copyright (c) 2007-2015 Kjell-Inge Gustafsson, kigkonsult, All rights reserved
|
|
||||||
* @link http://kigkonsult.se/iCalcreator/index.php
|
|
||||||
* @license http://kigkonsult.se/downloads/dl.php?f=LGPL
|
|
||||||
* @package iCalcreator
|
|
||||||
* @version 2.22
|
|
||||||
*/
|
|
||||||
/**
|
|
||||||
* This library is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
|
||||||
* License as published by the Free Software Foundation; either
|
|
||||||
* version 2.1 of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This library is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
|
||||||
* License along with this library; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*/
|
|
||||||
/*********************************************************************************/
|
|
||||||
/**
|
|
||||||
* class for calendar component VALARM
|
|
||||||
*
|
|
||||||
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
|
||||||
* @since 2.5.1 - 2008-10-12
|
|
||||||
*/
|
|
||||||
class valarm extends calendarComponent {
|
|
||||||
/**
|
|
||||||
* @var array $action component property value
|
|
||||||
* @var array $attach component property value
|
|
||||||
* @var array $attendee component property value
|
|
||||||
* @var array $description component property value
|
|
||||||
* @var array $duration component property value
|
|
||||||
* @var array $repeat component property value
|
|
||||||
* @var array $summary component property value
|
|
||||||
* @var array $trigger component property value
|
|
||||||
* @access protected
|
|
||||||
*/
|
|
||||||
protected $action;
|
|
||||||
protected $attach;
|
|
||||||
protected $attendee;
|
|
||||||
protected $description;
|
|
||||||
protected $duration;
|
|
||||||
protected $repeat;
|
|
||||||
protected $summary;
|
|
||||||
protected $trigger;
|
|
||||||
/**
|
|
||||||
* constructor for calendar component VALARM object
|
|
||||||
*
|
|
||||||
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
|
||||||
* @since 2.8.2 - 2011-05-01
|
|
||||||
* @param array $config
|
|
||||||
* @uses valarm::calendarComponent()
|
|
||||||
* @uses valarm::$action
|
|
||||||
* @uses valarm::$attach
|
|
||||||
* @uses valarm::$attendee
|
|
||||||
* @uses valarm::$description
|
|
||||||
* @uses valarm::$duration
|
|
||||||
* @uses valarm::$repeat
|
|
||||||
* @uses valarm::$summary
|
|
||||||
* @uses valarm::$trigger
|
|
||||||
* @uses valarm::$xprop
|
|
||||||
* @uses calendarComponent::setConfig()
|
|
||||||
*/
|
|
||||||
function valarm( $config = array()) {
|
|
||||||
$this->calendarComponent();
|
|
||||||
$this->action = '';
|
|
||||||
$this->attach = '';
|
|
||||||
$this->attendee = '';
|
|
||||||
$this->description = '';
|
|
||||||
$this->duration = '';
|
|
||||||
$this->repeat = '';
|
|
||||||
$this->summary = '';
|
|
||||||
$this->trigger = '';
|
|
||||||
$this->xprop = '';
|
|
||||||
if( defined( 'ICAL_LANG' ) && !isset( $config['language'] ))
|
|
||||||
$config['language'] = ICAL_LANG;
|
|
||||||
if( !isset( $config['allowEmpty'] )) $config['allowEmpty'] = TRUE;
|
|
||||||
if( !isset( $config['nl'] )) $config['nl'] = "\r\n";
|
|
||||||
if( !isset( $config['format'] )) $config['format'] = 'iCal';
|
|
||||||
if( !isset( $config['delimiter'] )) $config['delimiter'] = DIRECTORY_SEPARATOR;
|
|
||||||
$this->setConfig( $config );
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* create formatted output for calendar component VALARM object instance
|
|
||||||
*
|
|
||||||
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
|
||||||
* @since 2.5.1 - 2008-10-22
|
|
||||||
* @param array $xcaldecl
|
|
||||||
* @uses calendarComponent::_createFormat()
|
|
||||||
* @uses calendarComponent::$componentStart1
|
|
||||||
* @uses calendarComponent::$componentStart2
|
|
||||||
* @uses calendarComponent::$nl
|
|
||||||
* @uses calendarComponent::createAction()
|
|
||||||
* @uses calendarComponent::createAttach()
|
|
||||||
* @uses calendarComponent::createAttendee()
|
|
||||||
* @uses calendarComponent::createDescription()
|
|
||||||
* @uses calendarComponent::createDuration()
|
|
||||||
* @uses calendarComponent::createRepeat()
|
|
||||||
* @uses calendarComponent::createSummary()
|
|
||||||
* @uses calendarComponent::createTrigger()
|
|
||||||
* @uses calendarComponent::createXprop()
|
|
||||||
* @uses calendarComponent::$componentEnd1
|
|
||||||
* @uses calendarComponent::$componentEnd2
|
|
||||||
* @uses calendarComponent::$xcaldecl
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
function createComponent( & $xcaldecl ) {
|
|
||||||
$objectname = $this->_createFormat();
|
|
||||||
$component = $this->componentStart1.$objectname.$this->componentStart2.$this->nl;
|
|
||||||
$component .= $this->createAction();
|
|
||||||
$component .= $this->createAttach();
|
|
||||||
$component .= $this->createAttendee();
|
|
||||||
$component .= $this->createDescription();
|
|
||||||
$component .= $this->createDuration();
|
|
||||||
$component .= $this->createRepeat();
|
|
||||||
$component .= $this->createSummary();
|
|
||||||
$component .= $this->createTrigger();
|
|
||||||
$component .= $this->createXprop();
|
|
||||||
$component .= $this->componentEnd1.$objectname.$this->componentEnd2;
|
|
||||||
if( is_array( $this->xcaldecl ) && ( 0 < count( $this->xcaldecl ))) {
|
|
||||||
foreach( $this->xcaldecl as $localxcaldecl )
|
|
||||||
$xcaldecl[] = $localxcaldecl;
|
|
||||||
}
|
|
||||||
return $component;
|
|
||||||
}
|
|
||||||
}
|
|
File diff suppressed because it is too large
Load Diff
@ -1,269 +0,0 @@
|
|||||||
<?php
|
|
||||||
/*********************************************************************************/
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* iCalcreator, a PHP rfc2445/rfc5545 solution.
|
|
||||||
*
|
|
||||||
* @copyright Copyright (c) 2007-2015 Kjell-Inge Gustafsson, kigkonsult, All rights reserved
|
|
||||||
* @link http://kigkonsult.se/iCalcreator/index.php
|
|
||||||
* @license http://kigkonsult.se/downloads/dl.php?f=LGPL
|
|
||||||
* @package iCalcreator
|
|
||||||
* @version 2.22
|
|
||||||
*/
|
|
||||||
/**
|
|
||||||
* This library is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
|
||||||
* License as published by the Free Software Foundation; either
|
|
||||||
* version 2.1 of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This library is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
|
||||||
* License along with this library; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*/
|
|
||||||
/*********************************************************************************/
|
|
||||||
/**
|
|
||||||
* class for calendar component VEVENT
|
|
||||||
*
|
|
||||||
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
|
||||||
* @since 2.5.1 - 2008-10-12
|
|
||||||
*/
|
|
||||||
class vevent extends calendarComponent {
|
|
||||||
/**
|
|
||||||
* @var array $attach component property value
|
|
||||||
* @var array $attendee component property value
|
|
||||||
* @var array $categories component property value
|
|
||||||
* @var array $comment component property value
|
|
||||||
* @var array $contact component property value
|
|
||||||
* @var array $class component property value
|
|
||||||
* @var array $created component property value
|
|
||||||
* @var array $description component property value
|
|
||||||
* @var array $dtend component property value
|
|
||||||
* @var array $dtstart component property value
|
|
||||||
* @var array $duration component property value
|
|
||||||
* @var array $exdate component property value
|
|
||||||
* @var array $exrule component property value
|
|
||||||
* @var array $geo component property value
|
|
||||||
* @var array $lastmodified component property value
|
|
||||||
* @var array $location component property value
|
|
||||||
* @var array $organizer component property value
|
|
||||||
* @var array $priority component property value
|
|
||||||
* @var array $rdate component property value
|
|
||||||
* @var array $recurrenceid component property value
|
|
||||||
* @var array $relatedto component property value
|
|
||||||
* @var array $requeststatus component property value
|
|
||||||
* @var array $resources component property value
|
|
||||||
* @var array $rrule component property value
|
|
||||||
* @var array $sequence component property value
|
|
||||||
* @var array $status component property value
|
|
||||||
* @var array $summary component property value
|
|
||||||
* @var array $transp component property value
|
|
||||||
* @var array $url component property value
|
|
||||||
* @access protected
|
|
||||||
*/
|
|
||||||
protected $attach;
|
|
||||||
protected $attendee;
|
|
||||||
protected $categories;
|
|
||||||
protected $comment;
|
|
||||||
protected $contact;
|
|
||||||
protected $class;
|
|
||||||
protected $created;
|
|
||||||
protected $description;
|
|
||||||
protected $dtend;
|
|
||||||
protected $dtstart;
|
|
||||||
protected $duration;
|
|
||||||
protected $exdate;
|
|
||||||
protected $exrule;
|
|
||||||
protected $geo;
|
|
||||||
protected $lastmodified;
|
|
||||||
protected $location;
|
|
||||||
protected $organizer;
|
|
||||||
protected $priority;
|
|
||||||
protected $rdate;
|
|
||||||
protected $recurrenceid;
|
|
||||||
protected $relatedto;
|
|
||||||
protected $requeststatus;
|
|
||||||
protected $resources;
|
|
||||||
protected $rrule;
|
|
||||||
protected $sequence;
|
|
||||||
protected $status;
|
|
||||||
protected $summary;
|
|
||||||
protected $transp;
|
|
||||||
protected $url;
|
|
||||||
/**
|
|
||||||
* constructor for calendar component VEVENT object
|
|
||||||
*
|
|
||||||
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
|
||||||
* @since 2.8.2 - 2011-05-01
|
|
||||||
* @param array $config
|
|
||||||
* @uses vevent::calendarComponent()
|
|
||||||
* @uses vevent::$attach
|
|
||||||
* @uses vevent::$attendee
|
|
||||||
* @uses vevent::$categories
|
|
||||||
* @uses vevent::$class
|
|
||||||
* @uses vevent::$comment
|
|
||||||
* @uses vevent::$contact
|
|
||||||
* @uses vevent::$created
|
|
||||||
* @uses vevent::$description
|
|
||||||
* @uses vevent::$dtstart
|
|
||||||
* @uses vevent::$dtend
|
|
||||||
* @uses vevent::$duration
|
|
||||||
* @uses vevent::$exdate
|
|
||||||
* @uses vevent::$exrule
|
|
||||||
* @uses vevent::$geo
|
|
||||||
* @uses vevent::$lastmodified
|
|
||||||
* @uses vevent::$location
|
|
||||||
* @uses vevent::$organizer
|
|
||||||
* @uses vevent::$priority
|
|
||||||
* @uses vevent::$rdate
|
|
||||||
* @uses vevent::$recurrenceid
|
|
||||||
* @uses vevent::$relatedto
|
|
||||||
* @uses vevent::$requeststatus
|
|
||||||
* @uses vevent::$resources
|
|
||||||
* @uses vevent::$rrule
|
|
||||||
* @uses vevent::$sequence
|
|
||||||
* @uses vevent::$status
|
|
||||||
* @uses vevent::$summary
|
|
||||||
* @uses vevent::$transp
|
|
||||||
* @uses vevent::$url
|
|
||||||
* @uses vevent::$xprop
|
|
||||||
* @uses vevent::$components
|
|
||||||
* @uses calendarComponent::setConfig()
|
|
||||||
*/
|
|
||||||
function vevent( $config = array()) {
|
|
||||||
$this->calendarComponent();
|
|
||||||
$this->attach = '';
|
|
||||||
$this->attendee = '';
|
|
||||||
$this->categories = '';
|
|
||||||
$this->class = '';
|
|
||||||
$this->comment = '';
|
|
||||||
$this->contact = '';
|
|
||||||
$this->created = '';
|
|
||||||
$this->description = '';
|
|
||||||
$this->dtstart = '';
|
|
||||||
$this->dtend = '';
|
|
||||||
$this->duration = '';
|
|
||||||
$this->exdate = '';
|
|
||||||
$this->exrule = '';
|
|
||||||
$this->geo = '';
|
|
||||||
$this->lastmodified = '';
|
|
||||||
$this->location = '';
|
|
||||||
$this->organizer = '';
|
|
||||||
$this->priority = '';
|
|
||||||
$this->rdate = '';
|
|
||||||
$this->recurrenceid = '';
|
|
||||||
$this->relatedto = '';
|
|
||||||
$this->requeststatus = '';
|
|
||||||
$this->resources = '';
|
|
||||||
$this->rrule = '';
|
|
||||||
$this->sequence = '';
|
|
||||||
$this->status = '';
|
|
||||||
$this->summary = '';
|
|
||||||
$this->transp = '';
|
|
||||||
$this->url = '';
|
|
||||||
$this->xprop = '';
|
|
||||||
$this->components = array();
|
|
||||||
if( defined( 'ICAL_LANG' ) && !isset( $config['language'] ))
|
|
||||||
$config['language'] = ICAL_LANG;
|
|
||||||
if( !isset( $config['allowEmpty'] )) $config['allowEmpty'] = TRUE;
|
|
||||||
if( !isset( $config['nl'] )) $config['nl'] = "\r\n";
|
|
||||||
if( !isset( $config['format'] )) $config['format'] = 'iCal';
|
|
||||||
if( !isset( $config['delimiter'] )) $config['delimiter'] = DIRECTORY_SEPARATOR;
|
|
||||||
$this->setConfig( $config );
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* create formatted output for calendar component VEVENT object instance
|
|
||||||
*
|
|
||||||
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
|
||||||
* @since 2.10.16 - 2011-10-28
|
|
||||||
* @param array $xcaldecl
|
|
||||||
* @uses calendarComponent::_createFormat()
|
|
||||||
* @uses calendarComponent::$componentStart1
|
|
||||||
* @uses calendarComponent::$componentStart2
|
|
||||||
* @uses calendarComponent::$nl;
|
|
||||||
* @uses calendarComponent::createUid()
|
|
||||||
* @uses calendarComponent::createDtstamp()
|
|
||||||
* @uses calendarComponent::createAttach()
|
|
||||||
* @uses calendarComponent::createAttendee()
|
|
||||||
* @uses calendarComponent::createCategories()
|
|
||||||
* @uses calendarComponent::createComment()
|
|
||||||
* @uses calendarComponent::createContact()
|
|
||||||
* @uses calendarComponent::createClass()
|
|
||||||
* @uses calendarComponent::createCreated()
|
|
||||||
* @uses calendarComponent::createDescription()
|
|
||||||
* @uses calendarComponent::createDtstart()
|
|
||||||
* @uses calendarComponent::createDtend()
|
|
||||||
* @uses calendarComponent::createDuration()
|
|
||||||
* @uses calendarComponent::createExdate()
|
|
||||||
* @uses calendarComponent::createExrule()
|
|
||||||
* @uses calendarComponent::createGeo()
|
|
||||||
* @uses calendarComponent::createLastModified()
|
|
||||||
* @uses calendarComponent::createLocation()
|
|
||||||
* @uses calendarComponent::createOrganizer()
|
|
||||||
* @uses calendarComponent::createPriority()
|
|
||||||
* @uses calendarComponent::createRdate()
|
|
||||||
* @uses calendarComponent::createRrule()
|
|
||||||
* @uses calendarComponent::createRelatedTo()
|
|
||||||
* @uses calendarComponent::createRequestStatus()
|
|
||||||
* @uses calendarComponent::createRecurrenceid()
|
|
||||||
* @uses calendarComponent::createResources()
|
|
||||||
* @uses calendarComponent::createSequence()
|
|
||||||
* @uses calendarComponent::createStatus()
|
|
||||||
* @uses calendarComponent::createSummary()
|
|
||||||
* @uses calendarComponent::createTransp()
|
|
||||||
* @uses calendarComponent::createUrl()
|
|
||||||
* @uses calendarComponent::createXprop()
|
|
||||||
* @uses calendarComponent::createSubComponent()
|
|
||||||
* @uses calendarComponent::$componentEnd1
|
|
||||||
* @uses calendarComponent::$componentEnd2
|
|
||||||
* @uses calendarComponent::$xcaldecl
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
function createComponent( & $xcaldecl ) {
|
|
||||||
$objectname = $this->_createFormat();
|
|
||||||
$component = $this->componentStart1.$objectname.$this->componentStart2.$this->nl;
|
|
||||||
$component .= $this->createUid();
|
|
||||||
$component .= $this->createDtstamp();
|
|
||||||
$component .= $this->createAttach();
|
|
||||||
$component .= $this->createAttendee();
|
|
||||||
$component .= $this->createCategories();
|
|
||||||
$component .= $this->createComment();
|
|
||||||
$component .= $this->createContact();
|
|
||||||
$component .= $this->createClass();
|
|
||||||
$component .= $this->createCreated();
|
|
||||||
$component .= $this->createDescription();
|
|
||||||
$component .= $this->createDtstart();
|
|
||||||
$component .= $this->createDtend();
|
|
||||||
$component .= $this->createDuration();
|
|
||||||
$component .= $this->createExdate();
|
|
||||||
$component .= $this->createExrule();
|
|
||||||
$component .= $this->createGeo();
|
|
||||||
$component .= $this->createLastModified();
|
|
||||||
$component .= $this->createLocation();
|
|
||||||
$component .= $this->createOrganizer();
|
|
||||||
$component .= $this->createPriority();
|
|
||||||
$component .= $this->createRdate();
|
|
||||||
$component .= $this->createRrule();
|
|
||||||
$component .= $this->createRelatedTo();
|
|
||||||
$component .= $this->createRequestStatus();
|
|
||||||
$component .= $this->createRecurrenceid();
|
|
||||||
$component .= $this->createResources();
|
|
||||||
$component .= $this->createSequence();
|
|
||||||
$component .= $this->createStatus();
|
|
||||||
$component .= $this->createSummary();
|
|
||||||
$component .= $this->createTransp();
|
|
||||||
$component .= $this->createUrl();
|
|
||||||
$component .= $this->createXprop();
|
|
||||||
$component .= $this->createSubComponent();
|
|
||||||
$component .= $this->componentEnd1.$objectname.$this->componentEnd2;
|
|
||||||
if( is_array( $this->xcaldecl ) && ( 0 < count( $this->xcaldecl ))) {
|
|
||||||
foreach( $this->xcaldecl as $localxcaldecl )
|
|
||||||
$xcaldecl[] = $localxcaldecl;
|
|
||||||
}
|
|
||||||
return $component;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,149 +0,0 @@
|
|||||||
<?php
|
|
||||||
/*********************************************************************************/
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* iCalcreator, a PHP rfc2445/rfc5545 solution.
|
|
||||||
*
|
|
||||||
* @copyright Copyright (c) 2007-2015 Kjell-Inge Gustafsson, kigkonsult, All rights reserved
|
|
||||||
* @link http://kigkonsult.se/iCalcreator/index.php
|
|
||||||
* @license http://kigkonsult.se/downloads/dl.php?f=LGPL
|
|
||||||
* @package iCalcreator
|
|
||||||
* @version 2.22
|
|
||||||
*/
|
|
||||||
/**
|
|
||||||
* This library is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
|
||||||
* License as published by the Free Software Foundation; either
|
|
||||||
* version 2.1 of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This library is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
|
||||||
* License along with this library; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*/
|
|
||||||
/*********************************************************************************/
|
|
||||||
/**
|
|
||||||
* class for calendar component VFREEBUSY
|
|
||||||
*
|
|
||||||
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
|
||||||
* @since 2.5.1 - 2008-10-12
|
|
||||||
*/
|
|
||||||
class vfreebusy extends calendarComponent {
|
|
||||||
/**
|
|
||||||
* @var array $attendee component property value
|
|
||||||
* @var array $comment component property value
|
|
||||||
* @var array $contact component property value
|
|
||||||
* @var array $dtend component property value
|
|
||||||
* @var array $dtstart component property value
|
|
||||||
* @var array $duration component property value
|
|
||||||
* @var array $freebusy component property value
|
|
||||||
* @var array $organizer component property value
|
|
||||||
* @var array $requeststatus component property value
|
|
||||||
* @var array $url component property value
|
|
||||||
* @access protected
|
|
||||||
*/
|
|
||||||
protected $attendee;
|
|
||||||
protected $comment;
|
|
||||||
protected $contact;
|
|
||||||
protected $dtend;
|
|
||||||
protected $dtstart;
|
|
||||||
protected $duration;
|
|
||||||
protected $freebusy;
|
|
||||||
protected $organizer;
|
|
||||||
protected $requeststatus;
|
|
||||||
protected $url;
|
|
||||||
/**
|
|
||||||
* constructor for calendar component VFREEBUSY object
|
|
||||||
*
|
|
||||||
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
|
||||||
* @since 2.8.2 - 2011-05-01
|
|
||||||
* @param array $config
|
|
||||||
* @uses vjournal::calendarComponent()
|
|
||||||
* @uses vjournal::$attendee
|
|
||||||
* @uses vjournal::$comment
|
|
||||||
* @uses vjournal::$contact
|
|
||||||
* @uses vjournal::$dtend
|
|
||||||
* @uses vjournal::$dtstart
|
|
||||||
* @uses vjournal::$dtduration
|
|
||||||
* @uses vjournal::$organizer
|
|
||||||
* @uses vjournal::$requeststatus
|
|
||||||
* @uses vjournal::$url
|
|
||||||
* @uses vjournal::$xprop
|
|
||||||
* @uses calendarComponent::setConfig()
|
|
||||||
*/
|
|
||||||
function vfreebusy( $config = array()) {
|
|
||||||
$this->calendarComponent();
|
|
||||||
$this->attendee = '';
|
|
||||||
$this->comment = '';
|
|
||||||
$this->contact = '';
|
|
||||||
$this->dtend = '';
|
|
||||||
$this->dtstart = '';
|
|
||||||
$this->duration = '';
|
|
||||||
$this->freebusy = '';
|
|
||||||
$this->organizer = '';
|
|
||||||
$this->requeststatus = '';
|
|
||||||
$this->url = '';
|
|
||||||
$this->xprop = '';
|
|
||||||
if( defined( 'ICAL_LANG' ) && !isset( $config['language'] ))
|
|
||||||
$config['language'] = ICAL_LANG;
|
|
||||||
if( !isset( $config['allowEmpty'] )) $config['allowEmpty'] = TRUE;
|
|
||||||
if( !isset( $config['nl'] )) $config['nl'] = "\r\n";
|
|
||||||
if( !isset( $config['format'] )) $config['format'] = 'iCal';
|
|
||||||
if( !isset( $config['delimiter'] )) $config['delimiter'] = DIRECTORY_SEPARATOR;
|
|
||||||
$this->setConfig( $config );
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* create formatted output for calendar component VFREEBUSY object instance
|
|
||||||
*
|
|
||||||
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
|
||||||
* @since 2.3.1 - 2007-11-19
|
|
||||||
* @param array $xcaldecl
|
|
||||||
* @uses calendarComponent::_createFormat()
|
|
||||||
* @uses calendarComponent::createUid()
|
|
||||||
* @uses calendarComponent::createDtstamp()
|
|
||||||
* @uses calendarComponent::createAttendee()
|
|
||||||
* @uses calendarComponent::createComment()
|
|
||||||
* @uses calendarComponent::createContact()
|
|
||||||
* @uses calendarComponent::createDtstart()
|
|
||||||
* @uses calendarComponent::createDtend()
|
|
||||||
* @uses calendarComponent::createDuration()
|
|
||||||
* @uses calendarComponent::createFreebusy()
|
|
||||||
* @uses calendarComponent::createOrganizer()
|
|
||||||
* @uses calendarComponent::createRequestStatus()
|
|
||||||
* @uses calendarComponent::createUrl()
|
|
||||||
* @uses calendarComponent::createXprop()
|
|
||||||
* @uses calendarComponent::createUrl()
|
|
||||||
* @uses calendarComponent::createXprop()
|
|
||||||
* @uses calendarComponent::$componentEnd1
|
|
||||||
* @uses calendarComponent::$componentEnd2
|
|
||||||
* @uses calendarComponent::$xcaldecl
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
function createComponent( &$xcaldecl ) {
|
|
||||||
$objectname = $this->_createFormat();
|
|
||||||
$component = $this->componentStart1.$objectname.$this->componentStart2.$this->nl;
|
|
||||||
$component .= $this->createUid();
|
|
||||||
$component .= $this->createDtstamp();
|
|
||||||
$component .= $this->createAttendee();
|
|
||||||
$component .= $this->createComment();
|
|
||||||
$component .= $this->createContact();
|
|
||||||
$component .= $this->createDtstart();
|
|
||||||
$component .= $this->createDtend();
|
|
||||||
$component .= $this->createDuration();
|
|
||||||
$component .= $this->createFreebusy();
|
|
||||||
$component .= $this->createOrganizer();
|
|
||||||
$component .= $this->createRequestStatus();
|
|
||||||
$component .= $this->createUrl();
|
|
||||||
$component .= $this->createXprop();
|
|
||||||
$component .= $this->componentEnd1.$objectname.$this->componentEnd2;
|
|
||||||
if( is_array( $this->xcaldecl ) && ( 0 < count( $this->xcaldecl ))) {
|
|
||||||
foreach( $this->xcaldecl as $localxcaldecl )
|
|
||||||
$xcaldecl[] = $localxcaldecl;
|
|
||||||
}
|
|
||||||
return $component;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,222 +0,0 @@
|
|||||||
<?php
|
|
||||||
/*********************************************************************************/
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* iCalcreator, a PHP rfc2445/rfc5545 solution.
|
|
||||||
*
|
|
||||||
* @copyright Copyright (c) 2007-2015 Kjell-Inge Gustafsson, kigkonsult, All rights reserved
|
|
||||||
* @link http://kigkonsult.se/iCalcreator/index.php
|
|
||||||
* @license http://kigkonsult.se/downloads/dl.php?f=LGPL
|
|
||||||
* @package iCalcreator
|
|
||||||
* @version 2.22
|
|
||||||
*/
|
|
||||||
/**
|
|
||||||
* This library is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
|
||||||
* License as published by the Free Software Foundation; either
|
|
||||||
* version 2.1 of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This library is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
|
||||||
* License along with this library; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*/
|
|
||||||
/*********************************************************************************/
|
|
||||||
/**
|
|
||||||
* class for calendar component VJOURNAL
|
|
||||||
*
|
|
||||||
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
|
||||||
* @since 2.5.1 - 2008-10-12
|
|
||||||
*/
|
|
||||||
class vjournal extends calendarComponent {
|
|
||||||
/**
|
|
||||||
* @var array $attach component property value
|
|
||||||
* @var array $attendee component property value
|
|
||||||
* @var array $categories component property value
|
|
||||||
* @var array $comment component property value
|
|
||||||
* @var array $contact component property value
|
|
||||||
* @var array $class component property value
|
|
||||||
* @var array $created component property value
|
|
||||||
* @var array $description component property value
|
|
||||||
* @var array $dtstart component property value
|
|
||||||
* @var array $exdate component property value
|
|
||||||
* @var array $exrule component property value
|
|
||||||
* @var array $lastmodified component property value
|
|
||||||
* @var array $organizer component property value
|
|
||||||
* @var array $rdate component property value
|
|
||||||
* @var array $recurrenceid component property value
|
|
||||||
* @var array $relatedto component property value
|
|
||||||
* @var array $requeststatus component property value
|
|
||||||
* @var array $rrule component property value
|
|
||||||
* @var array $sequence component property value
|
|
||||||
* @var array $status component property value
|
|
||||||
* @var array $summary component property value
|
|
||||||
* @var array $url component property value
|
|
||||||
* @access protected
|
|
||||||
*/
|
|
||||||
protected $attach;
|
|
||||||
protected $attendee;
|
|
||||||
protected $categories;
|
|
||||||
protected $comment;
|
|
||||||
protected $contact;
|
|
||||||
protected $class;
|
|
||||||
protected $created;
|
|
||||||
protected $description;
|
|
||||||
protected $dtstart;
|
|
||||||
protected $exdate;
|
|
||||||
protected $exrule;
|
|
||||||
protected $lastmodified;
|
|
||||||
protected $organizer;
|
|
||||||
protected $rdate;
|
|
||||||
protected $recurrenceid;
|
|
||||||
protected $relatedto;
|
|
||||||
protected $requeststatus;
|
|
||||||
protected $rrule;
|
|
||||||
protected $sequence;
|
|
||||||
protected $status;
|
|
||||||
protected $summary;
|
|
||||||
protected $url;
|
|
||||||
/**
|
|
||||||
* constructor for calendar component VJOURNAL object
|
|
||||||
*
|
|
||||||
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
|
||||||
* @since 2.8.2 - 2011-05-01
|
|
||||||
* @param array $config
|
|
||||||
* @uses vjournal::calendarComponent()
|
|
||||||
* @uses vjournal::$attach
|
|
||||||
* @uses vjournal::$attendee
|
|
||||||
* @uses vjournal::$categories
|
|
||||||
* @uses vjournal::$class
|
|
||||||
* @uses vjournal::$comment
|
|
||||||
* @uses vjournal::$contact
|
|
||||||
* @uses vjournal::$created
|
|
||||||
* @uses vjournal::$description
|
|
||||||
* @uses vjournal::$dtstart
|
|
||||||
* @uses vjournal::$exdate
|
|
||||||
* @uses vjournal::$exrule
|
|
||||||
* @uses vjournal::$lastmodified
|
|
||||||
* @uses vjournal::$organizer
|
|
||||||
* @uses vjournal::$rdate
|
|
||||||
* @uses vjournal::$recurrenceid
|
|
||||||
* @uses vjournal::$relatedto
|
|
||||||
* @uses vjournal::$requeststatus
|
|
||||||
* @uses vjournal::$rrule
|
|
||||||
* @uses vjournal::$sequence
|
|
||||||
* @uses vjournal::$status
|
|
||||||
* @uses vjournal::$summary
|
|
||||||
* @uses vjournal::$url
|
|
||||||
* @uses vjournal::$xprop
|
|
||||||
* @uses calendarComponent::setConfig()
|
|
||||||
*/
|
|
||||||
function vjournal( $config = array()) {
|
|
||||||
$this->calendarComponent();
|
|
||||||
$this->attach = '';
|
|
||||||
$this->attendee = '';
|
|
||||||
$this->categories = '';
|
|
||||||
$this->class = '';
|
|
||||||
$this->comment = '';
|
|
||||||
$this->contact = '';
|
|
||||||
$this->created = '';
|
|
||||||
$this->description = '';
|
|
||||||
$this->dtstart = '';
|
|
||||||
$this->exdate = '';
|
|
||||||
$this->exrule = '';
|
|
||||||
$this->lastmodified = '';
|
|
||||||
$this->organizer = '';
|
|
||||||
$this->rdate = '';
|
|
||||||
$this->recurrenceid = '';
|
|
||||||
$this->relatedto = '';
|
|
||||||
$this->requeststatus = '';
|
|
||||||
$this->rrule = '';
|
|
||||||
$this->sequence = '';
|
|
||||||
$this->status = '';
|
|
||||||
$this->summary = '';
|
|
||||||
$this->url = '';
|
|
||||||
$this->xprop = '';
|
|
||||||
if( defined( 'ICAL_LANG' ) && !isset( $config['language'] ))
|
|
||||||
$config['language'] = ICAL_LANG;
|
|
||||||
if( !isset( $config['allowEmpty'] )) $config['allowEmpty'] = TRUE;
|
|
||||||
if( !isset( $config['nl'] )) $config['nl'] = "\r\n";
|
|
||||||
if( !isset( $config['format'] )) $config['format'] = 'iCal';
|
|
||||||
if( !isset( $config['delimiter'] )) $config['delimiter'] = DIRECTORY_SEPARATOR;
|
|
||||||
$this->setConfig( $config );
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* create formatted output for calendar component VJOURNAL object instance
|
|
||||||
*
|
|
||||||
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
|
||||||
* @since 2.5.1 - 2008-10-12
|
|
||||||
* @param array $xcaldecl
|
|
||||||
* @uses calendarComponent::_createFormat()
|
|
||||||
* @uses calendarComponent::$componentStart1
|
|
||||||
* @uses calendarComponent::$componentStart2
|
|
||||||
* @uses calendarComponent::$nl
|
|
||||||
* @uses calendarComponent::createUid()
|
|
||||||
* @uses calendarComponent::createDtstamp()
|
|
||||||
* @uses calendarComponent::createAttach()
|
|
||||||
* @uses calendarComponent::createAttendee()
|
|
||||||
* @uses calendarComponent::createCategories()
|
|
||||||
* @uses calendarComponent::createClass()
|
|
||||||
* @uses calendarComponent::createComment()
|
|
||||||
* @uses calendarComponent::createContact()
|
|
||||||
* @uses calendarComponent::createDescription()
|
|
||||||
* @uses calendarComponent::createDtstart()
|
|
||||||
* @uses calendarComponent::createExdate()
|
|
||||||
* @uses calendarComponent::createExrule()
|
|
||||||
* @uses calendarComponent::createLastModified()
|
|
||||||
* @uses calendarComponent::createOrganizer()
|
|
||||||
* @uses calendarComponent::createRdate()
|
|
||||||
* @uses calendarComponent::createRelatedTo()
|
|
||||||
* @uses calendarComponent::createRequestStatus()
|
|
||||||
* @uses calendarComponent::createRecurrenceid()
|
|
||||||
* @uses calendarComponent::createRrule()
|
|
||||||
* @uses calendarComponent::createSequence()
|
|
||||||
* @uses calendarComponent::createStatus()
|
|
||||||
* @uses calendarComponent::createSummary()
|
|
||||||
* @uses calendarComponent::createUrl()
|
|
||||||
* @uses calendarComponent::createXprop()
|
|
||||||
* @uses calendarComponent::$componentEnd1
|
|
||||||
* @uses calendarComponent::$componentEnd2
|
|
||||||
* @uses calendarComponent::$xcaldecl
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
function createComponent( &$xcaldecl ) {
|
|
||||||
$objectname = $this->_createFormat();
|
|
||||||
$component = $this->componentStart1.$objectname.$this->componentStart2.$this->nl;
|
|
||||||
$component .= $this->createUid();
|
|
||||||
$component .= $this->createDtstamp();
|
|
||||||
$component .= $this->createAttach();
|
|
||||||
$component .= $this->createAttendee();
|
|
||||||
$component .= $this->createCategories();
|
|
||||||
$component .= $this->createClass();
|
|
||||||
$component .= $this->createComment();
|
|
||||||
$component .= $this->createContact();
|
|
||||||
$component .= $this->createCreated();
|
|
||||||
$component .= $this->createDescription();
|
|
||||||
$component .= $this->createDtstart();
|
|
||||||
$component .= $this->createExdate();
|
|
||||||
$component .= $this->createExrule();
|
|
||||||
$component .= $this->createLastModified();
|
|
||||||
$component .= $this->createOrganizer();
|
|
||||||
$component .= $this->createRdate();
|
|
||||||
$component .= $this->createRequestStatus();
|
|
||||||
$component .= $this->createRecurrenceid();
|
|
||||||
$component .= $this->createRelatedTo();
|
|
||||||
$component .= $this->createRrule();
|
|
||||||
$component .= $this->createSequence();
|
|
||||||
$component .= $this->createStatus();
|
|
||||||
$component .= $this->createSummary();
|
|
||||||
$component .= $this->createUrl();
|
|
||||||
$component .= $this->createXprop();
|
|
||||||
$component .= $this->componentEnd1.$objectname.$this->componentEnd2;
|
|
||||||
if( is_array( $this->xcaldecl ) && ( 0 < count( $this->xcaldecl ))) {
|
|
||||||
foreach( $this->xcaldecl as $localxcaldecl )
|
|
||||||
$xcaldecl[] = $localxcaldecl;
|
|
||||||
}
|
|
||||||
return $component;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,164 +0,0 @@
|
|||||||
<?php
|
|
||||||
/*********************************************************************************/
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* iCalcreator, a PHP rfc2445/rfc5545 solution.
|
|
||||||
*
|
|
||||||
* @copyright Copyright (c) 2007-2015 Kjell-Inge Gustafsson, kigkonsult, All rights reserved
|
|
||||||
* @link http://kigkonsult.se/iCalcreator/index.php
|
|
||||||
* @license http://kigkonsult.se/downloads/dl.php?f=LGPL
|
|
||||||
* @package iCalcreator
|
|
||||||
* @version 2.22
|
|
||||||
*/
|
|
||||||
/**
|
|
||||||
* This library is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
|
||||||
* License as published by the Free Software Foundation; either
|
|
||||||
* version 2.1 of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This library is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
|
||||||
* License along with this library; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*/
|
|
||||||
/*********************************************************************************/
|
|
||||||
/**
|
|
||||||
* class for calendar component VTIMEZONE
|
|
||||||
*
|
|
||||||
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
|
||||||
* @since 2.5.1 - 2008-10-12
|
|
||||||
*/
|
|
||||||
class vtimezone extends calendarComponent {
|
|
||||||
/** @var array $timezonetype component property value */
|
|
||||||
public $timezonetype;
|
|
||||||
/**
|
|
||||||
* @var array $comment component property value
|
|
||||||
* @var array $dtstart component property value
|
|
||||||
* @var array $lastmodified component property value
|
|
||||||
* @var array $rdate component property value
|
|
||||||
* @var array $rrule component property value
|
|
||||||
* @var array $tzid component property value
|
|
||||||
* @var array $tzname component property value
|
|
||||||
* @var array $tzoffsetfrom component property value
|
|
||||||
* @var array $tzoffsetto component property value
|
|
||||||
* @var array $tzurl component property value
|
|
||||||
* @access protected
|
|
||||||
*/
|
|
||||||
protected $comment;
|
|
||||||
protected $dtstart;
|
|
||||||
protected $lastmodified;
|
|
||||||
protected $rdate;
|
|
||||||
protected $rrule;
|
|
||||||
protected $tzid;
|
|
||||||
protected $tzname;
|
|
||||||
protected $tzoffsetfrom;
|
|
||||||
protected $tzoffsetto;
|
|
||||||
protected $tzurl;
|
|
||||||
/**
|
|
||||||
* constructor for calendar component VTIMEZONE object
|
|
||||||
*
|
|
||||||
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
|
||||||
* @since 2.8.2 - 2011-05-01
|
|
||||||
* @param mixed $timezonetype default FALSE ( STANDARD / DAYLIGHT )
|
|
||||||
* @param array $config
|
|
||||||
* @uses vtimezone::$timezonetype
|
|
||||||
* @uses vtimezone::calendarComponent()
|
|
||||||
* @uses vtimezone::$comment
|
|
||||||
* @uses vtimezone::$dtstart
|
|
||||||
* @uses vtimezone::$lastmodified
|
|
||||||
* @uses vtimezone::$rdate
|
|
||||||
* @uses vtimezone::$rrule
|
|
||||||
* @uses vtimezone::$tzid
|
|
||||||
* @uses vtimezone::$tzname
|
|
||||||
* @uses vtimezone::$tzoffsetfrom
|
|
||||||
* @uses vtimezone::$tzoffsetto
|
|
||||||
* @uses vtimezone::$tzurl
|
|
||||||
* @uses vtimezone::$xprop
|
|
||||||
* @uses vtimezone::$components
|
|
||||||
* @uses calendarComponent::setConfig()
|
|
||||||
*/
|
|
||||||
function vtimezone( $timezonetype=FALSE, $config = array()) {
|
|
||||||
if( is_array( $timezonetype )) {
|
|
||||||
$config = $timezonetype;
|
|
||||||
$timezonetype = FALSE;
|
|
||||||
}
|
|
||||||
if( !$timezonetype )
|
|
||||||
$this->timezonetype = 'VTIMEZONE';
|
|
||||||
else
|
|
||||||
$this->timezonetype = strtoupper( $timezonetype );
|
|
||||||
$this->calendarComponent();
|
|
||||||
$this->comment = '';
|
|
||||||
$this->dtstart = '';
|
|
||||||
$this->lastmodified = '';
|
|
||||||
$this->rdate = '';
|
|
||||||
$this->rrule = '';
|
|
||||||
$this->tzid = '';
|
|
||||||
$this->tzname = '';
|
|
||||||
$this->tzoffsetfrom = '';
|
|
||||||
$this->tzoffsetto = '';
|
|
||||||
$this->tzurl = '';
|
|
||||||
$this->xprop = '';
|
|
||||||
$this->components = array();
|
|
||||||
if( defined( 'ICAL_LANG' ) && !isset( $config['language'] ))
|
|
||||||
$config['language'] = ICAL_LANG;
|
|
||||||
if( !isset( $config['allowEmpty'] )) $config['allowEmpty'] = TRUE;
|
|
||||||
if( !isset( $config['nl'] )) $config['nl'] = "\r\n";
|
|
||||||
if( !isset( $config['format'] )) $config['format'] = 'iCal';
|
|
||||||
if( !isset( $config['delimiter'] )) $config['delimiter'] = DIRECTORY_SEPARATOR;
|
|
||||||
$this->setConfig( $config );
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* create formatted output for calendar component VTIMEZONE object instance
|
|
||||||
*
|
|
||||||
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
|
||||||
* @since 2.5.1 - 2008-10-25
|
|
||||||
* @param array $xcaldecl
|
|
||||||
* @uses calendarComponent::_createFormat()
|
|
||||||
* @uses calendarComponent::$componentStart1
|
|
||||||
* @uses calendarComponent::$componentStart2
|
|
||||||
* @uses calendarComponent::$nl
|
|
||||||
* @uses calendarComponent::createTzid()
|
|
||||||
* @uses calendarComponent::createLastModified()
|
|
||||||
* @uses calendarComponent::createTzurl()
|
|
||||||
* @uses calendarComponent::createDtstart()
|
|
||||||
* @uses calendarComponent::createTzoffsetfrom()
|
|
||||||
* @uses calendarComponent::createTzoffsetto()
|
|
||||||
* @uses calendarComponent::createComment()
|
|
||||||
* @uses calendarComponent::createRdate()
|
|
||||||
* @uses calendarComponent::createRrule()
|
|
||||||
* @uses calendarComponent::createTzname()
|
|
||||||
* @uses calendarComponent::createXprop()
|
|
||||||
* @uses calendarComponent::createSubComponent()
|
|
||||||
* @uses calendarComponent::createXprop()
|
|
||||||
* @uses calendarComponent::$componentEnd1
|
|
||||||
* @uses calendarComponent::$componentEnd2
|
|
||||||
* @uses calendarComponent::$xcaldecl
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
function createComponent( &$xcaldecl ) {
|
|
||||||
$objectname = $this->_createFormat();
|
|
||||||
$component = $this->componentStart1.$objectname.$this->componentStart2.$this->nl;
|
|
||||||
$component .= $this->createTzid();
|
|
||||||
$component .= $this->createLastModified();
|
|
||||||
$component .= $this->createTzurl();
|
|
||||||
$component .= $this->createDtstart();
|
|
||||||
$component .= $this->createTzoffsetfrom();
|
|
||||||
$component .= $this->createTzoffsetto();
|
|
||||||
$component .= $this->createComment();
|
|
||||||
$component .= $this->createRdate();
|
|
||||||
$component .= $this->createRrule();
|
|
||||||
$component .= $this->createTzname();
|
|
||||||
$component .= $this->createXprop();
|
|
||||||
$component .= $this->createSubComponent();
|
|
||||||
$component .= $this->componentEnd1.$objectname.$this->componentEnd2;
|
|
||||||
if( is_array( $this->xcaldecl ) && ( 0 < count( $this->xcaldecl ))) {
|
|
||||||
foreach( $this->xcaldecl as $localxcaldecl )
|
|
||||||
$xcaldecl[] = $localxcaldecl;
|
|
||||||
}
|
|
||||||
return $component;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,273 +0,0 @@
|
|||||||
<?php
|
|
||||||
/*********************************************************************************/
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* A PHP implementation of rfc2445/rfc5545.
|
|
||||||
*
|
|
||||||
* @copyright Copyright (c) 2007-2015 Kjell-Inge Gustafsson, kigkonsult, All rights reserved
|
|
||||||
* @link http://kigkonsult.se/iCalcreator/index.php
|
|
||||||
* @license http://kigkonsult.se/downloads/dl.php?f=LGPL
|
|
||||||
* @package iCalcreator
|
|
||||||
* @version 2.22
|
|
||||||
*/
|
|
||||||
/**
|
|
||||||
* This library is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU Lesser General Public
|
|
||||||
* License as published by the Free Software Foundation; either
|
|
||||||
* version 2.1 of the License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This library is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
* Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public
|
|
||||||
* License along with this library; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*/
|
|
||||||
/*********************************************************************************/
|
|
||||||
/**
|
|
||||||
* class for calendar component VTODO
|
|
||||||
*
|
|
||||||
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
|
||||||
* @since 2.5.1 - 2008-10-12
|
|
||||||
*/
|
|
||||||
class vtodo extends calendarComponent {
|
|
||||||
/**
|
|
||||||
* @var array $attach component property value
|
|
||||||
* @var array $attendee component property value
|
|
||||||
* @var array $categories component property value
|
|
||||||
* @var array $comment component property value
|
|
||||||
* @var array $completed component property value
|
|
||||||
* @var array $contact component property value
|
|
||||||
* @var array $class component property value
|
|
||||||
* @var array $created component property value
|
|
||||||
* @var array $description component property value
|
|
||||||
* @var array $dtstart component property value
|
|
||||||
* @var array $due component property value
|
|
||||||
* @var array $duration component property value
|
|
||||||
* @var array $exdate component property value
|
|
||||||
* @var array $exrule component property value
|
|
||||||
* @var array $geo component property value
|
|
||||||
* @var array $lastmodified component property value
|
|
||||||
* @var array $location component property value
|
|
||||||
* @var array $organizer component property value
|
|
||||||
* @var array $percentcomplete component property value
|
|
||||||
* @var array $priority component property value
|
|
||||||
* @var array $rdate component property value
|
|
||||||
* @var array $recurrenceid component property value
|
|
||||||
* @var array $relatedto component property value
|
|
||||||
* @var array $requeststatus component property value
|
|
||||||
* @var array $resources component property value
|
|
||||||
* @var array $rrule component property value
|
|
||||||
* @var array $sequence component property value
|
|
||||||
* @var array $status component property value
|
|
||||||
* @var array $summary component property value
|
|
||||||
* @var arrayr $url;
|
|
||||||
* @access protected
|
|
||||||
*/
|
|
||||||
protected $attach;
|
|
||||||
protected $attendee;
|
|
||||||
protected $categories;
|
|
||||||
protected $comment;
|
|
||||||
protected $completed;
|
|
||||||
protected $contact;
|
|
||||||
protected $class;
|
|
||||||
protected $created;
|
|
||||||
protected $description;
|
|
||||||
protected $dtstart;
|
|
||||||
protected $due;
|
|
||||||
protected $duration;
|
|
||||||
protected $exdate;
|
|
||||||
protected $exrule;
|
|
||||||
protected $geo;
|
|
||||||
protected $lastmodified;
|
|
||||||
protected $location;
|
|
||||||
protected $organizer;
|
|
||||||
protected $percentcomplete;
|
|
||||||
protected $priority;
|
|
||||||
protected $rdate;
|
|
||||||
protected $recurrenceid;
|
|
||||||
protected $relatedto;
|
|
||||||
protected $requeststatus;
|
|
||||||
protected $resources;
|
|
||||||
protected $rrule;
|
|
||||||
protected $sequence;
|
|
||||||
protected $status;
|
|
||||||
protected $summary;
|
|
||||||
protected $url;
|
|
||||||
/**
|
|
||||||
* constructor for calendar component VTODO object
|
|
||||||
*
|
|
||||||
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
|
||||||
* @since 2.8.2 - 2011-05-01
|
|
||||||
* @param array $config
|
|
||||||
* @uses vtodo::calendarComponent()
|
|
||||||
* @uses vtodo::$attach
|
|
||||||
* @uses vtodo::$attendee
|
|
||||||
* @uses vtodo::$categories
|
|
||||||
* @uses vtodo::$class
|
|
||||||
* @uses vtodo::$comment
|
|
||||||
* @uses vtodo::$completed
|
|
||||||
* @uses vtodo::$contact
|
|
||||||
* @uses vtodo::$created
|
|
||||||
* @uses vtodo::$description
|
|
||||||
* @uses vtodo::$dtstart
|
|
||||||
* @uses vtodo::$due
|
|
||||||
* @uses vtodo::$duration
|
|
||||||
* @uses vtodo::$exdate
|
|
||||||
* @uses vtodo::$exrule
|
|
||||||
* @uses vtodo::$geo
|
|
||||||
* @uses vtodo::$lastmodified
|
|
||||||
* @uses vtodo::$location
|
|
||||||
* @uses vtodo::$organizer
|
|
||||||
* @uses vtodo::$percentcomplete
|
|
||||||
* @uses vtodo::$priority
|
|
||||||
* @uses vtodo::$rdate
|
|
||||||
* @uses vtodo::$recurrenceid
|
|
||||||
* @uses vtodo::$relatedto
|
|
||||||
* @uses vtodo::$requeststatus
|
|
||||||
* @uses vtodo::$resources
|
|
||||||
* @uses vtodo::$rrule
|
|
||||||
* @uses vtodo::$sequence
|
|
||||||
* @uses vtodo::$status
|
|
||||||
* @uses vtodo::$summary
|
|
||||||
* @uses vtodo::$url
|
|
||||||
* @uses vtodo::$xprop
|
|
||||||
* @uses vtodo::$components
|
|
||||||
* @uses calendarComponent::setConfig()
|
|
||||||
*/
|
|
||||||
function vtodo( $config = array()) {
|
|
||||||
$this->calendarComponent();
|
|
||||||
$this->attach = '';
|
|
||||||
$this->attendee = '';
|
|
||||||
$this->categories = '';
|
|
||||||
$this->class = '';
|
|
||||||
$this->comment = '';
|
|
||||||
$this->completed = '';
|
|
||||||
$this->contact = '';
|
|
||||||
$this->created = '';
|
|
||||||
$this->description = '';
|
|
||||||
$this->dtstart = '';
|
|
||||||
$this->due = '';
|
|
||||||
$this->duration = '';
|
|
||||||
$this->exdate = '';
|
|
||||||
$this->exrule = '';
|
|
||||||
$this->geo = '';
|
|
||||||
$this->lastmodified = '';
|
|
||||||
$this->location = '';
|
|
||||||
$this->organizer = '';
|
|
||||||
$this->percentcomplete = '';
|
|
||||||
$this->priority = '';
|
|
||||||
$this->rdate = '';
|
|
||||||
$this->recurrenceid = '';
|
|
||||||
$this->relatedto = '';
|
|
||||||
$this->requeststatus = '';
|
|
||||||
$this->resources = '';
|
|
||||||
$this->rrule = '';
|
|
||||||
$this->sequence = '';
|
|
||||||
$this->status = '';
|
|
||||||
$this->summary = '';
|
|
||||||
$this->url = '';
|
|
||||||
$this->xprop = '';
|
|
||||||
$this->components = array();
|
|
||||||
if( defined( 'ICAL_LANG' ) && !isset( $config['language'] ))
|
|
||||||
$config['language'] = ICAL_LANG;
|
|
||||||
if( !isset( $config['allowEmpty'] )) $config['allowEmpty'] = TRUE;
|
|
||||||
if( !isset( $config['nl'] )) $config['nl'] = "\r\n";
|
|
||||||
if( !isset( $config['format'] )) $config['format'] = 'iCal';
|
|
||||||
if( !isset( $config['delimiter'] )) $config['delimiter'] = DIRECTORY_SEPARATOR;
|
|
||||||
$this->setConfig( $config );
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* create formatted output for calendar component VTODO object instance
|
|
||||||
*
|
|
||||||
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
|
|
||||||
* @since 2.5.1 - 2008-11-07
|
|
||||||
* @param array $xcaldecl
|
|
||||||
* @uses calendarComponent::_createFormat()
|
|
||||||
* @uses calendarComponent::$componentStart1
|
|
||||||
* @uses calendarComponent::$componentStart2
|
|
||||||
* @uses calendarComponent::$nl;
|
|
||||||
* @uses calendarComponent::createUid()
|
|
||||||
* @uses calendarComponent::createDtstamp()
|
|
||||||
* @uses calendarComponent::createAttach()
|
|
||||||
* @uses calendarComponent::createAttendee()
|
|
||||||
* @uses calendarComponent::createCategories()
|
|
||||||
* @uses calendarComponent::createClass()
|
|
||||||
* @uses calendarComponent::createComment()
|
|
||||||
* @uses calendarComponent::createCompleted()
|
|
||||||
* @uses calendarComponent::createContact()
|
|
||||||
* @uses calendarComponent::createDescription()
|
|
||||||
* @uses calendarComponent::createDtstart()
|
|
||||||
* @uses calendarComponent::createDtend()
|
|
||||||
* @uses calendarComponent::createDuration()
|
|
||||||
* @uses calendarComponent::createExdate()
|
|
||||||
* @uses calendarComponent::createExrule()
|
|
||||||
* @uses calendarComponent::createGeo()
|
|
||||||
* @uses calendarComponent::createLastModified()
|
|
||||||
* @uses calendarComponent::createLocation()
|
|
||||||
* @uses calendarComponent::createOrganizer()
|
|
||||||
* @uses calendarComponent::createPriority()
|
|
||||||
* @uses calendarComponent::createRdate()
|
|
||||||
* @uses calendarComponent::createRelatedTo()
|
|
||||||
* @uses calendarComponent::createRequestStatus()
|
|
||||||
* @uses calendarComponent::createRecurrenceid()
|
|
||||||
* @uses calendarComponent::createResources()
|
|
||||||
* @uses calendarComponent::createRrule()
|
|
||||||
* @uses calendarComponent::createSequence()
|
|
||||||
* @uses calendarComponent::createStatus()
|
|
||||||
* @uses calendarComponent::createSummary()
|
|
||||||
* @uses calendarComponent::createUrl()
|
|
||||||
* @uses calendarComponent::createXprop()
|
|
||||||
* @uses calendarComponent::createSubComponent()
|
|
||||||
* @uses calendarComponent::$componentEnd1
|
|
||||||
* @uses calendarComponent::$componentEnd2
|
|
||||||
* @uses calendarComponent::$xcaldecl
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
function createComponent( &$xcaldecl ) {
|
|
||||||
$objectname = $this->_createFormat();
|
|
||||||
$component = $this->componentStart1.$objectname.$this->componentStart2.$this->nl;
|
|
||||||
$component .= $this->createUid();
|
|
||||||
$component .= $this->createDtstamp();
|
|
||||||
$component .= $this->createAttach();
|
|
||||||
$component .= $this->createAttendee();
|
|
||||||
$component .= $this->createCategories();
|
|
||||||
$component .= $this->createClass();
|
|
||||||
$component .= $this->createComment();
|
|
||||||
$component .= $this->createCompleted();
|
|
||||||
$component .= $this->createContact();
|
|
||||||
$component .= $this->createCreated();
|
|
||||||
$component .= $this->createDescription();
|
|
||||||
$component .= $this->createDtstart();
|
|
||||||
$component .= $this->createDue();
|
|
||||||
$component .= $this->createDuration();
|
|
||||||
$component .= $this->createExdate();
|
|
||||||
$component .= $this->createExrule();
|
|
||||||
$component .= $this->createGeo();
|
|
||||||
$component .= $this->createLastModified();
|
|
||||||
$component .= $this->createLocation();
|
|
||||||
$component .= $this->createOrganizer();
|
|
||||||
$component .= $this->createPercentComplete();
|
|
||||||
$component .= $this->createPriority();
|
|
||||||
$component .= $this->createRdate();
|
|
||||||
$component .= $this->createRelatedTo();
|
|
||||||
$component .= $this->createRequestStatus();
|
|
||||||
$component .= $this->createRecurrenceid();
|
|
||||||
$component .= $this->createResources();
|
|
||||||
$component .= $this->createRrule();
|
|
||||||
$component .= $this->createSequence();
|
|
||||||
$component .= $this->createStatus();
|
|
||||||
$component .= $this->createSummary();
|
|
||||||
$component .= $this->createUrl();
|
|
||||||
$component .= $this->createXprop();
|
|
||||||
$component .= $this->createSubComponent();
|
|
||||||
$component .= $this->componentEnd1.$objectname.$this->componentEnd2;
|
|
||||||
if( is_array( $this->xcaldecl ) && ( 0 < count( $this->xcaldecl ))) {
|
|
||||||
foreach( $this->xcaldecl as $localxcaldecl )
|
|
||||||
$xcaldecl[] = $localxcaldecl;
|
|
||||||
}
|
|
||||||
return $component;
|
|
||||||
}
|
|
||||||
}
|
|
@ -21,19 +21,20 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
include_once('ical/class.icalcreator.php');
|
include_once('vendor/autoload.php');
|
||||||
include_once('ical/class.icalparser.php');
|
|
||||||
|
|
||||||
class CalendarModule extends Module {
|
class CalendarModule extends Module
|
||||||
|
{
|
||||||
|
|
||||||
private $DEBUG = false; // enable error_log debugging
|
private $DEBUG = true; // enable error_log debugging
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @constructor
|
* @constructor
|
||||||
* @param $id
|
* @param $id
|
||||||
* @param $data
|
* @param $data
|
||||||
*/
|
*/
|
||||||
public function __construct($id, $data) {
|
public function __construct($id, $data)
|
||||||
|
{
|
||||||
parent::Module($id, $data);
|
parent::Module($id, $data);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -42,21 +43,25 @@ class CalendarModule extends Module {
|
|||||||
* Exception part is used for authentication errors also
|
* Exception part is used for authentication errors also
|
||||||
* @return boolean true on success or false on failure.
|
* @return boolean true on success or false on failure.
|
||||||
*/
|
*/
|
||||||
public function execute() {
|
public function execute()
|
||||||
|
{
|
||||||
$result = false;
|
$result = false;
|
||||||
|
|
||||||
if(!$this->DEBUG) {
|
if (!$this->DEBUG) {
|
||||||
/* disable error printing - otherwise json communication might break... */
|
/* disable error printing - otherwise json communication might break... */
|
||||||
ini_set('display_errors', '0');
|
ini_set('display_errors', '0');
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach($this->data as $actionType => $actionData) {
|
foreach ($this->data as $actionType => $actionData) {
|
||||||
if(isset($actionType)) {
|
if (isset($actionType)) {
|
||||||
try {
|
try {
|
||||||
if($this->DEBUG) {
|
if ($this->DEBUG) {
|
||||||
error_log("exec: " . $actionType);
|
error_log("exec: " . $actionType);
|
||||||
}
|
}
|
||||||
switch($actionType) {
|
switch ($actionType) {
|
||||||
|
case "load":
|
||||||
|
$result = $this->loadCalendar($actionType, $actionData);
|
||||||
|
break;
|
||||||
case "export":
|
case "export":
|
||||||
$result = $this->exportCalendar($actionType, $actionData);
|
$result = $this->exportCalendar($actionType, $actionData);
|
||||||
break;
|
break;
|
||||||
@ -71,11 +76,11 @@ class CalendarModule extends Module {
|
|||||||
}
|
}
|
||||||
|
|
||||||
} catch (MAPIException $e) {
|
} catch (MAPIException $e) {
|
||||||
if($this->DEBUG) {
|
if ($this->DEBUG) {
|
||||||
error_log("mapi exception: " . $e->getMessage());
|
error_log("mapi exception: " . $e->getMessage());
|
||||||
}
|
}
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
if($this->DEBUG) {
|
if ($this->DEBUG) {
|
||||||
error_log("exception: " . $e->getMessage());
|
error_log("exception: " . $e->getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -90,11 +95,12 @@ class CalendarModule extends Module {
|
|||||||
* @param $length the lenght of the generated string
|
* @param $length the lenght of the generated string
|
||||||
* @return string a random string
|
* @return string a random string
|
||||||
*/
|
*/
|
||||||
private function randomstring($length = 6) {
|
private function randomstring($length = 6)
|
||||||
|
{
|
||||||
// $chars - all allowed charakters
|
// $chars - all allowed charakters
|
||||||
$chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
|
$chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890";
|
||||||
|
|
||||||
srand((double)microtime()*1000000);
|
srand((double)microtime() * 1000000);
|
||||||
$i = 0;
|
$i = 0;
|
||||||
$pass = "";
|
$pass = "";
|
||||||
while ($i < $length) {
|
while ($i < $length) {
|
||||||
@ -106,25 +112,14 @@ class CalendarModule extends Module {
|
|||||||
return $pass;
|
return $pass;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Generates the secid file (used to verify the download path)
|
|
||||||
* @param $secid the secid, a random security token
|
|
||||||
*/
|
|
||||||
private function createSecIDFile($secid) {
|
|
||||||
$lockFile = TMP_PATH . "/secid." . $secid;
|
|
||||||
$fh = fopen($lockFile, 'w') or die("can't open secid file");
|
|
||||||
$stringData = date(DATE_RFC822);
|
|
||||||
fwrite($fh, $stringData);
|
|
||||||
fclose($fh);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generates the secid file (used to verify the download path)
|
* Generates the secid file (used to verify the download path)
|
||||||
* @param $time a timestamp
|
* @param $time a timestamp
|
||||||
* @param $incl_time true if date should include time
|
* @param $incl_time true if date should include time
|
||||||
* @ return date object
|
* @ return date object
|
||||||
*/
|
*/
|
||||||
private function getIcalDate($time, $incl_time = true) {
|
private function getIcalDate($time, $incl_time = true)
|
||||||
|
{
|
||||||
return $incl_time ? date('Ymd\THis', $time) : date('Ymd', $time);
|
return $incl_time ? date('Ymd\THis', $time) : date('Ymd', $time);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -133,15 +128,16 @@ class CalendarModule extends Module {
|
|||||||
* @param $vevent pointer to the eventstore
|
* @param $vevent pointer to the eventstore
|
||||||
* @param $event the event to add
|
* @param $event the event to add
|
||||||
*/
|
*/
|
||||||
private function addEvent(&$vevent, $event) {
|
private function addEvent(&$vevent, $event)
|
||||||
|
{
|
||||||
|
|
||||||
$busystate = array("FREE", "TENTATIVE", "BUSY", "OOF");
|
$busystate = array("FREE", "TENTATIVE", "BUSY", "OOF");
|
||||||
$zlabel = array("NONE", "IMPORTANT", "WORK", "PERSONAL", "HOLIDAY", "REQUIRED", "TRAVEL REQUIRED", "PREPARATION REQUIERED", "BIRTHDAY", "SPECIAL DATE", "PHONE INTERVIEW");
|
$zlabel = array("NONE", "IMPORTANT", "WORK", "PERSONAL", "HOLIDAY", "REQUIRED", "TRAVEL REQUIRED", "PREPARATION REQUIERED", "BIRTHDAY", "SPECIAL DATE", "PHONE INTERVIEW");
|
||||||
|
|
||||||
$vevent->setProperty("LOCATION", $event["location"]); // property name - case independent
|
$vevent->setProperty("LOCATION", $event["location"]); // property name - case independent
|
||||||
$vevent->setProperty("SUMMARY", $event["subject"]);
|
$vevent->setProperty("SUMMARY", $event["subject"]);
|
||||||
$vevent->setProperty("DESCRIPTION", str_replace("\n", "\\n",$event["description"]));
|
$vevent->setProperty("DESCRIPTION", str_replace("\n", "\\n", $event["description"]));
|
||||||
$vevent->setProperty("COMMENT", "Exported from Zarafa" );
|
$vevent->setProperty("COMMENT", "Exported from Zarafa");
|
||||||
$vevent->setProperty("ORGANIZER", $event["sent_representing_email_address"]);
|
$vevent->setProperty("ORGANIZER", $event["sent_representing_email_address"]);
|
||||||
$vevent->setProperty("DTSTART", $this->getIcalDate($event["commonstart"]) . "Z");
|
$vevent->setProperty("DTSTART", $this->getIcalDate($event["commonstart"]) . "Z");
|
||||||
$vevent->setProperty("DTEND", $this->getIcalDate($event["commonend"]) . "Z");
|
$vevent->setProperty("DTEND", $this->getIcalDate($event["commonend"]) . "Z");
|
||||||
@ -154,16 +150,16 @@ class CalendarModule extends Module {
|
|||||||
$vevent->setProperty("CLASS", $event["private"] ? "PRIVATE" : "PUBLIC");
|
$vevent->setProperty("CLASS", $event["private"] ? "PRIVATE" : "PUBLIC");
|
||||||
|
|
||||||
// ATTENDEES
|
// ATTENDEES
|
||||||
if(count($event["attendees"]) > 0) {
|
if (count($event["attendees"]) > 0) {
|
||||||
foreach($event["attendees"] as $attendee) {
|
foreach ($event["attendees"] as $attendee) {
|
||||||
$vevent->setProperty("ATTENDEE", $attendee["props"]["smtp_address"]);
|
$vevent->setProperty("ATTENDEE", $attendee["props"]["smtp_address"]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// REMINDERS
|
// REMINDERS
|
||||||
if($event["reminder"]) {
|
if ($event["reminder"]) {
|
||||||
$valarm = & $vevent->newComponent("valarm"); // create an event alarm
|
$valarm = &$vevent->newComponent("valarm"); // create an event alarm
|
||||||
$valarm->setProperty("action", "DISPLAY" );
|
$valarm->setProperty("action", "DISPLAY");
|
||||||
$valarm->setProperty("description", $vevent->getProperty("SUMMARY")); // reuse the event summary
|
$valarm->setProperty("description", $vevent->getProperty("SUMMARY")); // reuse the event summary
|
||||||
$valarm->setProperty("trigger", $this->getIcalDate($event["reminder_time"]) . "Z"); // create alarm trigger (in UTC datetime)
|
$valarm->setProperty("trigger", $this->getIcalDate($event["reminder_time"]) . "Z"); // create alarm trigger (in UTC datetime)
|
||||||
}
|
}
|
||||||
@ -174,7 +170,8 @@ class CalendarModule extends Module {
|
|||||||
* @param $event
|
* @param $event
|
||||||
* @return array with event description/body
|
* @return array with event description/body
|
||||||
*/
|
*/
|
||||||
private function loadEventDescription($event) {
|
private function loadEventDescription($event)
|
||||||
|
{
|
||||||
$entryid = $this->getActionEntryID($event);
|
$entryid = $this->getActionEntryID($event);
|
||||||
$store = $this->getActionStore($event);
|
$store = $this->getActionStore($event);
|
||||||
|
|
||||||
@ -185,7 +182,7 @@ class CalendarModule extends Module {
|
|||||||
|
|
||||||
$data = array();
|
$data = array();
|
||||||
|
|
||||||
if($store && $entryid) {
|
if ($store && $entryid) {
|
||||||
$message = $GLOBALS['operations']->openMessage($store, $entryid);
|
$message = $GLOBALS['operations']->openMessage($store, $entryid);
|
||||||
|
|
||||||
|
|
||||||
@ -193,8 +190,8 @@ class CalendarModule extends Module {
|
|||||||
$data['item'] = $GLOBALS['operations']->getMessageProps($store, $message, $properties, (isset($plaintext) && $plaintext));
|
$data['item'] = $GLOBALS['operations']->getMessageProps($store, $message, $properties, (isset($plaintext) && $plaintext));
|
||||||
|
|
||||||
// if appointment is recurring then only we should get properties of occurence if basedate is supplied
|
// if appointment is recurring then only we should get properties of occurence if basedate is supplied
|
||||||
if($data['item']['props']['recurring'] === true) {
|
if ($data['item']['props']['recurring'] === true) {
|
||||||
if(isset($basedate) && $basedate) {
|
if (isset($basedate) && $basedate) {
|
||||||
$recur = new Recurrence($store, $message);
|
$recur = new Recurrence($store, $message);
|
||||||
|
|
||||||
$exceptionatt = $recur->getExceptionAttachment($basedate);
|
$exceptionatt = $recur->getExceptionAttachment($basedate);
|
||||||
@ -202,7 +199,7 @@ class CalendarModule extends Module {
|
|||||||
// Single occurences are never recurring
|
// Single occurences are never recurring
|
||||||
$data['item']['props']['recurring'] = false;
|
$data['item']['props']['recurring'] = false;
|
||||||
|
|
||||||
if($exceptionatt) {
|
if ($exceptionatt) {
|
||||||
// Existing exception (open existing item, which includes basedate)
|
// Existing exception (open existing item, which includes basedate)
|
||||||
$exceptionattProps = mapi_getprops($exceptionatt, array(PR_ATTACH_NUM));
|
$exceptionattProps = mapi_getprops($exceptionatt, array(PR_ATTACH_NUM));
|
||||||
$exception = mapi_attach_openobj($exceptionatt, 0);
|
$exception = mapi_attach_openobj($exceptionatt, 0);
|
||||||
@ -229,11 +226,11 @@ class CalendarModule extends Module {
|
|||||||
// @FIXME getMessageProps should not return empty string if exception doesn't contain body
|
// @FIXME getMessageProps should not return empty string if exception doesn't contain body
|
||||||
// by this change we can handle a situation where user has set empty string in the body explicitly
|
// by this change we can handle a situation where user has set empty string in the body explicitly
|
||||||
if (!empty($exceptionProps['props']['body']) || !empty($exceptionProps['props']['html_body'])) {
|
if (!empty($exceptionProps['props']['body']) || !empty($exceptionProps['props']['html_body'])) {
|
||||||
if(!empty($exceptionProps['props']['body'])) {
|
if (!empty($exceptionProps['props']['body'])) {
|
||||||
$data['item']['props']['body'] = $exceptionProps['props']['body'];
|
$data['item']['props']['body'] = $exceptionProps['props']['body'];
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!empty($exceptionProps['props']['html_body'])) {
|
if (!empty($exceptionProps['props']['html_body'])) {
|
||||||
$data['item']['props']['html_body'] = $exceptionProps['props']['html_body'];
|
$data['item']['props']['html_body'] = $exceptionProps['props']['html_body'];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -284,12 +281,12 @@ class CalendarModule extends Module {
|
|||||||
$tz = $recur->tz; // no function to do this at the moment
|
$tz = $recur->tz; // no function to do this at the moment
|
||||||
|
|
||||||
// Add the recurrence pattern to the data
|
// Add the recurrence pattern to the data
|
||||||
if(isset($recurpattern) && is_array($recurpattern)) {
|
if (isset($recurpattern) && is_array($recurpattern)) {
|
||||||
$data['item']['props'] += $recurpattern;
|
$data['item']['props'] += $recurpattern;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add the timezone information to the data
|
// Add the timezone information to the data
|
||||||
if(isset($tz) && is_array($tz)) {
|
if (isset($tz) && is_array($tz)) {
|
||||||
$data['item']['props'] += $tz;
|
$data['item']['props'] += $tz;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -304,7 +301,8 @@ class CalendarModule extends Module {
|
|||||||
* @param $event
|
* @param $event
|
||||||
* @return array with event attendees
|
* @return array with event attendees
|
||||||
*/
|
*/
|
||||||
private function loadAttendees($event) {
|
private function loadAttendees($event)
|
||||||
|
{
|
||||||
$entryid = $this->getActionEntryID($event);
|
$entryid = $this->getActionEntryID($event);
|
||||||
$store = $this->getActionStore($event);
|
$store = $this->getActionStore($event);
|
||||||
|
|
||||||
@ -315,7 +313,7 @@ class CalendarModule extends Module {
|
|||||||
|
|
||||||
$data = array();
|
$data = array();
|
||||||
|
|
||||||
if($store && $entryid) {
|
if ($store && $entryid) {
|
||||||
$message = $GLOBALS['operations']->openMessage($store, $entryid);
|
$message = $GLOBALS['operations']->openMessage($store, $entryid);
|
||||||
|
|
||||||
|
|
||||||
@ -332,24 +330,25 @@ class CalendarModule extends Module {
|
|||||||
* @param $actionType
|
* @param $actionType
|
||||||
* @param $actionData
|
* @param $actionData
|
||||||
*/
|
*/
|
||||||
private function exportCalendar($actionType, $actionData) {
|
private function exportCalendar($actionType, $actionData)
|
||||||
|
{
|
||||||
$secid = $this->randomstring();
|
$secid = $this->randomstring();
|
||||||
$this->createSecIDFile($secid);
|
$this->createSecIDFile($secid);
|
||||||
$tmpname = stripslashes($actionData["calendar"] . ".ics." . $this->randomstring(8));
|
$tmpname = stripslashes($actionData["calendar"] . ".ics." . $this->randomstring(8));
|
||||||
$filename = TMP_PATH . "/" . $tmpname . "." . $secid;
|
$filename = TMP_PATH . "/" . $tmpname . "." . $secid;
|
||||||
|
|
||||||
if(!is_writable(TMP_PATH . "/")) {
|
if (!is_writable(TMP_PATH . "/")) {
|
||||||
error_log("could not write to export tmp directory!");
|
error_log("could not write to export tmp directory!");
|
||||||
}
|
}
|
||||||
|
|
||||||
$tz = date("e"); // use php timezone (maybe set up in php.ini, date.timezone)
|
$tz = date("e"); // use php timezone (maybe set up in php.ini, date.timezone)
|
||||||
|
|
||||||
if($this->DEBUG) {
|
if ($this->DEBUG) {
|
||||||
error_log("PHP Timezone: " . $tz);
|
error_log("PHP Timezone: " . $tz);
|
||||||
}
|
}
|
||||||
|
|
||||||
$config = array(
|
$config = array(
|
||||||
"language" => substr($GLOBALS["settings"]->get("zarafa/v1/main/language"),0,2),
|
"language" => substr($GLOBALS["settings"]->get("zarafa/v1/main/language"), 0, 2),
|
||||||
"directory" => TMP_PATH . "/",
|
"directory" => TMP_PATH . "/",
|
||||||
"filename" => $tmpname . "." . $secid,
|
"filename" => $tmpname . "." . $secid,
|
||||||
"unique_id" => "zarafa-export-plugin",
|
"unique_id" => "zarafa-export-plugin",
|
||||||
@ -366,11 +365,11 @@ class CalendarModule extends Module {
|
|||||||
iCalUtilityFunctions::createTimezone($v, $tz, $xprops); // create timezone object in calendar
|
iCalUtilityFunctions::createTimezone($v, $tz, $xprops); // create timezone object in calendar
|
||||||
|
|
||||||
|
|
||||||
foreach($actionData["data"] as $event) {
|
foreach ($actionData["data"] as $event) {
|
||||||
$event["props"]["description"] = $this->loadEventDescription($event);
|
$event["props"]["description"] = $this->loadEventDescription($event);
|
||||||
$event["props"]["attendees"] = $this->loadAttendees($event);
|
$event["props"]["attendees"] = $this->loadAttendees($event);
|
||||||
|
|
||||||
$vevent = & $v->newComponent("vevent"); // create a new event object
|
$vevent = &$v->newComponent("vevent"); // create a new event object
|
||||||
$this->addEvent($vevent, $event["props"]);
|
$this->addEvent($vevent, $event["props"]);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -384,7 +383,7 @@ class CalendarModule extends Module {
|
|||||||
$this->addActionData($actionType, $response);
|
$this->addActionData($actionType, $response);
|
||||||
$GLOBALS["bus"]->addData($this->getResponseData());
|
$GLOBALS["bus"]->addData($this->getResponseData());
|
||||||
|
|
||||||
if($this->DEBUG) {
|
if ($this->DEBUG) {
|
||||||
error_log("export done, bus data written!");
|
error_log("export done, bus data written!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -394,38 +393,41 @@ class CalendarModule extends Module {
|
|||||||
* @param $actionType
|
* @param $actionType
|
||||||
* @param $actionData
|
* @param $actionData
|
||||||
*/
|
*/
|
||||||
private function importCalendar($actionType, $actionData) {
|
private function importCalendar($actionType, $actionData)
|
||||||
if($this->DEBUG) {
|
{
|
||||||
|
if ($this->DEBUG) {
|
||||||
error_log("PHP Timezone: " . $tz);
|
error_log("PHP Timezone: " . $tz);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(is_readable ($actionData["ics_filepath"])) {
|
if (is_readable($actionData["ics_filepath"])) {
|
||||||
$ical = new ICal($actionData["ics_filepath"], $GLOBALS["settings"]->get("zarafa/v1/plugins/calendarimporter/default_timezone"), $actionData["timezone"], $actionData["ignore_dst"]); // Parse it!
|
$ical = new ICal($actionData["ics_filepath"], $GLOBALS["settings"]->get("zarafa/v1/plugins/calendarimporter/default_timezone"), $actionData["timezone"], $actionData["ignore_dst"]); // Parse it!
|
||||||
|
|
||||||
if(isset($ical->errors)) {
|
if (isset($ical->errors)) {
|
||||||
$response['status'] = false;
|
$response['status'] = false;
|
||||||
$response['message']= $ical->errors;
|
$response['message'] = $ical->errors;
|
||||||
} else if(!$ical->hasEvents()) {
|
} else {
|
||||||
|
if (!$ical->hasEvents()) {
|
||||||
$response['status'] = false;
|
$response['status'] = false;
|
||||||
$response['message']= "No events in ics file";
|
$response['message'] = "No events in ics file";
|
||||||
} else {
|
} else {
|
||||||
$response['status'] = true;
|
$response['status'] = true;
|
||||||
$response['parsed_file']= $actionData["ics_filepath"];
|
$response['parsed_file'] = $actionData["ics_filepath"];
|
||||||
$response['parsed'] = array (
|
$response['parsed'] = array(
|
||||||
'timezone' => $ical->timezone(),
|
'timezone' => $ical->timezone(),
|
||||||
'calendar' => $ical->calendar(),
|
'calendar' => $ical->calendar(),
|
||||||
'events' => $ical->events()
|
'events' => $ical->events()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
$response['status'] = false;
|
$response['status'] = false;
|
||||||
$response['message']= "File could not be read by server";
|
$response['message'] = "File could not be read by server";
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->addActionData($actionType, $response);
|
$this->addActionData($actionType, $response);
|
||||||
$GLOBALS["bus"]->addData($this->getResponseData());
|
$GLOBALS["bus"]->addData($this->getResponseData());
|
||||||
|
|
||||||
if($this->DEBUG) {
|
if ($this->DEBUG) {
|
||||||
error_log("parsing done, bus data written!");
|
error_log("parsing done, bus data written!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -436,16 +438,17 @@ class CalendarModule extends Module {
|
|||||||
* @param $actionData
|
* @param $actionData
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
private function getAttachmentPath($actionType, $actionData) {
|
private function getAttachmentPath($actionType, $actionData)
|
||||||
|
{
|
||||||
// Get store id
|
// Get store id
|
||||||
$storeid = false;
|
$storeid = false;
|
||||||
if(isset($actionData["store"])) {
|
if (isset($actionData["store"])) {
|
||||||
$storeid = $actionData["store"];
|
$storeid = $actionData["store"];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get message entryid
|
// Get message entryid
|
||||||
$entryid = false;
|
$entryid = false;
|
||||||
if(isset($actionData["entryid"])) {
|
if (isset($actionData["entryid"])) {
|
||||||
$entryid = $actionData["entryid"];
|
$entryid = $actionData["entryid"];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -454,41 +457,40 @@ class CalendarModule extends Module {
|
|||||||
|
|
||||||
// Get number of attachment which should be opened.
|
// Get number of attachment which should be opened.
|
||||||
$attachNum = false;
|
$attachNum = false;
|
||||||
if(isset($actionData["attachNum"])) {
|
if (isset($actionData["attachNum"])) {
|
||||||
$attachNum = $actionData["attachNum"];
|
$attachNum = $actionData["attachNum"];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if storeid and entryid isset
|
// Check if storeid and entryid isset
|
||||||
if($storeid && $entryid) {
|
if ($storeid && $entryid) {
|
||||||
// Open the store
|
// Open the store
|
||||||
$store = $GLOBALS["mapisession"]->openMessageStore(hex2bin($storeid));
|
$store = $GLOBALS["mapisession"]->openMessageStore(hex2bin($storeid));
|
||||||
|
|
||||||
if($store) {
|
if ($store) {
|
||||||
// Open the message
|
// Open the message
|
||||||
$message = mapi_msgstore_openentry($store, hex2bin($entryid));
|
$message = mapi_msgstore_openentry($store, hex2bin($entryid));
|
||||||
|
|
||||||
if($message) {
|
if ($message) {
|
||||||
$attachment = false;
|
$attachment = false;
|
||||||
|
|
||||||
// Check if attachNum isset
|
// Check if attachNum isset
|
||||||
if($attachNum) {
|
if ($attachNum) {
|
||||||
// Loop through the attachNums, message in message in message ...
|
// Loop through the attachNums, message in message in message ...
|
||||||
for($i = 0; $i < (count($attachNum) - 1); $i++)
|
for ($i = 0; $i < (count($attachNum) - 1); $i++) {
|
||||||
{
|
|
||||||
// Open the attachment
|
// Open the attachment
|
||||||
$tempattach = mapi_message_openattach($message, (int) $attachNum[$i]);
|
$tempattach = mapi_message_openattach($message, (int)$attachNum[$i]);
|
||||||
if($tempattach) {
|
if ($tempattach) {
|
||||||
// Open the object in the attachment
|
// Open the object in the attachment
|
||||||
$message = mapi_attach_openobj($tempattach);
|
$message = mapi_attach_openobj($tempattach);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Open the attachment
|
// Open the attachment
|
||||||
$attachment = mapi_message_openattach($message, (int) $attachNum[(count($attachNum) - 1)]);
|
$attachment = mapi_message_openattach($message, (int)$attachNum[(count($attachNum) - 1)]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if the attachment is opened
|
// Check if the attachment is opened
|
||||||
if($attachment) {
|
if ($attachment) {
|
||||||
|
|
||||||
// Get the props of the attachment
|
// Get the props of the attachment
|
||||||
$props = mapi_attach_getprops($attachment, array(PR_ATTACH_LONG_FILENAME, PR_ATTACH_MIME_TAG, PR_DISPLAY_NAME, PR_ATTACH_METHOD));
|
$props = mapi_attach_getprops($attachment, array(PR_ATTACH_LONG_FILENAME, PR_ATTACH_MIME_TAG, PR_DISPLAY_NAME, PR_ATTACH_METHOD));
|
||||||
@ -498,29 +500,33 @@ class CalendarModule extends Module {
|
|||||||
$filename = "ERROR";
|
$filename = "ERROR";
|
||||||
|
|
||||||
// Set filename
|
// Set filename
|
||||||
if(isset($props[PR_ATTACH_LONG_FILENAME])) {
|
if (isset($props[PR_ATTACH_LONG_FILENAME])) {
|
||||||
$filename = $props[PR_ATTACH_LONG_FILENAME];
|
$filename = $props[PR_ATTACH_LONG_FILENAME];
|
||||||
} else if(isset($props[PR_ATTACH_FILENAME])) {
|
} else {
|
||||||
|
if (isset($props[PR_ATTACH_FILENAME])) {
|
||||||
$filename = $props[PR_ATTACH_FILENAME];
|
$filename = $props[PR_ATTACH_FILENAME];
|
||||||
} else if(isset($props[PR_DISPLAY_NAME])) {
|
} else {
|
||||||
|
if (isset($props[PR_DISPLAY_NAME])) {
|
||||||
$filename = $props[PR_DISPLAY_NAME];
|
$filename = $props[PR_DISPLAY_NAME];
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Set content type
|
// Set content type
|
||||||
if(isset($props[PR_ATTACH_MIME_TAG])) {
|
if (isset($props[PR_ATTACH_MIME_TAG])) {
|
||||||
$contentType = $props[PR_ATTACH_MIME_TAG];
|
$contentType = $props[PR_ATTACH_MIME_TAG];
|
||||||
} else {
|
} else {
|
||||||
// Parse the extension of the filename to get the content type
|
// Parse the extension of the filename to get the content type
|
||||||
if(strrpos($filename, ".") !== false) {
|
if (strrpos($filename, ".") !== false) {
|
||||||
$extension = strtolower(substr($filename, strrpos($filename, ".")));
|
$extension = strtolower(substr($filename, strrpos($filename, ".")));
|
||||||
$contentType = "application/octet-stream";
|
$contentType = "application/octet-stream";
|
||||||
if (is_readable("mimetypes.dat")){
|
if (is_readable("mimetypes.dat")) {
|
||||||
$fh = fopen("mimetypes.dat","r");
|
$fh = fopen("mimetypes.dat", "r");
|
||||||
$ext_found = false;
|
$ext_found = false;
|
||||||
while (!feof($fh) && !$ext_found){
|
while (!feof($fh) && !$ext_found) {
|
||||||
$line = fgets($fh);
|
$line = fgets($fh);
|
||||||
preg_match("/(\.[a-z0-9]+)[ \t]+([^ \t\n\r]*)/i", $line, $result);
|
preg_match("/(\.[a-z0-9]+)[ \t]+([^ \t\n\r]*)/i", $line, $result);
|
||||||
if ($extension == $result[1]){
|
if ($extension == $result[1]) {
|
||||||
$ext_found = true;
|
$ext_found = true;
|
||||||
$contentType = $result[2];
|
$contentType = $result[2];
|
||||||
}
|
}
|
||||||
@ -538,12 +544,12 @@ class CalendarModule extends Module {
|
|||||||
$stat = mapi_stream_stat($stream);
|
$stat = mapi_stream_stat($stream);
|
||||||
// File length = $stat["cb"]
|
// File length = $stat["cb"]
|
||||||
|
|
||||||
$fhandle = fopen($tmpname,'w');
|
$fhandle = fopen($tmpname, 'w');
|
||||||
$buffer = null;
|
$buffer = null;
|
||||||
for($i = 0; $i < $stat["cb"]; $i += BLOCK_SIZE) {
|
for ($i = 0; $i < $stat["cb"]; $i += BLOCK_SIZE) {
|
||||||
// Write stream
|
// Write stream
|
||||||
$buffer = mapi_stream_read($stream, BLOCK_SIZE);
|
$buffer = mapi_stream_read($stream, BLOCK_SIZE);
|
||||||
fwrite($fhandle,$buffer,strlen($buffer));
|
fwrite($fhandle, $buffer, strlen($buffer));
|
||||||
}
|
}
|
||||||
fclose($fhandle);
|
fclose($fhandle);
|
||||||
|
|
||||||
@ -568,6 +574,71 @@ class CalendarModule extends Module {
|
|||||||
$GLOBALS["bus"]->addData($this->getResponseData());
|
$GLOBALS["bus"]->addData($this->getResponseData());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
|
||||||
|
/**
|
||||||
|
* Function that parses the uploaded ics file and posts it via json
|
||||||
|
* @param $actionType
|
||||||
|
* @param $actionData
|
||||||
|
*/
|
||||||
|
private function loadCalendar($actionType, $actionData)
|
||||||
|
{
|
||||||
|
$error = false;
|
||||||
|
$error_msg = "";
|
||||||
|
|
||||||
|
if (is_readable($actionData["ics_filepath"])) {
|
||||||
|
$parser = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
$parser = new vcalendar([
|
||||||
|
"unique_id" => md5($actionData["ics_filepath"]),
|
||||||
|
"filename" => $actionData["ics_filepath"]
|
||||||
|
]);
|
||||||
|
$parser->parse();
|
||||||
|
} catch (Exception $e) {
|
||||||
|
$error = true;
|
||||||
|
$error_msg = $e->getMessage();
|
||||||
|
}
|
||||||
|
if ($error) {
|
||||||
|
$response['status'] = false;
|
||||||
|
$response['message'] = $error_msg;
|
||||||
|
} else {
|
||||||
|
if (iterator_count($parser) == 0) {
|
||||||
|
$response['status'] = false;
|
||||||
|
$response['message'] = "No event in ics file";
|
||||||
|
} else {
|
||||||
|
$response['status'] = true;
|
||||||
|
$response['parsed_file'] = $actionData["ics_filepath"];
|
||||||
|
$response['parsed'] = array(
|
||||||
|
'contacts' => $this->parseCalendarToArray($parser)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$response['status'] = false;
|
||||||
|
$response['message'] = "File could not be read by server";
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->addActionData($actionType, $response);
|
||||||
|
$GLOBALS["bus"]->addData($this->getResponseData());
|
||||||
|
|
||||||
|
if ($this->DEBUG) {
|
||||||
|
error_log("parsing done, bus data written!");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a array with contacts
|
||||||
|
*
|
||||||
|
* @param calendar ics parser object
|
||||||
|
* @return array parsed events
|
||||||
|
* @private
|
||||||
|
*/
|
||||||
|
private function parseCalendarToArray($calendar)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
;
|
||||||
|
|
||||||
?>
|
?>
|
||||||
|
@ -19,24 +19,31 @@
|
|||||||
* License along with this library; if not, write to the Free Software
|
* License along with this library; if not, write to the Free Software
|
||||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
*
|
*
|
||||||
*
|
*/
|
||||||
|
require_once __DIR__ . "/download.php";
|
||||||
|
|
||||||
|
/**
|
||||||
* calendarimporter Plugin
|
* calendarimporter Plugin
|
||||||
*
|
*
|
||||||
* With this plugin you can import a ics file to your zarafa calendar
|
* With this plugin you can import a ics file to your zarafa calendar
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
class Plugincalendarimporter extends Plugin {
|
class Plugincalendarimporter extends Plugin
|
||||||
|
{
|
||||||
/**
|
/**
|
||||||
* Constructor
|
* Constructor
|
||||||
*/
|
*/
|
||||||
function Plugincalendarimporter() {}
|
function Plugincalendarimporter()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function initializes the Plugin and registers all hooks
|
* Function initializes the Plugin and registers all hooks
|
||||||
*
|
*
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
function init() {
|
function init()
|
||||||
|
{
|
||||||
$this->registerHook('server.core.settings.init.before');
|
$this->registerHook('server.core.settings.init.before');
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -47,11 +54,17 @@ class Plugincalendarimporter extends Plugin {
|
|||||||
* @param mixed $data object(s) related to the hook
|
* @param mixed $data object(s) related to the hook
|
||||||
* @return void
|
* @return void
|
||||||
*/
|
*/
|
||||||
function execute($eventID, &$data) {
|
function execute($eventID, &$data)
|
||||||
switch($eventID) {
|
{
|
||||||
|
switch ($eventID) {
|
||||||
case 'server.core.settings.init.before' :
|
case 'server.core.settings.init.before' :
|
||||||
$this->injectPluginSettings($data);
|
$this->injectPluginSettings($data);
|
||||||
break;
|
break;
|
||||||
|
case 'server.index.load.custom':
|
||||||
|
if ($data['name'] == 'download_ics') {
|
||||||
|
DownloadHandler::doDownload();
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -60,7 +73,8 @@ class Plugincalendarimporter extends Plugin {
|
|||||||
* settings.
|
* settings.
|
||||||
* @param Array $data Reference to the data of the triggered hook
|
* @param Array $data Reference to the data of the triggered hook
|
||||||
*/
|
*/
|
||||||
function injectPluginSettings(&$data) {
|
function injectPluginSettings(&$data)
|
||||||
|
{
|
||||||
$data['settingsObj']->addSysAdminDefaults(Array(
|
$data['settingsObj']->addSysAdminDefaults(Array(
|
||||||
'zarafa' => Array(
|
'zarafa' => Array(
|
||||||
'v1' => Array(
|
'v1' => Array(
|
||||||
@ -77,4 +91,5 @@ class Plugincalendarimporter extends Plugin {
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
?>
|
?>
|
||||||
|
Loading…
Reference in New Issue
Block a user