Add upstream plugins

Signed-off-by: Adrian Nöthlich <git@promasu.tech>
This commit is contained in:
2019-10-25 22:42:20 +02:00
parent 5d3c2ec184
commit 290736650a
1186 changed files with 302577 additions and 0 deletions

View File

@@ -0,0 +1,126 @@
<?php
define('SG_ICALREADER_VERSION', '0.7.0');
/**
* A simple iCal parser. Should take care of most stuff for ya
* http://github.com/fangel/SG-iCalendar
*
* Roadmap:
* * Finish FREQUENCY-parsing.
* * Add API for recurring events
*
* A simple example:
* <?php
* $ical = new SG_iCalReader("http://example.com/calendar.ics");
* foreach( $ical->getEvents() As $event ) {
* // Do stuff with the event $event
* }
* ?>
*
* @package SG_iCalReader
* @author Morten Fangel (C) 2008
* @author xonev (C) 2010
* @author Tanguy Pruvot (C) 2010
* @license http://creativecommons.org/licenses/by-sa/2.5/dk/deed.en_GB CC-BY-SA-DK
*/
class SG_iCal {
//objects
public $information; //SG_iCal_VCalendar
public $timezones; //SG_iCal_VTimeZone
protected $events; //SG_iCal_VEvent[]
/**
* Constructs a new iCalReader. You can supply the url now, or later using setUrl
* @param $url string
*/
public function __construct($url = false) {
$this->setUrl($url);
}
/**
* Sets (or resets) the url this reader reads from.
* @param $url string
*/
public function setUrl( $url = false ) {
if( $url !== false ) {
SG_iCal_Parser::Parse($url, $this);
}
}
/**
* Returns the main calendar info. You can then query the returned
* object with ie getTitle().
* @return SG_iCal_VCalendar
*/
public function getCalendarInfo() {
return $this->information;
}
/**
* Sets the calendar info for this calendar
* @param SG_iCal_VCalendar $info
*/
public function setCalendarInfo( SG_iCal_VCalendar $info ) {
$this->information = $info;
}
/**
* Returns a given timezone for the calendar. This is mainly used
* by VEvents to adjust their date-times if they have specified a
* timezone.
*
* If no timezone is given, all timezones in the calendar is
* returned.
*
* @param $tzid string
* @return SG_iCal_VTimeZone
*/
public function getTimeZoneInfo( $tzid = null ) {
if( $tzid == null ) {
return $this->timezones;
} else {
if ( !isset($this->timezones)) {
return null;
}
foreach( $this->timezones AS $tz ) {
if( $tz->getTimeZoneId() == $tzid ) {
return $tz;
}
}
return null;
}
}
/**
* Adds a new timezone to this calendar
* @param SG_iCal_VTimeZone $tz
*/
public function addTimeZone( SG_iCal_VTimeZone $tz ) {
$this->timezones[] = $tz;
}
/**
* Returns the events found
* @return array
*/
public function getEvents() {
return $this->events;
}
/**
* Adds a event to this calendar
* @param SG_iCal_VEvent $event
*/
public function addEvent( SG_iCal_VEvent $event ) {
$this->events[] = $event;
}
}
/**
* For legacy reasons, we keep the name SG_iCalReader..
*/
class SG_iCalReader extends SG_iCal {}

View File

@@ -0,0 +1,64 @@
<?php // BUILD: Remove line
/**
* The wrapper for the main vcalendar data. Used instead of ArrayObject
* so you can easily query for title and description.
* Exposes a iterator that will loop though all the data
*
* @package SG_iCalReader
* @author Morten Fangel (C) 2008
* @license http://creativecommons.org/licenses/by-sa/2.5/dk/deed.en_GB CC-BY-SA-DK
*/
class SG_iCal_VCalendar implements IteratorAggregate {
protected $data;
/**
* Creates a new SG_iCal_VCalendar.
*/
public function __construct($data) {
$this->data = $data;
}
/**
* Returns the title of the calendar. If no title is known, NULL
* will be returned
* @return string
*/
public function getTitle() {
if( isset($this->data['x-wr-calname']) ) {
return $this->data['x-wr-calname'];
} else {
return null;
}
}
/**
* Returns the description of the calendar. If no description is
* known, NULL will be returned.
* @return string
*/
public function getDescription() {
if( isset($this->data['x-wr-caldesc']) ) {
return $this->data['x-wr-caldesc'];
} else {
return null;
}
}
public function getTimezone() {
if( isset($this->data['x-wr-timezone']) ) {
return $this->data['x-wr-timezone'];
} else {
return null;
}
}
/**
* @see IteratorAggregate.getIterator()
*/
public function getIterator() {
return new ArrayIterator($this->data);
}
}
?>

View File

@@ -0,0 +1,292 @@
<?php // BUILD: Remove line
/**
* The wrapper for vevents. Will reveal a unified and simple api for
* the events, which include always finding a start and end (except
* when no end or duration is given) and checking if the event is
* blocking or similar.
*
* Will apply the specified timezone to timestamps if a tzid is
* specified
*
* @package SG_iCalReader
* @author Morten Fangel (C) 2008
* @license http://creativecommons.org/licenses/by-sa/2.5/dk/deed.en_GB CC-BY-SA-DK
*/
class SG_iCal_VEvent {
const DEFAULT_CONFIRMED = true;
public $uid;
public $start;
public $end;
public $summary;
public $description;
public $location;
public $laststart;
public $lastend;
public $recurrence; //RRULE
public $recurex; //EXRULE
public $excluded; //EXDATE(s)
public $added; //RDATE(s)
public $freq; //getFrequency() SG_iCal_Freq
public $data;
/**
* Constructs a new SG_iCal_VEvent. Needs the SG_iCalReader
* supplied so it can query for timezones.
* @param SG_iCal_Line[] $data
* @param SG_iCalReader $ical
*/
public function __construct($data, SG_iCal $ical) {
$this->uid = $data['uid']->getData();
unset($data['uid']);
if ( isset($data['rrule']) ) {
$this->recurrence = new SG_iCal_Recurrence($data['rrule']);
unset($data['rrule']);
}
if ( isset($data['exrule']) ) {
$this->recurex = new SG_iCal_Recurrence($data['exrule']);
unset($data['exrule']);
}
if( isset($data['dtstart']) ) {
$this->start = $this->getTimestamp($data['dtstart'], $ical);
unset($data['dtstart']);
}
if( isset($data['dtend']) ) {
$this->end = $this->getTimestamp($data['dtend'], $ical);
unset($data['dtend']);
} elseif( isset($data['duration']) ) {
$dur = new SG_iCal_Duration( $data['duration']->getData() );
$this->end = $this->start + $dur->getDuration();
unset($data['duration']);
}
//google cal set dtend as end of initial event (duration)
if ( isset($this->recurrence) ) {
//if there is a recurrence rule
//exclusions
if ( isset($data['exdate']) ) {
foreach ($data['exdate'] as $exdate) {
foreach ($exdate->getDataAsArray() as $ts) {
$this->excluded[] = strtotime($ts);
}
}
unset($data['exdate']);
}
//additions
if ( isset($data['rdate']) ) {
foreach ($data['rdate'] as $rdate) {
foreach ($rdate->getDataAsArray() as $ts) {
$this->added[] = strtotime($ts);
}
}
unset($data['rdate']);
}
$until = $this->recurrence->getUntil();
$count = $this->recurrence->getCount();
//check if there is either 'until' or 'count' set
if ( $until ) {
//ok..
} elseif ($count) {
//if count is set, then figure out the last occurrence and set that as the end date
$this->getFrequency();
$until = $this->freq->lastOccurrence($this->start);
} else {
//forever... limit to 3 years
$this->recurrence->setUntil('+3 years');
$until = $this->recurrence->getUntil();
}
//date_default_timezone_set( xx ) needed ?;
$this->laststart = strtotime($until);
$this->lastend = $this->laststart + $this->getDuration();
}
$imports = array('summary','description','location');
foreach( $imports AS $import ) {
if( isset($data[$import]) ) {
$this->$import = $data[$import]->getData();
unset($data[$import]);
}
}
if( isset($this->previous_tz) ) {
date_default_timezone_set($this->previous_tz);
}
$this->data = SG_iCal_Line::Remove_Line($data);
}
/**
* Returns the Event Occurrences Iterator (if recurrence set)
* @return SG_iCal_Freq
*/
public function getFrequency() {
if (! isset($this->freq)) {
if ( isset($this->recurrence) ) {
$this->freq = new SG_iCal_Freq($this->recurrence->rrule, $this->start, $this->excluded, $this->added);
}
}
return $this->freq;
}
/**
* Returns the UID of the event
* @return string
*/
public function getUID() {
return $this->uid;
}
/**
* Returns the summary (or null if none is given) of the event
* @return string
*/
public function getSummary() {
return $this->summary;
}
/**
* Returns the description (or null if none is given) of the event
* @return string
*/
public function getDescription() {
return $this->description;
}
/**
* Returns the location (or null if none is given) of the event
* @return string
*/
public function getLocation() {
return $this->location;
}
/**
* Returns true if the event is blocking (ie not transparent)
* @return bool
*/
public function isBlocking() {
return !(isset($this->data['transp']) && $this->data['transp'] == 'TRANSPARENT');
}
/**
* Returns true if the event is confirmed
* @return bool
*/
public function isConfirmed() {
if( !isset($this->data['status']) ) {
return self::DEFAULT_CONFIRMED;
} else {
return $this->data['status'] == 'CONFIRMED';
}
}
/**
* Returns true if duration is multiple of 86400
* @return bool
*/
public function isWholeDay() {
$dur = $this->getDuration();
if ($dur > 0 && ($dur % 86400) == 0) {
return true;
}
return false;
}
/**
* Returns the timestamp for the beginning of the event
* @return int
*/
public function getStart() {
return $this->start;
}
/**
* Returns the timestamp for the end of the event
* @return int
*/
public function getEnd() {
return $this->end;
}
/**
* Returns the timestamp for the end of the last event
* @return int
*/
public function getRangeEnd() {
return max($this->end,$this->lastend);
}
/**
* Returns the duration of this event in seconds
* @return int
*/
public function getDuration() {
return $this->end - $this->start;
}
/**
* Returns the given property of the event.
* @param string $prop
* @return string
*/
public function getProperty( $prop ) {
if( isset($this->$prop) ) {
return $this->$prop;
} elseif( isset($this->data[$prop]) ) {
return $this->data[$prop];
} else {
return null;
}
}
/**
* Set default timezone (temporary) to get timestamps
* @return string
*/
protected function setLineTimeZone(SG_iCal_Line $line) {
if( isset($line['tzid']) ) {
if (!isset($this->previous_tz)) {
$this->previous_tz = @ date_default_timezone_get();
}
$this->tzid = $line['tzid'];
date_default_timezone_set($this->tzid);
return true;
}
return false;
}
/**
* Calculates the timestamp from a DT line.
* @param $line SG_iCal_Line
* @return int
*/
protected function getTimestamp( SG_iCal_Line $line, SG_iCal $ical ) {
if( isset($line['tzid']) ) {
$this->setLineTimeZone($line);
//$tz = $ical->getTimeZoneInfo($line['tzid']);
//$offset = $tz->getOffset($ts);
//$ts = strtotime(date('D, d M Y H:i:s', $ts) . ' ' . $offset);
}
$ts = strtotime($line->getData());
return $ts;
}
}

View File

@@ -0,0 +1,95 @@
<?php // BUILD: Remove line
/**
* The wrapper for vtimezones. Stores the timezone-id and the setup for
* daylight savings and standard time.
*
* @package SG_iCalReader
* @author Morten Fangel (C) 2008
* @license http://creativecommons.org/licenses/by-sa/2.5/dk/deed.en_GB CC-BY-SA-DK
*/
class SG_iCal_VTimeZone {
protected $tzid;
protected $daylight;
protected $standard;
protected $cache = array();
/**
* Constructs a new SG_iCal_VTimeZone
*/
public function __construct( $data ) {
require_once dirname(__FILE__).'/../helper/SG_iCal_Freq.php'; // BUILD: Remove line
$this->tzid = $data['tzid'];
$this->daylight = $data['daylight'];
$this->standard = $data['standard'];
}
/**
* Returns the timezone-id for this timezone. (Used to
* differentiate between different tzs in a calendar)
* @return string
*/
public function getTimeZoneId() {
return $this->tzid;
}
/**
* Returns the given offset in this timezone for the given
* timestamp. (eg +0200)
* @param int $ts
* @return string
*/
public function getOffset( $ts ) {
$act = $this->getActive($ts);
return $this->{$act}['tzoffsetto'];
}
/**
* Returns the timezone name for the given timestamp (eg CEST)
* @param int $ts
* @return string
*/
public function getTimeZoneName($ts) {
$act = $this->getActive($ts);
return $this->{$act}['tzname'];
}
/**
* Determines which of the daylight or standard is the active
* setting.
* The call is cached for a given timestamp, so a call to
* getOffset and getTimeZoneName with the same ts won't calculate
* the answer twice.
* @param int $ts
* @return string standard|daylight
*/
private function getActive( $ts ) {
if (class_exists('DateTimeZone')) {
//PHP >= 5.2
$tz = new DateTimeZone( $this->tzid );
$date = new DateTime("@$ts", $tz);
return ($date->format('I') == 1) ? 'daylight' : 'standard';
} else {
if( isset($this->cache[$ts]) ) {
return $this->cache[$ts];
}
$daylight_freq = new SG_iCal_Freq($this->daylight['rrule'], strtotime($this->daylight['dtstart']));
$standard_freq = new SG_iCal_Freq($this->standard['rrule'], strtotime($this->standard['dtstart']));
$last_standard = $standard_freq->previousOccurrence($ts);
$last_dst = $daylight_freq->previousOccurrence($ts);
if( $last_dst > $last_standard ) {
$this->cache[$ts] = 'daylight';
} else {
$this->cache[$ts] = 'standard';
}
return $this->cache[$ts];
}
}
}

View File

@@ -0,0 +1,56 @@
<?php // BUILD: Remove line
/**
* A class for calculating how many seconds a duration-string is
*
* @package SG_iCalReader
* @author Morten Fangel (C) 2008
* @license http://creativecommons.org/licenses/by-sa/2.5/dk/deed.en_GB CC-BY-SA-DK
*/
class SG_iCal_Duration {
protected $dur;
/**
* Constructs a new SG_iCal_Duration from a duration-rule.
* The basic build-up of DURATIONs are:
* (["+"] / "-") "P" (dur-date / dur-date + "T" + dur-time / dur-time / dur-week)
* Is solved via a really fugly reg-exp with way to many ()'s..
*
* @param $duration string
*/
public function __construct( $duration ) {
$ts = 0;
if (preg_match('/[\\+\\-]{0,1}P((\d+)W)?((\d+)D)?(T)?((\d+)H)?((\d+)M)?((\d+)S)?/', $duration, $matches) === 1) {
$results = array(
'weeks'=> (int)@ $matches[2],
'days'=> (int)@ $matches[4],
'hours'=> (int)@ $matches[7],
'minutes'=>(int)@ $matches[9],
'seconds'=>(int)@ $matches[11]
);
$ts += $results['seconds'];
$ts += 60 * $results['minutes'];
$ts += 60 * 60 * $results['hours'];
$ts += 24 * 60 * 60 * $results['days'];
$ts += 7 * 24 * 60 * 60 * $results['weeks'];
} else {
// Invalid duration!
}
$dir = ($duration{0} == '-') ? -1 : 1;
$this->dur = $dir * $ts;
}
/**
* Returns the duration in seconds
* @return int
*/
public function getDuration() {
return $this->dur;
}
}

View File

@@ -0,0 +1,42 @@
<?php // BUILD: Remove line
/**
* A simple Factory for converting a section/data pair into the
* corrosponding block-object. If the section isn't known a simple
* ArrayObject is used instead.
*
* @package SG_iCalReader
* @author Morten Fangel (C) 2008
* @license http://creativecommons.org/licenses/by-sa/2.5/dk/deed.en_GB CC-BY-SA-DK
*/
class SG_iCal_Factory {
/**
* Returns a new block-object for the section/data-pair. The list
* of returned objects is:
*
* vcalendar => SG_iCal_VCalendar
* vtimezone => SG_iCal_VTimeZone
* vevent => SG_iCal_VEvent
* * => ArrayObject
*
* @param $ical SG_iCalReader The reader this section/data-pair belongs to
* @param $section string
* @param SG_iCal_Line[]
*/
public static function factory( SG_iCal $ical, $section, $data ) {
switch( $section ) {
case "vcalendar":
require_once dirname(__FILE__).'/../block/SG_iCal_VCalendar.php'; // BUILD: Remove line
return new SG_iCal_VCalendar(SG_iCal_Line::Remove_Line($data), $ical );
case "vtimezone":
require_once dirname(__FILE__).'/../block/SG_iCal_VTimeZone.php'; // BUILD: Remove line
return new SG_iCal_VTimeZone(SG_iCal_Line::Remove_Line($data), $ical );
case "vevent":
require_once dirname(__FILE__).'/../block/SG_iCal_VEvent.php'; // BUILD: Remove line
return new SG_iCal_VEvent($data, $ical );
default:
return new ArrayObject(SG_iCal_Line::Remove_Line((array) $data) );
}
}
}

View File

@@ -0,0 +1,559 @@
<?php // BUILD: Remove line
/**
* A class to store Frequency-rules in. Will allow a easy way to find the
* last and next occurrence of the rule.
*
* No - this is so not pretty. But.. ehh.. You do it better, and I will
* gladly accept patches.
*
* Created by trail-and-error on the examples given in the RFC.
*
* TODO: Update to a better way of doing calculating the different options.
* Instead of only keeping track of the best of the current dates found
* it should instead keep a array of all the calculated dates within the
* period.
* This should fix the issues with multi-rule + multi-rule interference,
* and make it possible to implement the SETPOS rule.
* By pushing the next period onto the stack as the last option will
* (hopefully) remove the need for the awful simpleMode
*
* @package SG_iCalReader
* @author Morten Fangel (C) 2008
* @license http://creativecommons.org/licenses/by-sa/2.5/dk/deed.en_GB CC-BY-SA-DK
*/
class SG_iCal_Freq {
protected $weekdays = array('MO'=>'monday', 'TU'=>'tuesday', 'WE'=>'wednesday', 'TH'=>'thursday', 'FR'=>'friday', 'SA'=>'saturday', 'SU'=>'sunday');
protected $knownRules = array('month', 'weekno', 'day', 'monthday', 'yearday', 'hour', 'minute'); //others : 'setpos', 'second'
protected $ruleModifiers = array('wkst');
protected $simpleMode = true;
protected $rules = array('freq'=>'yearly', 'interval'=>1);
protected $start = 0;
protected $freq = '';
protected $excluded; //EXDATE
protected $added; //RDATE
protected $cache; // getAllOccurrences()
/**
* Constructs a new Freqency-rule
* @param $rule string
* @param $start int Unix-timestamp (important : Need to be the start of Event)
* @param $excluded array of int (timestamps), see EXDATE documentation
* @param $added array of int (timestamps), see RDATE documentation
*/
public function __construct( $rule, $start, $excluded=array(), $added=array(), $exrule = false) {
$this->start = $start;
$this->excluded = array();
$rules = array();
foreach( explode(';', $rule) AS $v) {
if( strpos( $v, '=' ) === false )
continue;
list($k, $v) = explode('=', $v);
$this->rules[ strtolower($k) ] = $v;
}
if( isset($this->rules['until']) && is_string($this->rules['until']) ) {
$this->rules['until'] = strtotime($this->rules['until']);
}
$this->freq = strtolower($this->rules['freq']);
foreach( $this->knownRules AS $rule ) {
if( isset($this->rules['by' . $rule]) ) {
if( $this->isPrerule($rule, $this->freq) ) {
$this->simpleMode = false;
}
}
}
if(!$this->simpleMode) {
if(! (isset($this->rules['byday']) || isset($this->rules['bymonthday']) || isset($this->rules['byyearday']))) {
$this->rules['bymonthday'] = date('d', $this->start);
}
}
//set until, and cache
if( isset($this->rules['count']) ) {
if( $exrule )
$this->rules['count']++;
$cache[$ts] = $ts = $this->start;
for($n=1; $n < $this->rules['count']; $n++) {
$ts = $this->findNext($ts);
$cache[$ts] = $ts;
}
$this->rules['until'] = $ts;
//EXDATE
if (!empty($excluded)) {
foreach($excluded as $ts) {
unset($cache[$ts]);
}
}
//RDATE
if (!empty($added)) {
$cache = $cache + $added;
asort($cache);
}
$this->cache = array_values($cache);
}
$this->excluded = $excluded;
$this->added = $added;
}
/**
* Returns all timestamps array(), build the cache if not made before
* @return array
*/
public function getAllOccurrences() {
if (empty($this->cache)) {
//build cache
$next = $this->firstOccurrence();
while ($next) {
$cache[] = $next;
$next = $this->findNext($next);
}
if (!empty($this->added)) {
$cache = $cache + $this->added;
asort($cache);
}
$this->cache = $cache;
}
return $this->cache;
}
/**
* Returns the previous (most recent) occurrence of the rule from the
* given offset
* @param int $offset
* @return int
*/
public function previousOccurrence( $offset ) {
if (!empty($this->cache)) {
$t2=$this->start;
foreach($this->cache as $ts) {
if ($ts >= $offset)
return $t2;
$t2 = $ts;
}
} else {
$ts = $this->start;
while( ($t2 = $this->findNext($ts)) < $offset) {
if( $t2 == false ){
break;
}
$ts = $t2;
}
}
return $ts;
}
/**
* Returns the next occurrence of this rule after the given offset
* @param int $offset
* @return int
*/
public function nextOccurrence( $offset ) {
if ($offset < $this->start)
return $this->firstOccurrence();
return $this->findNext($offset);
}
/**
* Finds the first occurrence of the rule.
* @return int timestamp
*/
public function firstOccurrence() {
$t = $this->start;
if ( is_array( $this->excluded ) && in_array($t, $this->excluded))
$t = $this->findNext($t);
return $t;
}
/**
* Finds the absolute last occurrence of the rule from the given offset.
* Builds also the cache, if not set before...
* @return int timestamp
*/
public function lastOccurrence() {
//build cache if not done
$this->getAllOccurrences();
//return last timestamp in cache
return end($this->cache);
}
/**
* Calculates the next time after the given offset that the rule
* will apply.
*
* The approach to finding the next is as follows:
* First we establish a timeframe to find timestamps in. This is
* between $offset and the end of the period that $offset is in.
*
* We then loop though all the rules (that is a Prerule in the
* current freq.), and finds the smallest timestamp inside the
* timeframe.
*
* If we find something, we check if the date is a valid recurrence
* (with validDate). If it is, we return it. Otherwise we try to
* find a new date inside the same timeframe (but using the new-
* found date as offset)
*
* If no new timestamps were found in the period, we try in the
* next period
*
* @param int $offset
* @return int
*/
public function findNext($offset) {
if (!empty($this->cache)) {
foreach($this->cache as $ts) {
if ($ts > $offset)
return $ts;
}
}
$debug = false;
//make sure the offset is valid
if( $offset === false || (isset($this->rules['until']) && $offset > $this->rules['until']) ) {
if($debug) echo 'STOP: ' . date('r', $offset) . "\n";
return false;
}
$found = true;
//set the timestamp of the offset (ignoring hours and minutes unless we want them to be
//part of the calculations.
if($debug) echo 'O: ' . date('r', $offset) . "\n";
$hour = (in_array($this->freq, array('hourly','minutely')) && $offset > $this->start) ? date('H', $offset) : date('H', $this->start);
$minute = (($this->freq == 'minutely' || isset($this->rules['byminute'])) && $offset > $this->start) ? date('i', $offset) : date('i', $this->start);
$t = mktime($hour, $minute, date('s', $this->start), date('m', $offset), date('d', $offset), date('Y',$offset));
if($debug) echo 'START: ' . date('r', $t) . "\n";
if( $this->simpleMode ) {
if( $offset < $t ) {
$ts = $t;
if ($ts && in_array($ts, $this->excluded))
$ts = $this->findNext($ts);
} else {
$ts = $this->findStartingPoint( $t, $this->rules['interval'], false );
if( !$this->validDate( $ts ) ) {
$ts = $this->findNext($ts);
}
}
return $ts;
}
$eop = $this->findEndOfPeriod($offset);
if($debug) echo 'EOP: ' . date('r', $eop) . "\n";
foreach( $this->knownRules AS $rule ) {
if( $found && isset($this->rules['by' . $rule]) ) {
if( $this->isPrerule($rule, $this->freq) ) {
$subrules = explode(',', $this->rules['by' . $rule]);
$_t = null;
foreach( $subrules AS $subrule ) {
$imm = call_user_func_array(array($this, 'ruleBy' . $rule), array($subrule, $t));
if( $imm === false ) {
break;
}
if($debug) echo strtoupper($rule) . ': ' . date('r', $imm) . ' A: ' . ((int) ($imm > $offset && $imm < $eop)) . "\n";
if( $imm > $offset && $imm < $eop && ($_t == null || $imm < $_t) ) {
$_t = $imm;
}
}
if( $_t !== null ) {
$t = $_t;
} else {
$found = $this->validDate($t);
}
}
}
}
if( $offset < $this->start && $this->start < $t ) {
$ts = $this->start;
} else if( $found && ($t != $offset)) {
if( $this->validDate( $t ) ) {
if($debug) echo 'OK' . "\n";
$ts = $t;
} else {
if($debug) echo 'Invalid' . "\n";
$ts = $this->findNext($t);
}
} else {
if($debug) echo 'Not found' . "\n";
$ts = $this->findNext( $this->findStartingPoint( $offset, $this->rules['interval'] ) );
}
if ( is_array( $this->excluded ) && $ts && in_array($ts, $this->excluded))
return $this->findNext($ts);
return $ts;
}
/**
* Finds the starting point for the next rule. It goes $interval
* 'freq' forward in time since the given offset
* @param int $offset
* @param int $interval
* @param boolean $truncate
* @return int
*/
private function findStartingPoint( $offset, $interval, $truncate = true ) {
$_freq = ($this->freq == 'daily') ? 'day__' : $this->freq;
$t = '+' . $interval . ' ' . substr($_freq,0,-2) . 's';
if( $_freq == 'monthly' && $truncate ) {
if( $interval > 1) {
$offset = strtotime('+' . ($interval - 1) . ' months ', $offset);
}
$t = '+' . (date('t', $offset) - date('d', $offset) + 1) . ' days';
}
$sp = strtotime($t, $offset);
if( $truncate ) {
$sp = $this->truncateToPeriod($sp, $this->freq);
}
return $sp;
}
/**
* Finds the earliest timestamp posible outside this perioid
* @param int $offset
* @return int
*/
public function findEndOfPeriod($offset) {
return $this->findStartingPoint($offset, 1);
}
/**
* Resets the timestamp to the beginning of the
* period specified by freq
*
* Yes - the fall-through is on purpose!
*
* @param int $time
* @param int $freq
* @return int
*/
private function truncateToPeriod( $time, $freq ) {
$date = getdate($time);
switch( $freq ) {
case "yearly":
$date['mon'] = 1;
case "monthly":
$date['mday'] = 1;
case "daily":
$date['hours'] = 0;
case 'hourly':
$date['minutes'] = 0;
case "minutely":
$date['seconds'] = 0;
break;
case "weekly":
if( date('N', $time) == 1) {
$date['hours'] = 0;
$date['minutes'] = 0;
$date['seconds'] = 0;
} else {
$date = getdate(strtotime("last monday 0:00", $time));
}
break;
}
$d = mktime($date['hours'], $date['minutes'], $date['seconds'], $date['mon'], $date['mday'], $date['year']);
return $d;
}
/**
* Applies the BYDAY rule to the given timestamp
* @param string $rule
* @param int $t
* @return int
*/
private function ruleByday($rule, $t) {
$dir = ($rule{0} == '-') ? -1 : 1;
$dir_t = ($dir == 1) ? 'next' : 'last';
$d = $this->weekdays[substr($rule,-2)];
$s = $dir_t . ' ' . $d . ' ' . date('H:i:s',$t);
if( $rule == substr($rule, -2) ) {
if( date('l', $t) == ucfirst($d) ) {
$s = 'today ' . date('H:i:s',$t);
}
$_t = strtotime($s, $t);
if( $_t == $t && in_array($this->freq, array('monthly', 'yearly')) ) {
// Yes. This is not a great idea.. but hey, it works.. for now
$s = 'next ' . $d . ' ' . date('H:i:s',$t);
$_t = strtotime($s, $_t);
}
return $_t;
} else {
$_f = $this->freq;
if( isset($this->rules['bymonth']) && $this->freq == 'yearly' ) {
$this->freq = 'monthly';
}
if( $dir == -1 ) {
$_t = $this->findEndOfPeriod($t);
} else {
$_t = $this->truncateToPeriod($t, $this->freq);
}
$this->freq = $_f;
$c = preg_replace('/[^0-9]/','',$rule);
$c = ($c == '') ? 1 : $c;
$n = $_t;
while($c > 0 ) {
if( $dir == 1 && $c == 1 && date('l', $t) == ucfirst($d) ) {
$s = 'today ' . date('H:i:s',$t);
}
$n = strtotime($s, $n);
$c--;
}
return $n;
}
}
private function ruleBymonth($rule, $t) {
$_t = mktime(date('H',$t), date('i',$t), date('s',$t), $rule, date('d', $t), date('Y', $t));
if( $t == $_t && isset($this->rules['byday']) ) {
// TODO: this should check if one of the by*day's exists, and have a multi-day value
return false;
} else {
return $_t;
}
}
private function ruleBymonthday($rule, $t) {
if( $rule < 0 ) {
$rule = date('t', $t) + $rule + 1;
}
return mktime(date('H',$t), date('i',$t), date('s',$t), date('m', $t), $rule, date('Y', $t));
}
private function ruleByyearday($rule, $t) {
if( $rule < 0 ) {
$_t = $this->findEndOfPeriod();
$d = '-';
} else {
$_t = $this->truncateToPeriod($t, $this->freq);
$d = '+';
}
$s = $d . abs($rule -1) . ' days ' . date('H:i:s',$t);
return strtotime($s, $_t);
}
private function ruleByweekno($rule, $t) {
if( $rule < 0 ) {
$_t = $this->findEndOfPeriod();
$d = '-';
} else {
$_t = $this->truncateToPeriod($t, $this->freq);
$d = '+';
}
$sub = (date('W', $_t) == 1) ? 2 : 1;
$s = $d . abs($rule - $sub) . ' weeks ' . date('H:i:s',$t);
$_t = strtotime($s, $_t);
return $_t;
}
private function ruleByhour($rule, $t) {
$_t = mktime($rule, date('i',$t), date('s',$t), date('m',$t), date('d', $t), date('Y', $t));
return $_t;
}
private function ruleByminute($rule, $t) {
$_t = mktime(date('h',$t), $rule, date('s',$t), date('m',$t), date('d', $t), date('Y', $t));
return $_t;
}
private function validDate( $t ) {
if( isset($this->rules['until']) && $t > $this->rules['until'] ) {
return false;
}
if ( is_array( $this->excluded ) && in_array($t, $this->excluded)) {
return false;
}
if( isset($this->rules['bymonth']) ) {
$months = explode(',', $this->rules['bymonth']);
if( !in_array(date('m', $t), $months)) {
return false;
}
}
if( isset($this->rules['byday']) ) {
$days = explode(',', $this->rules['byday']);
foreach( $days As $i => $k ) {
$days[$i] = $this->weekdays[ preg_replace('/[^A-Z]/', '', $k)];
}
if( !in_array(strtolower(date('l', $t)), $days)) {
return false;
}
}
if( isset($this->rules['byweekno']) ) {
$weeks = explode(',', $this->rules['byweekno']);
if( !in_array(date('W', $t), $weeks)) {
return false;
}
}
if( isset($this->rules['bymonthday'])) {
$weekdays = explode(',', $this->rules['bymonthday']);
foreach( $weekdays As $i => $k ) {
if( $k < 0 ) {
$weekdays[$i] = date('t', $t) + $k + 1;
}
}
if( !in_array(date('d', $t), $weekdays)) {
return false;
}
}
if( isset($this->rules['byhour']) ) {
$hours = explode(',', $this->rules['byhour']);
if( !in_array(date('H', $t), $hours)) {
return false;
}
}
return true;
}
private function isPrerule($rule, $freq) {
if( $rule == 'year')
return false;
if( $rule == 'month' && $freq == 'yearly')
return true;
if( $rule == 'monthday' && in_array($freq, array('yearly', 'monthly')) && !isset($this->rules['byday']))
return true;
// TODO: is it faster to do monthday first, and ignore day if monthday exists? - prolly by a factor of 4..
if( $rule == 'yearday' && $freq == 'yearly' )
return true;
if( $rule == 'weekno' && $freq == 'yearly' )
return true;
if( $rule == 'day' && in_array($freq, array('yearly', 'monthly', 'weekly')))
return true;
if( $rule == 'hour' && in_array($freq, array('yearly', 'monthly', 'weekly', 'daily')))
return true;
if( $rule == 'minute' )
return true;
return false;
}
}

View File

@@ -0,0 +1,165 @@
<?php // BUILD: Remove line
/**
* A class for storing a single (complete) line of the iCal file.
* Will find the line-type, the arguments and the data of the file and
* store them.
*
* The line-type can be found by querying getIdent(), data via either
* getData() or typecasting to a string.
* Params can be access via the ArrayAccess. A iterator is also avilable
* to iterator over the params.
*
* @package SG_iCalReader
* @author Morten Fangel (C) 2008
* @license http://creativecommons.org/licenses/by-sa/2.5/dk/deed.en_GB CC-BY-SA-DK
*/
class SG_iCal_Line implements ArrayAccess, Countable, IteratorAggregate {
protected $ident;
protected $data;
protected $params = array();
protected $replacements = array('from'=>array('\\,', '\\n', '\\;', '\\:', '\\"'), 'to'=>array(',', "\n", ';', ':', '"'));
/**
* Constructs a new line.
*/
public function __construct( $line ) {
$split = strpos($line, ':');
$idents = explode(';', substr($line, 0, $split));
$ident = strtolower(array_shift($idents));
$data = trim(substr($line, $split+1));
$data = str_replace($this->replacements['from'], $this->replacements['to'], $data);
$params = array();
foreach( $idents AS $v) {
list($k, $v) = explode('=', $v);
$params[ strtolower($k) ] = $v;
}
$this->ident = $ident;
$this->params = $params;
$this->data = $data;
}
/**
* Is this line the begining of a new block?
* @return bool
*/
public function isBegin() {
return $this->ident == 'begin';
}
/**
* Is this line the end of a block?
* @return bool
*/
public function isEnd() {
return $this->ident == 'end';
}
/**
* Returns the line-type (ident) of the line
* @return string
*/
public function getIdent() {
return $this->ident;
}
/**
* Returns the content of the line
* @return string
*/
public function getData() {
return $this->data;
}
/**
* Returns the content of the line
* @return string
*/
public function getDataAsArray() {
if (strpos($this->data,",") !== false) {
return explode(",",$this->data);
}
else
return array($this->data);
}
/**
* A static helper to get a array of SG_iCal_Line's, and calls
* getData() on each of them to lay the data "bare"..
*
* @param SG_iCal_Line[]
* @return array
*/
public static function Remove_Line($arr) {
$rtn = array();
foreach( $arr AS $k => $v ) {
if(is_array($v)) {
$rtn[$k] = self::Remove_Line($v);
} elseif( $v instanceof SG_iCal_Line ) {
$rtn[$k] = $v->getData();
} else {
$rtn[$k] = $v;
}
}
return $rtn;
}
/**
* @see ArrayAccess.offsetExists
*/
public function offsetExists( $param ) {
return isset($this->params[ strtolower($param) ]);
}
/**
* @see ArrayAccess.offsetGet
*/
public function offsetGet( $param ) {
$index = strtolower($param);
if (isset($this->params[ $index ])) {
return $this->params[ $index ];
}
}
/**
* Disabled ArrayAccess requirement
* @see ArrayAccess.offsetSet
*/
public function offsetSet( $param, $val ) {
return false;
}
/**
* Disabled ArrayAccess requirement
* @see ArrayAccess.offsetUnset
*/
public function offsetUnset( $param ) {
return false;
}
/**
* toString method.
* @see getData()
*/
public function __toString() {
return $this->getData();
}
/**
* @see Countable.count
*/
public function count() {
return count($this->params);
}
/**
* @see IteratorAggregate.getIterator
*/
public function getIterator() {
return new ArrayIterator($this->params);
}
}

View File

@@ -0,0 +1,196 @@
<?php // BUILD: Remove line
class SG_iCal_Parser {
/**
* Fetches $url and passes it on to be parsed
* @param string $url
* @param SG_iCal $ical
*/
public static function Parse( $url, SG_iCal $ical ) {
$content = self::Fetch( $url );
$content = self::UnfoldLines($content);
self::_Parse( $content, $ical );
}
/**
* Passes a text string on to be parsed
* @param string $content
* @param SG_iCal $ical
*/
public static function ParseString($content, SG_iCal $ical ) {
$content = self::UnfoldLines($content);
self::_Parse( $content, $ical );
}
/**
* Fetches a resource and tries to make sure it's UTF8
* encoded
* @return string
*/
protected static function Fetch( $resource ) {
$is_utf8 = true;
if( is_file( $resource ) ) {
// The resource is a local file
$content = file_get_contents($resource);
if( ! self::_ValidUtf8( $content ) ) {
// The file doesn't appear to be UTF8
$is_utf8 = false;
}
} else {
// The resource isn't local, so it's assumed to
// be a URL
$c = curl_init();
curl_setopt($c, CURLOPT_URL, $resource);
curl_setopt($c, CURLOPT_RETURNTRANSFER, true);
curl_setopt($c, CURLOPT_USERAGENT, 'PHP/'.PHP_VERSION);
curl_setopt($c, CURLOPT_ENCODING, '');
if( strstr( $resource, 'https' ) !== FALSE ) {
curl_setopt($c, CURLOPT_SSLVERSION, 3);
curl_setopt($c, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($c, CURLOPT_SSL_VERIFYHOST, 2);
}
curl_setopt($c, CURLOPT_COOKIESESSION, true);
curl_setopt($c, CURLOPT_HEADER, true);
curl_setopt($c, CURLOPT_FOLLOWLOCATION, true);
$content = curl_exec($c);
$ct = curl_getinfo($c, CURLINFO_CONTENT_TYPE);
$enc = preg_replace('/^.*charset=([-a-zA-Z0-9]+).*$/', '$1', $ct);
if( ! self::_ValidUtf8( $content ) ) {
// The data isn't utf-8
$is_utf8 = false;
}
}
if( !$is_utf8 ) {
$content = utf8_encode($content);
}
return $content;
}
/**
* Takes the string $content, and creates a array of iCal lines.
* This includes unfolding multi-line entries into a single line.
* @param $content string
*/
protected static function UnfoldLines($content) {
$data = array();
$content = explode("\n", $content);
for( $i=0; $i < count($content); $i++) {
$line = rtrim($content[$i]);
while( isset($content[$i+1]) && strlen($content[$i+1]) > 0 && ($content[$i+1]{0} == ' ' || $content[$i+1]{0} == "\t" )) {
$line .= rtrim(substr($content[++$i],1));
}
$data[] = $line;
}
return $data;
}
/**
* Parses the feed found in content and calls storeSection to store
* parsed data
* @param string $content
* @param SG_iCal $ical
*/
private static function _Parse( $content, SG_iCal $ical ) {
$main_sections = array('vevent', 'vjournal', 'vtodo', 'vtimezone', 'vcalendar');
$array_idents = array('exdate','rdate');
$sections = array();
$section = '';
$current_data = array();
foreach( $content AS $line ) {
$line = new SG_iCal_Line($line);
if( $line->isBegin() ) {
// New block of data, $section = new block
$section = strtolower($line->getData());
$sections[] = strtolower($line->getData());
} elseif( $line->isEnd() ) {
// End of block of data ($removed = just ended block, $section = new top-block)
$removed = array_pop($sections);
$section = end($sections);
if( array_search($removed, $main_sections) !== false ) {
self::StoreSection( $removed, $current_data[$removed], $ical);
$current_data[$removed] = array();
}
} else {
// Data line
foreach( $main_sections AS $s ) {
// Loops though the main sections
if( array_search($s, $sections) !== false ) {
// This section is in the main section
if( $section == $s ) {
// It _is_ the main section else
if (in_array($line->getIdent(), $array_idents))
//exdate could appears more that once
$current_data[$s][$line->getIdent()][] = $line;
else {
$current_data[$s][$line->getIdent()] = $line;
}
} else {
// Sub section
$current_data[$s][$section][$line->getIdent()] = $line;
}
break;
}
}
}
}
$current_data = array();
}
/**
* Stores the data in provided SG_iCal object
* @param string $section eg 'vcalender', 'vevent' etc
* @param string $data
* @param SG_iCal $ical
*/
protected static function storeSection( $section, $data, SG_iCal $ical ) {
$data = SG_iCal_Factory::Factory($ical, $section, $data);
switch( $section ) {
case 'vcalendar':
return $ical->setCalendarInfo( $data );
case 'vevent':
return $ical->addEvent( $data );
case 'vjournal':
case 'vtodo':
return true; // TODO: Implement
case 'vtimezone':
return $ical->addTimeZone( $data );
}
}
/**
* This functions does some regexp checking to see if the value is
* valid UTF-8.
*
* The function is from the book "Building Scalable Web Sites" by
* Cal Henderson.
*
* @param string $data
* @return bool
*/
public static function _ValidUtf8( $data ) {
$rx = '[\xC0-\xDF]([^\x80-\xBF]|$)';
$rx .= '|[\xE0-\xEF].{0,1}([^\x80-\xBF]|$)';
$rx .= '|[\xF0-\xF7].{0,2}([^\x80-\xBF]|$)';
$rx .= '|[\xF8-\xFB].{0,3}([^\x80-\xBF]|$)';
$rx .= '|[\xFC-\xFD].{0,4}([^\x80-\xBF]|$)';
$rx .= '|[\xFE-\xFE].{0,5}([^\x80-\xBF]|$)';
$rx .= '|[\x00-\x7F][\x80-\xBF]';
$rx .= '|[\xC0-\xDF].[\x80-\xBF]';
$rx .= '|[\xE0-\xEF]..[\x80-\xBF]';
$rx .= '|[\xF0-\xF7]...[\x80-\xBF]';
$rx .= '|[\xF8-\xFB]....[\x80-\xBF]';
$rx .= '|[\xFC-\xFD].....[\x80-\xBF]';
$rx .= '|[\xFE-\xFE]......[\x80-\xBF]';
$rx .= '|^[\x80-\xBF]';
return ( ! (bool) preg_match('!'.$rx.'!', $data) );
}
}

View File

@@ -0,0 +1,84 @@
<?php // BUILD: Remove line
/**
* A collection of functions to query the events in a calendar.
*
* @package SG_iCalReader
* @author Morten Fangel (C) 2008
* @license http://creativecommons.org/licenses/by-sa/2.5/dk/deed.en_GB CC-BY-SA-DK
*/
class SG_iCal_Query {
/**
* Returns all events from the calendar between two timestamps
*
* Note that the events returned needs only slightly overlap.
*
* @param SG_iCalReader|array $ical The calendar to query
* @param int $start
* @param int $end
* @return SG_iCal_VEvent[]
*/
public static function Between( $ical, $start, $end ) {
if( $ical instanceof SG_iCalReader ) {
$ical = $ical->getEvents();
}
if( !is_array($ical) ) {
throw new Exception('SG_iCal_Query::Between called with invalid input!');
}
$rtn = array();
foreach( $ical AS $e ) {
if( ($start <= $e->getStart() && $e->getStart() < $end)
|| ($start < $e->getRangeEnd() && $e->getRangeEnd() <= $end) ) {
$rtn[] = $e;
}
}
return $rtn;
}
/**
* Returns all events from the calendar after a given timestamp
*
* @param SG_iCalReader|array $ical The calendar to query
* @param int $start
* @return SG_iCal_VEvent[]
*/
public static function After( $ical, $start ) {
if( $ical instanceof SG_iCalReader ) {
$ical = $ical->getEvents();
}
if( !is_array($ical) ) {
throw new Exception('SG_iCal_Query::After called with invalid input!');
}
$rtn = array();
foreach( $ical AS $e ) {
if($e->getStart() >= $start || $e->getRangeEnd() >= $start) {
$rtn[] = $e;
}
}
return $rtn;
}
/**
* Sorts the events from the calendar after the specified column.
* Column can be all valid entires that getProperty can return.
* So stuff like uid, start, end, summary etc.
* @param SG_iCalReader|array $ical The calendar to query
* @param string $column
* @return SG_iCal_VEvent[]
*/
public static function Sort( $ical, $column ) {
if( $ical instanceof SG_iCalReader ) {
$ical = $ical->getEvents();
}
if( !is_array($ical) ) {
throw new Exception('SG_iCal_Query::Sort called with invalid input!');
}
$cmp = create_function('$a, $b', 'return strcmp($a->getProperty("' . $column . '"), $b->getProperty("' . $column . '"));');
usort($ical, $cmp);
return $ical;
}
}

View File

@@ -0,0 +1,223 @@
<?php // BUILD: Remove line
/**
* A wrapper for recurrence rules in iCalendar. Parses the given line and puts the
* recurrence rules in the correct field of this object.
*
* See http://tools.ietf.org/html/rfc2445 for more information. Page 39 and onward contains more
* information on the recurrence rules themselves. Page 116 and onward contains
* some great examples which were often used for testing.
*
* @package SG_iCalReader
* @author Steven Oxley
* @license http://creativecommons.org/licenses/by-sa/2.5/dk/deed.en_GB CC-BY-SA-DK
*/
class SG_iCal_Recurrence {
public $rrule;
protected $freq;
protected $until;
protected $count;
protected $interval;
protected $bysecond;
protected $byminute;
protected $byhour;
protected $byday;
protected $bymonthday;
protected $byyearday;
protected $byyearno;
protected $bymonth;
protected $bysetpos;
protected $wkst;
/**
* A list of the properties that can have comma-separated lists for values.
* @var array
*/
protected $listProperties = array(
'bysecond', 'byminute', 'byhour', 'byday', 'bymonthday',
'byyearday', 'byyearno', 'bymonth', 'bysetpos'
);
/**
* Creates an recurrence object with a passed in line. Parses the line.
* @param object $line an SG_iCal_Line object which will be parsed to get the
* desired information.
*/
public function __construct(SG_iCal_Line $line) {
$this->parseLine($line->getData());
}
/**
* Parses an 'RRULE' line and sets the member variables of this object.
* Expects a string that looks like this: 'FREQ=WEEKLY;INTERVAL=2;BYDAY=SU,TU,WE'
* @param string $line the line to be parsed
*/
protected function parseLine($line) {
$this->rrule = $line;
//split up the properties
$recurProperties = explode(';', $line);
$recur = array();
//loop through the properties in the line and set their associated
//member variables
foreach ($recurProperties as $property) {
if( empty( $property ) )
continue;
$nameAndValue = explode('=', $property);
//need the lower-case name for setting the member variable
$propertyName = strtolower($nameAndValue[0]);
$propertyValue = $nameAndValue[1];
//split up the list of values into an array (if it's a list)
if (in_array($propertyName, $this->listProperties)) {
$propertyValue = explode(',', $propertyValue);
}
$this->$propertyName = $propertyValue;
}
}
/**
* Set the $until member
* @param mixed timestamp (int) / Valid DateTime format (string)
*/
public function setUntil($ts) {
if ( is_int($ts) )
$dt = new DateTime('@'.$ts);
else
$dt = new DateTime($ts);
$this->until = $dt->format('Ymd\THisO');
}
/**
* Retrieves the desired member variable and returns it (if it's set)
* @param string $member name of the member variable
* @return mixed the variable value (if set), false otherwise
*/
protected function getMember($member)
{
if (isset($this->$member)) {
return $this->$member;
}
return false;
}
/**
* Returns the frequency - corresponds to FREQ in RFC 2445.
* @return mixed string if the member has been set, false otherwise
*/
public function getFreq() {
return $this->getMember('freq');
}
/**
* Returns when the event will go until - corresponds to UNTIL in RFC 2445.
* @return mixed string if the member has been set, false otherwise
*/
public function getUntil() {
return $this->getMember('until');
}
/**
* Returns the count of the times the event will occur (should only appear if 'until'
* does not appear) - corresponds to COUNT in RFC 2445.
* @return mixed string if the member has been set, false otherwise
*/
public function getCount() {
return $this->getMember('count');
}
/**
* Returns the interval - corresponds to INTERVAL in RFC 2445.
* @return mixed string if the member has been set, false otherwise
*/
public function getInterval() {
return $this->getMember('interval');
}
/**
* Returns the bysecond part of the event - corresponds to BYSECOND in RFC 2445.
* @return mixed string if the member has been set, false otherwise
*/
public function getBySecond() {
return $this->getMember('bysecond');
}
/**
* Returns the byminute information for the event - corresponds to BYMINUTE in RFC 2445.
* @return mixed string if the member has been set, false otherwise
*/
public function getByMinute() {
return $this->getMember('byminute');
}
/**
* Corresponds to BYHOUR in RFC 2445.
* @return mixed string if the member has been set, false otherwise
*/
public function getByHour() {
return $this->getMember('byhour');
}
/**
*Corresponds to BYDAY in RFC 2445.
* @return mixed string if the member has been set, false otherwise
*/
public function getByDay() {
return $this->getMember('byday');
}
/**
* Corresponds to BYMONTHDAY in RFC 2445.
* @return mixed string if the member has been set, false otherwise
*/
public function getByMonthDay() {
return $this->getMember('bymonthday');
}
/**
* Corresponds to BYYEARDAY in RFC 2445.
* @return mixed string if the member has been set, false otherwise
*/
public function getByYearDay() {
return $this->getMember('byyearday');
}
/**
* Corresponds to BYYEARNO in RFC 2445.
* @return mixed string if the member has been set, false otherwise
*/
public function getByYearNo() {
return $this->getMember('byyearno');
}
/**
* Corresponds to BYMONTH in RFC 2445.
* @return mixed string if the member has been set, false otherwise
*/
public function getByMonth() {
return $this->getMember('bymonth');
}
/**
* Corresponds to BYSETPOS in RFC 2445.
* @return mixed string if the member has been set, false otherwise
*/
public function getBySetPos() {
return $this->getMember('bysetpos');
}
/**
* Corresponds to WKST in RFC 2445.
* @return mixed string if the member has been set, false otherwise
*/
public function getWkst() {
return $this->getMember('wkst');
}
}

View File

@@ -0,0 +1,34 @@
# iCalcreator
is the PHP class package managing
> iCal (rfc2445/rfc5445) calendar information
operating on calendar and
calendar events, reports, todos and journaling data.
~~~~~~~~
iCalcreator supports systems like
* calendars
* CMS
* project management systems
* other applications...
~~~~~~~~
__Builds__
Please review the releaseNotes for a brief overview,
docs/summary and docs/using for details.
Stable 2.26.9 *(master)*.
Release 2.28 candidate (tag 2.27.17)
Unsupported (tags):
- 2.26
- 2.24.2
- 2.24
- 2.22.5

View File

@@ -0,0 +1,70 @@
<?php
/**
* iCalcreator, the PHP class package managing iCal (rfc2445/rfc5445) calendar information.
*
* copyright (c) 2007-2019 Kjell-Inge Gustafsson, kigkonsult, All rights reserved
* Link https://kigkonsult.se
* Package iCalcreator
* Version 2.26.9
* License Subject matter of licence is the software iCalcreator.
* The above copyright, link, package and version notices,
* this licence notice and the invariant [rfc5545] PRODID result use
* as implemented and invoked in iCalcreator shall be included in
* all copies or substantial portions of the iCalcreator.
*
* iCalcreator 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 3 of the License,
* or (at your option) any later version.
*
* iCalcreator 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 iCalcreator. If not, see <https://www.gnu.org/licenses/>.
*
* This file is a part of iCalcreator.
*/
/**
* autoload.php
*
* iCalcreator package autoloader
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.26.8 - 2019-04-09
*/
/**
* Do NOT alter or remove the constant!!
*/
define( 'ICALCREATOR_VERSION', 'iCalcreator 2.26.9' );
/**
* load iCalcreator src and support classes and Traits
*/
spl_autoload_register(
function( $class ) {
static $SRC = 'src';
static $BS = '\\';
static $PHP = '.php';
static $PREFIX = 'Kigkonsult\\Icalcreator\\';
static $BASEDIR = null;
if( is_null( $BASEDIR ))
$BASEDIR = __DIR__ . DIRECTORY_SEPARATOR . $SRC . DIRECTORY_SEPARATOR;
if( 0 != strncmp( $PREFIX, $class, 23 ))
return false;
$class = substr( $class, 23 );
if( false !== strpos( $class, $BS ))
$class = str_replace( $BS, DIRECTORY_SEPARATOR, $class );
$file = $BASEDIR . $class . $PHP;
if( file_exists( $file )) {
require $file;
return true;
}
return false;
}
);
/**
* iCalcreator timezones add-on functionality functions, IF required?
*/
// include __DIR__ . DIRECTORY_SEPARATOR . 'src' . DIRECTORY_SEPARATOR . 'iCal.tz.inc.php';

View File

@@ -0,0 +1,40 @@
{
"name": "kigkonsult/icalcreator",
"type": "library",
"description": "iCalcreator is the PHP implementation of rfc2445/rfc5545, management of iCal formatted files",
"keywords": [ "rfc2445",
"rfc5545",
"rfc6321",
"management",
"calendar",
"vCalendar",
"vevent",
"vtodo",
"vjournal",
"vfreebusy",
"valarm",
"vtimezone",
"standard",
"daylight",
"file" ],
"time" : "2019-03-14",
"license": ["LGPL-3.0-or-later"],
"homepage": "http://kigkonsult.se",
"support": {
"issues": "https://github.com/iCalcreator/iCalcreator/issues"
},
"authors": [
{
"name": "Kjell-Inge Gustafsson",
"email": "ical@kigkonsult.se"
}
],
"autoload": {
"files": ["autoload.php"],
"psr-4": { "Kigkonsult\\Icalcreator\\": ["src/", "src/Util/", "src/Traits/"] }
},
"require": {
"php": ">=5.6",
"ext-simplexml": "*"
}
}

View File

@@ -0,0 +1,165 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
This version of the GNU Lesser General Public License incorporates
the terms and conditions of version 3 of the GNU General Public
License, supplemented by the additional permissions listed below.
0. Additional Definitions.
As used herein, "this License" refers to version 3 of the GNU Lesser
General Public License, and the "GNU GPL" refers to version 3 of the GNU
General Public License.
"The Library" refers to a covered work governed by this License,
other than an Application or a Combined Work as defined below.
An "Application" is any work that makes use of an interface provided
by the Library, but which is not otherwise based on the Library.
Defining a subclass of a class defined by the Library is deemed a mode
of using an interface provided by the Library.
A "Combined Work" is a work produced by combining or linking an
Application with the Library. The particular version of the Library
with which the Combined Work was made is also called the "Linked
Version".
The "Minimal Corresponding Source" for a Combined Work means the
Corresponding Source for the Combined Work, excluding any source code
for portions of the Combined Work that, considered in isolation, are
based on the Application, and not on the Linked Version.
The "Corresponding Application Code" for a Combined Work means the
object code and/or source code for the Application, including any data
and utility programs needed for reproducing the Combined Work from the
Application, but excluding the System Libraries of the Combined Work.
1. Exception to Section 3 of the GNU GPL.
You may convey a covered work under sections 3 and 4 of this License
without being bound by section 3 of the GNU GPL.
2. Conveying Modified Versions.
If you modify a copy of the Library, and, in your modifications, a
facility refers to a function or data to be supplied by an Application
that uses the facility (other than as an argument passed when the
facility is invoked), then you may convey a copy of the modified
version:
a) under this License, provided that you make a good faith effort to
ensure that, in the event an Application does not supply the
function or data, the facility still operates, and performs
whatever part of its purpose remains meaningful, or
b) under the GNU GPL, with none of the additional permissions of
this License applicable to that copy.
3. Object Code Incorporating Material from Library Header Files.
The object code form of an Application may incorporate material from
a header file that is part of the Library. You may convey such object
code under terms of your choice, provided that, if the incorporated
material is not limited to numerical parameters, data structure
layouts and accessors, or small macros, inline functions and templates
(ten or fewer lines in length), you do both of the following:
a) Give prominent notice with each copy of the object code that the
Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the object code with a copy of the GNU GPL and this license
document.
4. Combined Works.
You may convey a Combined Work under terms of your choice that,
taken together, effectively do not restrict modification of the
portions of the Library contained in the Combined Work and reverse
engineering for debugging such modifications, if you also do each of
the following:
a) Give prominent notice with each copy of the Combined Work that
the Library is used in it and that the Library and its use are
covered by this License.
b) Accompany the Combined Work with a copy of the GNU GPL and this license
document.
c) For a Combined Work that displays copyright notices during
execution, include the copyright notice for the Library among
these notices, as well as a reference directing the user to the
copies of the GNU GPL and this license document.
d) Do one of the following:
0) Convey the Minimal Corresponding Source under the terms of this
License, and the Corresponding Application Code in a form
suitable for, and under terms that permit, the user to
recombine or relink the Application with a modified version of
the Linked Version to produce a modified Combined Work, in the
manner specified by section 6 of the GNU GPL for conveying
Corresponding Source.
1) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (a) uses at run time
a copy of the Library already present on the user's computer
system, and (b) will operate properly with a modified version
of the Library that is interface-compatible with the Linked
Version.
e) Provide Installation Information, but only if you would otherwise
be required to provide such information under section 6 of the
GNU GPL, and only to the extent that such information is
necessary to install and execute a modified version of the
Combined Work produced by recombining or relinking the
Application with a modified version of the Linked Version. (If
you use option 4d0, the Installation Information must accompany
the Minimal Corresponding Source and Corresponding Application
Code. If you use option 4d1, you must provide the Installation
Information in the manner specified by section 6 of the GNU GPL
for conveying Corresponding Source.)
5. Combined Libraries.
You may place library facilities that are a work based on the
Library side by side in a single library together with other library
facilities that are not Applications and are not covered by this
License, and convey such a combined library under terms of your
choice, if you do both of the following:
a) Accompany the combined library with a copy of the same work based
on the Library, uncombined with any other library facilities,
conveyed under the terms of this License.
b) Give prominent notice with the combined library that part of it
is a work based on the Library, and explaining where to find the
accompanying uncombined form of the same work.
6. Revised Versions of the GNU Lesser General Public License.
The Free Software Foundation may publish revised and/or new versions
of the GNU Lesser General Public License from time to time. Such new
versions will be similar in spirit to the present version, but may
differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the
Library as you received it specifies that a certain numbered version
of the GNU Lesser General Public License "or any later version"
applies to it, you have the option of following the terms and
conditions either of that published version or of any later version
published by the Free Software Foundation. If the Library as you
received it does not specify a version number of the GNU Lesser
General Public License, you may choose any version of the GNU Lesser
General Public License ever published by the Free Software Foundation.
If the Library as you received it specifies that a proxy can decide
whether future versions of the GNU Lesser General Public License shall
apply, that proxy's public statement of acceptance of any version is
permanent authorization for you to choose that version for the
Library.

View File

@@ -0,0 +1,682 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">
<!--
iCalcreator, the PHP class package managing iCal (rfc2445/rfc5445) calendar information.
This file is a part of iCalcreator.
copyright (c) 2007-2019 Kjell-Inge Gustafsson, kigkonsult, All rights reserved
Link https://kigkonsult.se
Package iCalcreator
Version 2.26.8
License Subject matter of licence is the software iCalcreator.
The above copyright, link, package and version notices,
this licence notice and the invariant [rfc5545] PRODID result use
as implemented and invoked in iCalcreator shall be included in
all copies or substantial portions of the iCalcreator.
iCalcreator 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 3 of the License,
or (at your option) any later version.
iCalcreator 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 iCalcreator. If not, see <https://www.gnu.org/licenses/>.
-->
<html>
<head>
<title>iCalcreator 2.26.8 manual</title>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8">
<meta name="author" content="Kjell-Inge Gustafsson, kigkonsult, All rights reserved">
<meta name="copyright" content="2007-2019 Kjell-Inge Gustafsson, kigkonsult">
<meta name="keywords" content="ical, calendar, calender, xcal, xml, icalender, rfc2445, rfc5545, vcalender, php, create">
<meta name="description" content="using iCalcreator v2.26.8">
<style type="text/css">
* {
FONT-FAMILY : "Bitstream Vera Sans", Helvetica, "Lucida Grande","Lucida Sans Unicode", Lucida, Arial, Geneva, sans-serif;
BACKGROUND-COLOR: white;
COLOR : black;
FONT-SIZE : small;
}
body {
MARGIN-LEFT : 10px;
WIDTH : 750px;
}
h1 {
BACKGROUND-COLOR: silver;
BORDER : thin solid black;
FONT-SIZE : x-large;
FONT-WEIGHT : bold;
DISPLAY : block;
}
h2 {
FONT-SIZE : large;
}
h3 {
FONT-SIZE : medium;
}
h4 {
FONT-SIZE : small;
FONT-WEIGHT : bold;
}
h5 {
FONT-SIZE : small;
FONT-WEIGHT : normal;
TEXT-DECORATION : underline;
}
table {
border-collapse : collapse;
width : 100%;
}
p.comment {
FONT-FAMILY : monospace;
FONT-SIZE : 9pt;
FONT-WEIGHT : 500;
WHITE-SPACE : pre-wrap; /* css-3 */
WHITE-SPACE : -moz-pre-wrap; /* Mozilla, since 1999 */
WHITE-SPACE : -pre-wrap; /* Opera 4-6 */
WHITE-SPACE : -o-pre-wrap; /* Opera 7 */
WORD-WRAP : break-word; /* Internet Explorer 5.5+ */
}
span.comment {
BACKGROUND-COLOR: inherit;
FONT-FAMILY : Areal;
FONT-SIZE : 8pt;
LETTER-SPACING : 0.2em;
}
p.example {
BACKGROUND-COLOR: #DCDCDC;
font-family : monospace;
FONT-SIZE : 9pt;
LETTER-SPACING : 0.1em;
LINE-HEIGHT : 1.5em;
WHITE-SPACE : pre-wrap; /* css-3 */
WHITE-SPACE : -moz-pre-wrap; /* Mozilla, since 1999 */
WHITE-SPACE : -pre-wrap; /* Opera 4-6 */
WHITE-SPACE : -o-pre-wrap; /* Opera 7 */
WORD-WRAP : break-word; /* Internet Explorer 5.5+ */
}
p.format, span.format {
BORDER : gray dotted thin;
FONT-FAMILY : Helvetica;
FONT-SIZE : 9pt;
LETTER-SPACING : 0.2em;
LINE-HEIGHT : 2em;
WHITE-SPACE : pre-wrap; /* css-3 */
WHITE-SPACE : -moz-pre-wrap; /* Mozilla, since 1999 */
WHITE-SPACE : -pre-wrap; /* Opera 4-6 */
WHITE-SPACE : -o-pre-wrap; /* Opera 7 */
WORD-WRAP : break-word; /* Internet Explorer 5.5+ */
}
.header {
BACKGROUND-COLOR: silver;
BORDER : thin solid black;
FONT-SIZE : xx-large;
}
p.quotes {
BACKGROUND-COLOR: #F5F5F5;
FONT-FAMILY : Arial;
FONT-STYLE : italic;
LETTER-SPACING : 0.1em;
}
sup {
BACKGROUND-COLOR: transparent;
FONT-SIZE : x-small;
FONT-WEIGHT : bold;
VERTICAL-ALIGN : super;
}
.top {
VERTICAL-ALIGN : top;
}
</style>
</head>
<body>
<a name="top"></a>
<p class="header">iCalcreator v2.26.8</p>
<p>
iCalcreator v2.26.8<br>
Copyright &copy; 2007-2019 Kjell-Inge Gustafsson, kigkonsult, All rights reserved.<br>
<a href="http://kigkonsult.se/iCalcreator/index.php" title="kigkonsult.se/iCalcreator" target="_blank">kigkonsult.se iCalcreator</a><br>
Contact : iCal_at_kigkonsult_dot_se
</p>
<h2>Preface</h2>
<p>
This document describes usage of iCalcreator, the <em>PHP</em> software implementation of standards
<a href="https://tools.ietf.org/html/rfc5545" title="Download RFC5545 in text format" target="_blank">rfc5545</a>/
<a href="https://tools.ietf.org/html/rfc5546" title="Download RFC5546 in text format" target="_blank">rfc5546</a>
(rfc2445/rfc2446) to manage iCal formatted files.
</p>
<p>
This document is provided by kigkonsult for informational purposes
and is provided on an &quot;as is&quot; basis without any warranties expressed or implied.
</p>
<p>
Information in this document is subject to change without notice and does
not represent a commitment on the part of kigkonsult.
The software described in this document is provided under a <a href="#Copyright_and_Licence">license agreement</a>.
The software may be used only in accordance with the terms of that <a href="#Copyright_and_Licence">license agreement</a>.
It is against the law to copy or use the software except as specifically allowed in the <a href="#Copyright_and_Licence">license agreement</a>.
</p>
<p>
It is the users responsibility to ensure the suitability of the software before using it.
In no circumstances will kigkonsult be responsible for
the use of the software's outcomes or results or any loss
or damage of data or programs as a result of using the software.
</p>
<p>
The use of the software implies acceptance of these terms and the <a href="#Copyright_and_Licence">license</a>.
</p>
<p>
This document makes previous versions obsolete.
</p>
<h4>The software</h4>
<p>
iCalcreator is a <em>PHP</em> class package managing iCal files, supporting (non-)calendar
systems and applications to process and communicate calendar information like
events, agendas, tasks, reports, totos and journaling information.
</p>
<p>
For iCalcreator 2.26.8 version (and later), <em>PHP</em> version 5.6+ is required.
</p>
<h4>iCal</h4>
<p>
A short iCal description is found at
<a href="http://en.wikipedia.org/wiki/ICalendar#Core_object" title="iCalendar From Wikipedia, the free encyclopedia" target="_blank">Wikipedia</a>.
If You are not familiar with iCal, read this first!
</p>
<p>
The <strong>iCalendar</strong> format, <strong>iCal</strong>, are described in
</p>
<dl>
<dt><a href="https://tools.ietf.org/html/rfc5545" title="Download RFC5545 in text format" target="_blank">rfc5545</a>
<dd>&quot;Internet Calendaring and Scheduling Core Object Specification (<strong>iCalendar</strong>)&quot;
<dt><a href="https://tools.ietf.org/html/rfc5546" title="Download RFC5546 in text format" target="_blank">rfc5546</a>
<dd>&quot;iCalendar Transport-Independent Interoperability Protocol (iTIP)&quot;<br>Scheduling Events, BusyTime, To-dos and Journal Entries
<p class="quotes">. ..allows for the capture and exchange of information normally stored
within a calendaring and scheduling application.</p>
and
<p class="quotes">. ..is an exchange format between applications or systems.</p>
</dl>
<p>
<a href="https://tools.ietf.org/html/rfc5545" title="Download RFC5545 in text format" target="_blank">rfc5545</a> and
<a href="https://tools.ietf.org/html/rfc5546" title="Download RFC5546 in text format" target="_blank">rfc5546</a>
obsoletes, respectively,
<a href="https://tools.ietf.org/html/rfc2445" title="Download RFC2445 in text format" target="_blank">rfc2445</a> and
<a href="https://tools.ietf.org/html/rfc2446" title="Download RFC2446 in text format" target="_blank">rfc2446</a>.
</p>
<p>
Any references to rfc2445, below, corresponds to rfc5545.
</p>
<h4>xCal</h4>
<p>
iCalcreator also supports xCal (iCal xml),
<a href="https://tools.ietf.org/html/rfc6321" title="Download RFC6321 in text format" target="_blank">rfc6321</a>,
The XML Format for <strong>iCalendar</strong>.
</p>
<p>
A short xCal description is found at <a href="http://en.wikipedia.org/wiki/XCal" title="xCal on Wikipedia, the free encyclopedia" target="_blank">Wikipedia</a>.
</p>
<h4>Support</h4>
<p>
For previous iCalcreator releases support upon (paid) request only.
</p>
<p>
Use the issues <a href="https://github.com/iCalcreator/iCalcreator/issues" title="kigkonsult.se issues" target="_blank">page</a>
for queries, improvement/development issues or professional support and development.
Please note that paid support or consulting service has the highest priority.
</p>
<p>
kigkonsult offer professional services for software support, design and new/re-development, customizations and adaptations
of <em>PHP</em>/<em>MySQL</em> solutions with focus on software lifecycle management, including long term utility, reliability and maintainability.
</p>
<h4>Donate</h4>
<p>
You can show your appreciation for our free software,
and can support future development by making a donation to the kigkonsult GPL/LGPL projects.
</p>
<p>
Make a donation of any size by clicking <a href="http://kigkonsult.se/contact/index.php#Donate" title="Donate" target="_blank">here</a>.
Thanks in advance!
</p>
<h4>Contact</h4>
<p>
Use the <a href="https://github.com/iCalcreator/iCalcreator/issues" title="kigkonsult.se issues" target="_blank"> github issues</a>
for queries, improvement/development issues or professional support and development.
Please note that paid support or consulting service has the highest priority.
</p>
<h4>Downloads and usage examples</h4>
<p>
At <a href="https://github.com/iCalcreator/iCalcreator" title="kigkonsult iCalcreator" target="_blank">kigkonsult.se</a> you can download a more
complete manual and review and explore iCalcreator usage.
</p>
<h4>Install</h4>
<dl>
<dt>Composer (https://getcomposer.org/)
<dd>&nbsp;
<dd>composer require kigkonsult/icalcreator
<dd>&nbsp;
<dt>Or
<dd> include the (download) iCalcreator folder to your include-path
<dd>Add
<dd><span class="format">require_once &quot;[path/]iCalcreator-2.26.8/autoload.php&quot;;</span>
<dd>to your <em>PHP</em>-script.
<dd>The iCalcreator invoker has changed since previous version!
</dl>
<p>
iCalcreator 2.26.8 is using namespace &quot;Kigkonsult\Icalcreator&quot;.
</p>
<h4>Notes</h4>
<p>
When creating a new Vcalendar(/component) instance, review config settings.
</p>
<p>
You will find a complete iCalcreator function list (ex. getProperty, deleteProperty) in
<a href="https://github.com/iCalcreator/iCalcreator/docs" title="iCalcreator complete manual" target="_blank">iCalcreator manual</a>.
</p>
<p>
Note, to ease up usage, you will find convenient holders for component names,
properties, config keys etc in top of the &quot;util&quot; class file (src/util/util.php).
</p>
<h2>CREATE</h2>
<p class="example">&lt;?php
namespace Kigkonsult\Icalcreator;
use Kigkonsult\Icalcreator\Util\Util;
// <span class="comment">define time zone</span>
$tz = &quot;Europe/Stockholm&quot;;
// <span class="comment">set Your unique id, </span>
// <span class="comment">required if any component UID is missing</span>
$config = [
Util::$UNIQUE_ID =&gt; &quot;kigkonsult.se&quot;,
// <span class="comment">opt. set &quot;calendar&quot; timezone</span>
Util::$TZID =&gt; $tz
];
// <span class="comment">create a new Vcalendar instance</span>
$calendar= new Vcalendar( $config );
// <span class="comment">required of some calendar software</span>
$calendar-&gt;setProperty( Util::$METHOD, &quot;PUBLISH&quot; );
$calendar-&gt;setProperty( Util::$X_WR_CALNAME, &quot;Calendar Sample&quot;);
$calendar-&gt;setProperty( Util::$X_WR_CALDESC, &quot;Calendar Description&quot; );
$calendar-&gt;setProperty( Util::$X_WR_TIMEZONE, $tz );
// <span class="comment">create an calendar event component</span>
$vevent = $calendar-&gt;newVevent();
// <span class="comment">set event start</span>
$vevent-&gt;setProperty(
Util::$DTSTART,
new DateTime( '2017-04-01 19:00:00')
);
// <span class="comment">set event end</span>
$vevent-&gt;setProperty(
Util::$DTEND,
new DateTime( '2017-04-01 22:30:00')
);
$vevent-&gt;setProperty( Util::$LOCATION, &quot;Central Placa&quot; );
$vevent-&gt;setProperty( Util::$SUMMARY, &quot;PHP summit&quot; );
$vevent-&gt;setProperty( Util::$DESCRIPTION, &quot;This is a description&quot; );
$vevent-&gt;setProperty( Util::$COMMENT, &quot;This is a comment&quot; );
$vevent-&gt;setProperty( Util::$ATTENDEE, &quot;attendee1@icaldomain.net&quot; );
// <span class="comment">create an event alarm</span>
$valarm = $vevent-&gt;newValarm();
$valarm-&gt;setProperty( Util::$ACTION, &quot;DISPLAY&quot; );
// <span class="comment">reuse the event description</span>
$valarm-&gt;setProperty( Util::$DESCRIPTION, $vevent-&gt;getProperty( Util::$DESCRIPTION ));
// <span class="comment">create alarm trigger (in UTC datetime)</span>
$valarm-&gt;setProperty(
Util::$TRIGGER,
new DateTime( '2017-04-01 08:00:00 UTC')
);
// <span class="comment">create another calendar event component</span>
$vevent = $calendar-&gt;newVevent();
// <span class="comment">alt. date format, here for an all-day event</span>
$vevent-&gt;setProperty(
Util::$DTSTART,
&quot;20170401&quot;,
[ &quot;VALUE&quot; =&gt; &quot;DATE&quot; ]
);
$vevent-&gt;setProperty( Util::$ORGANIZER, &quot;cio@icaldomain.com&quot; );
$vevent-&gt;setProperty( Util::$SUMMARY, &quot;ALL-DAY event&quot; );
$vevent-&gt;setProperty( Util::$DESCRIPTION, &quot;This is a description for an all-day event&quot; );
$vevent-&gt;setProperty( Util::$RESOURCES, &quot;Full attension&quot; );
// <span class="comment">weekly, four occasions</span>
$vevent-&gt;setProperty(
Util::$RRULE,
[
&quot;FREQ&quot; =&gt; &quot;WEEKLY&quot;,
&quot;count&quot; =&gt; 4
]
);
// <span class="comment">supporting parse of strict rfc5545 formatted text</span>
$vevent-&gt;parse( &quot;LOCATION:1CP Conference Room 4350&quot; );
// <span class="comment">all calendar components are described in <a href="https://tools.ietf.org/html/rfc5545" title="RFC5545" target="_blank">rfc5545</a></span>
// <span class="comment">a complete iCalcreator function list (ex. setProperty) in the iCalcreator using manual</span>
// <span class="comment">create timezone component(-s)</span>
// <span class="comment">based on all start dates in events (i.e. all dtstarts)</span>
// <span class="comment">X-LIC-LOCATION required of some calendar software</span>
$xprops = [ Util::$X_LIC_LOCATION => $tz ];
Kigkonsult\Icalcreator\TimezoneHandler::createTimezone( $v, $tz, $xprops );
</p>
<h2>PARSE</h2>
<h4>iCal, rfc5545 / rfc2445 </h4>
<p>How to parse an iCal (external/file) resource</p>
<p class="example">
// <span class="comment">set Your unique id, </span>
// <span class="comment">required if any component UID is missing</span>
$vcalendar = new Vcalendar(
[ Util::$UNIQUE_ID =&gt; &quot;kigkonsult.se&quot;, ]
);
$iCalContent = file_get_contents( &quot;calendar.ics&quot; );
$vcalendar-&gt;parse( $iCalContent );
<h4>xCal, rfc6321 (XML)</h4>
<p>
How to convert (file) XML resource to an Vcalendar instance.
</p>
<p class="example">
// <span class="comment">set Your unique id, </span>
// <span class="comment">required if any component UID is missing</span>
$config = [ Util::$UNIQUE_ID =&gt; &quot;kigkonsult.se&quot; ];
// <span class="comment">use a local xCal file</span>
$filename = &quot;xmlfile.xml&quot;;
// <span class="comment"> or a remote xCal resource</span>
/* $filename = 'http://kigkonsult.se/xcal.php?a=1&amp;b=2&amp;c=3'; */
if( ! ( $calendar = Kigkonsult\Icalcreator\IcalXML::XMLfile2iCal( $filename, $config ))) {
exit( &quot;Error when parsing $filename&quot; );
}
// <span class="comment">continue process (edit, parse, select) $calendar</span>
</p>
<h2>EDIT</h2>
<p class="example">
// <span class="comment">create a new Vcalendar instance</span>
$config = [ Util::$UNIQUE_ID =&gt; &quot;kigkonsult.se&quot; ];
$calendar = new Vcalendar( $config );
// <span class="comment">parse a calendar file</span>
$config = [
Util::$DIRECTORY =&gt; &quot;calendars&quot;,
Util::$FILENAME =&gt; &quot;file.ics&quot;
];
$calendar-&gt;setConfig( $config );
$calendar-&gt;parse();
// <span class="comment">required of some calendar software</span>
$calendar-&gt;setProperty( Util::$METHOD, &quot;PUBLISH&quot; );
$calendar-&gt;setProperty( Util::$X_WR_CALNAME, &quot;Calendar Sample&quot;);
$calendar-&gt;setProperty( Util::$X_WR_CALDESC, &quot;Calendar Description&quot; );
$calendar-&gt;setProperty( Util::$X_WR_TIMEZONE, &quot;Europe/Stockholm&quot; );
// <span class="comment">read events, one by one</span>
while( $vevent = $calendar-&gt;getComponent(
Vcalendar::VEVENT )) {
// <span class="comment">get uid (unique id/key for component), required, one occurrence </span>
$uid = $vevent-&gt;getProperty( Util::$UID );
// <span class="comment">get dtstart required, one occurrence</span>
$dtstart = $vevent-&gt;getProperty( Util::$DTSTART );
// <span class="comment">opt. description</span>
if( $description = $vevent-&gt;getProperty( Util::$DESCRIPTION, 1 )) {
// <span class="comment">edit the description</span>
// <span class="comment">update/replace the description</span>
$vevent-&gt;setProperty(
Util::$DESCRIPTION,
$description,
false,
1
);
}
// <span class="comment">get optional comments</span>
while( $comment = $vevent-&gt;getProperty( Util::$COMMENT )) {
.. .
}
// <span class="comment">remove all ATTENDEE properties .. .</span>
while( $vevent-&gt;deleteProperty( Util::$ATTENDEE )) {
continue;
}
// <span class="comment">update/replace event in calendar</span>
// <span class="comment"> with UID as key</span>
$calendar-&gt;setComponent ( $vevent, $uid );
} // end while
</p>
<br>
<br>
<h2>SELECT</h2>
<p>
(setup)
</p>
<p class="example">
// <span class="comment">create a new Vcalendar instance</span>
$calendar = new Vcalendar(
[ Util::$UNIQUE_ID =&gt; &quot;kigkonsult.se&quot;, ]
);
$iCalContent = file_get_contents( &quot;http://www.aDomain.net/file.ics&quot; );
$calendar-&gt;parse( $iCalContent );
// <span class="comment">required of some calendar software</span>
$calendar-&gt;setProperty( Util::$METHOD, &quot;PUBLISH&quot; );
$calendar-&gt;setProperty( Util::$X_WR_CALNAME, &quot;Calendar Sample&quot;);
$calendar-&gt;setProperty( Util::$X_WR_CALDESC, &quot;Calendar Description&quot; );
$calendar-&gt;setProperty( Util::$X_WR_TIMEZONE, &quot;Europe/Stockholm&quot;);
</p>
<h4>Ex. calendar date based select</h4>
<p class="example">
// <span class="comment">select components occurring today</span>
// <span class="comment">(including components with recurrence pattern)</span>
$eventArray = $calendar-&gt;selectComponents();
foreach( $eventArray as $year =&gt; $yearArray) {
foreach( $yearArray as $month =&gt; $monthArray ) {
foreach( $monthArray as $day =&gt; $dailyEventsArray ) {
foreach( $dailyEventsArray as $vevent ) {
// <span class="comment">if event is a member of a recurrence set</span>
// <span class="comment">returns [ </span>
// <span class="comment"> &quot;x-current-dtstart&quot;,</span>
// <span class="comment"> (string) date( &quot;Y-m-d [H:i:s][timezone/UTC offset]&quot;)</span>
// <span class="comment">]</span>
$currddate = $event-&gt;getProperty( Util::$X_CURRENT_DTSTART );
// <span class="comment">orig. dtstart</span>
$dtstart = $vevent-&gt;getProperty( Util::$DTSTART );
$summary = $vevent-&gt;getProperty( Util::$SUMMARY );
$description = $vevent-&gt;getProperty( Util::$DESCRIPTION );
.. .
.. .
} // end foreach
} // end foreach
} // end foreach
} // end foreach
</p>
<h4>Ex. calendar select specific property values</h4>
<p class="example">
// <span class="comment">fetch specific property from calendar perspective</span>
// <span class="comment">(unique) values and occurrences : </span>
// <span class="comment">ATTENDEE, CATEGORIES, CONTACT,</span>
// <span class="comment">DTSTART, LOCATION, ORGANIZER,</span>
// <span class="comment">PRIORITY, RESOURCES, STATUS,</span>
// <span class="comment">SUMMARY, UID, URL,</span>
// <span class="comment">GEOLOCATION<sup>*</sup></span>
$valueOccur = $calendar-&gt;getProperty( Util::$RESOURCES );
foreach( $valueOccur as $uniqueValue =&gt; $occurCnt ) {
echo &quot;The RESOURCES value &lt;b&gt;$uniqueValue&lt;/b&gt; occurs &lt;b&gt;$occurCnt&lt;/b&gt; times&lt;br /&gt;&quot;;
}
</p>
<p>
<sup>*</sup>) Using the non-standard directive "GEOLOCATION", iCalcreator returns output supporting
ISO6709 "Standard representation of geographic point location by coordinates",
by combining the "LOCATION" and "GEO" property values (only if "GEO" is set).
</p>
<h4>Ex. select calendar components based on specific property value</h4>
<p class="example">
// <span class="comment">selects components</span>
// <span class="comment">based on specific property value(-s)</span>
// <span class="comment">ATTENDEE, CATEGORIES, CONTACT,</span>
// <span class="comment">LOCATION, ORGANIZER,</span>
// <span class="comment">PRIORITY, RESOURCES, STATUS,</span>
// <span class="comment">SUMMARY, URL, UID</span>
$selectSpec = [ Util::$CATEGORIES =&gt; &quot;course1&quot; ];
$specComps = $calendar-&gt;selectComponents( $selectSpec );
foreach( $specComps as $comp ) {
.. .
}
</p>
<br>
<br>
<h2>OUTPUT</h2>
<p>(setup)</p>
<p class="example">
// <span class="comment">create a new Vcalendar instance</span>
$calendar = new Vcalendar(
[ Util::$UNIQUE_ID =&gt; &quot;kigkonsult.se&quot;, ]
);
// <span class="comment">required of some calendar software</span>
$calendar-&gt;setProperty( Util::$METHOD, &quot;PUBLISH&quot; );
$calendar-&gt;setProperty( Util::$X_WR_CALNAME, &quot;Calendar Sample&quot;);
$calendar-&gt;setProperty( Util::$X_WR_CALDESC, &quot;Calendar Description&quot; );
$calendar-&gt;setProperty( Util::$X_WR_TIMEZONE, &quot;Europe/Stockholm&quot;);
// <span class="comment">continue process (edit, parse, select) $calendar</span>
</p>
<h5>opt 1</h5>
<p>
Redirect calendar file to browser.
</p>
<p class="example">
$calendar-&gt;returnCalendar();
exit;
</p>
<h5>opt 2</h5>
<p>
Save calendar to file.
</p>
<p class="example">
// <span class="comment">set output directory and file name</span>
$config = [
Util::$DIRECTORY =&gt; &quot;depot&quot;,
Util::$FILENAME =&gt; &quot;calendar.ics&quot;
];
$calendar-&gt;setConfig( $config );
$calendar-&gt;saveCalendar();
</p>
<h5>opt 3, xCal</h5>
<p>
Create well-formed XML, rfc6321 (as string).
</p>
<p class="example">
$xmlstr = Kigkonsult\Icalcreator\IcalXML::iCal2XML( $calendar);
</p>
<h5>opt 4, json</h5>
<p>
Create a json string.
</p>
<p class="example">
$xmlstr = Kigkonsult\Icalcreator\IcalXML::iCal2XML( $calendar);
$json = json_encode( simplexml_load_string( $xmlstr ));
</p>
<br>
<br>
<a name="Copyright_and_Licence"></a>
<h2>COPYRIGHT AND LICENSE</h2>
<table>
<tr><td>Copyright<td>(c) 2007-2019 Kjell-Inge Gustafsson, kigkonsult, All rights reserved
<tr><td>Link <td>http://kigkonsult.se/iCalcreator/index.php
<tr><td>Package <td>iCalcreator
<tr><td>Version <td>2.26.8
<tr><td class="top">License <td>
Subject matter of licence is the software iCalcreator.<br>
The above copyright, link, package and version notices,<br>
this licence notice and the invariant [rfc5545] PRODID result use<br>
as implemented and invoked in iCalcreator shall be included in<br>
all copies or substantial portions of the iCalcreator.<br>
<br>
iCalcreator is free software: you can redistribute it and/or modify<br>
it under the terms of the GNU Lesser General Public License as published<br>
by the Free Software Foundation, either version 3 of the License,<br>
or (at your option) any later version.<br>
<br>
iCalcreator is distributed in the hope that it will be useful,<br>
but WITHOUT ANY WARRANTY; without even the implied warranty of<br>
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the<br>
GNU Lesser General Public License for more details.<br>
<br>
You should have received a copy of the GNU Lesser General Public License<br>
along with iCalcreator. If not, see &lt;https://www.gnu.org/licenses/&gt;.
</table>
<br>
</body>
</html>

View File

@@ -0,0 +1,41 @@
iCalcreator 2.26.8 releaseNotes
v2.26 PHP 5.6+ required
PSR 1+4 support
new Namespace Kigkonsult\IcalCreator
minor internal rework
static variables replaced by constants :
Kigkonsult\Icalcreator\Vcalendar::VEVENT,
Kigkonsult\Icalcreator\Vcalendar::VTODO,,
Kigkonsult\Icalcreator\Vcalendar::VJOURNAL,
Kigkonsult\Icalcreator\Vcalendar::VFREEBUSY
Kigkonsult\Icalcreator\Vcalendar::VTIMEZONE
Kigkonsult\Icalcreator\Vcalendar::STANDARD
Kigkonsult\Icalcreator\Vcalendar::DAYLIGHT
Kigkonsult\Icalcreator\Util\UtilSelect::X_CURRENT_DTSTART,
Kigkonsult\Icalcreator\Util\UtilSelect::X_CURRENT_DTEND,
Kigkonsult\Icalcreator\Util\UtilSelect::X_CURRENT_DUE,
Kigkonsult\Icalcreator\Util\UtilSelect::X_RECURRENCE,
Kigkonsult\Icalcreator\Util\UtilSelect::X_OCCURENCE
v2.26.1 More general PSR1+4/PHP 5.6+ adaptation + internal rework
v2.26.2 UtilSelect (+IcaldateTime) more reworking
v2.26.3 VcalendarSortHandler: sort key update
v2.26.4 UtilSelect: RDATE RRULE overwrite bug
v2.26.5 UtilSelect: update UID-matched recurr-id component
v2.26.6 Util: setDate/setDate2 reworked
v2.26.7 Accept DateTime as input arg. in set-functions:
DTSTART, DTEND, DUE
DTSTAMP, CREATED, COMPLETED, LAST-MODIFIED
EXDATE, EXRULE, RDATE, RRULE
FREEBUSY, TRIGGER
v2.26.8 Accept DateInterval as input arg. in set-functions:
DURATION, FREEBUSY, RDATE, TRIGGER
Note, date/duration array set-property methods arguments
are objects for removal in future versions
as well as date/duration arrays returned from property get-methods,
replaced by DateTime/DateInterval
v2.26.9 Util::dateTimeHasOffset typo error

View File

@@ -0,0 +1,595 @@
<?php
/**
* iCalcreator, the PHP class package managing iCal (rfc2445/rfc5445) calendar information.
*
* copyright (c) 2007-2019 Kjell-Inge Gustafsson, kigkonsult, All rights reserved
* Link https://kigkonsult.se
* Package iCalcreator
* Version 2.26.9
* License Subject matter of licence is the software iCalcreator.
* The above copyright, link, package and version notices,
* this licence notice and the invariant [rfc5545] PRODID result use
* as implemented and invoked in iCalcreator shall be included in
* all copies or substantial portions of the iCalcreator.
*
* iCalcreator 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 3 of the License,
* or (at your option) any later version.
*
* iCalcreator 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 iCalcreator. If not, see <https://www.gnu.org/licenses/>.
*
* This file is a part of iCalcreator.
*/
namespace Kigkonsult\Icalcreator;
use Kigkonsult\Icalcreator\Util\Util;
use function define;
use function defined;
use function array_change_key_case;
use function array_filter;
use function array_keys;
use function array_slice;
use function array_unshift;
use function count;
use function ctype_digit;
use function get_object_vars;
use function gethostbyname;
use function is_array;
use function is_null;
use function is_object;
use function key;
use function strtolower;
use function strtoupper;
use function trim;
use function ucfirst;
/**
* Do NOT alter or remove the constant!!
*/
if( ! defined( 'ICALCREATOR_VERSION' )) {
define( 'ICALCREATOR_VERSION', 'iCalcreator 2.26.9' );
}
/**
* iCalcreator base class
*
* Properties and methods shared by Vcalendar and CalendarComponents
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.26.1 - 2018-11-17
*/
abstract class IcalBase implements IcalInterface
{
use Traits\X_PROPtrait;
/**
* @var string
* @access protected
* @static
*/
protected static $INDEX = 'INDEX';
/**
* @var array container for sub-components
* @access protected
*/
protected $components = [];
/**
* @var array $unparsed calendar/components in 'raw' text...
* @access protected
*/
protected $unparsed = null;
/**
* @var array $config configuration
* @access protected
*/
protected $config = [];
/**
* @var array component index
* @access protected
*/
protected $compix = [];
/**
* @var array get multi property index
* @access protected
*/
protected $propix = [];
/**
* @var array delete multi property index
* @access protected
*/
protected $propdelix = [];
/**
* __clone method
*
* @link https://php.net/manual/en/language.oop5.cloning.php#116329
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.26 - 2018-11-10
*/
public function __clone() {
$object_vars = get_object_vars( $this );
foreach( $object_vars as $attr_name => $attr_value ) {
if( is_object( $this->$attr_name )) {
$this->$attr_name = clone $this->$attr_name;
}
else if( is_array( $this->$attr_name )) {
// Note: This copies only one dimension arrays
foreach( $this->$attr_name as & $attr_array_value ) {
if( is_object( $attr_array_value )) {
$attr_array_value = clone $attr_array_value;
}
unset( $attr_array_value);
}
}
}
$this->compix = [];
$this->propix = [];
$this->propdelix = [];
}
/**
* Return config value or info about subcomponents, false on not found
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.26 - 2018-11-10
* @param mixed $config
* @return mixed
*/
public function getConfig( $config = false ) {
static $LCORDNO = 'ordno';
static $LCTYPE = 'type';
static $LCUID = 'uid';
static $LCPROPS = 'props';
static $LCSUB = 'sub';
if( empty( $config )) {
$return = [];
$return[Util::$ALLOWEMPTY] = $this->getConfig( Util::$ALLOWEMPTY );
if( false !== ( $lang = $this->getConfig( Util::$LANGUAGE ))) {
$return[Util::$LANGUAGE] = $lang;
}
$return[Util::$TZID] = $this->getConfig( Util::$TZID );
$return[Util::$UNIQUE_ID] = $this->getConfig( Util::$UNIQUE_ID );
return $return;
}
switch( strtoupper( $config )) {
case Util::$ALLOWEMPTY:
if( isset( $this->config[Util::$ALLOWEMPTY] )) {
return $this->config[Util::$ALLOWEMPTY];
}
break;
case Util::$COMPSINFO:
$this->compix = [];
$info = [];
if( ! empty( $this->components )) {
foreach( $this->components as $cix => $component ) {
if( empty( $component )) {
continue;
}
$info[$cix][$LCORDNO] = $cix + 1;
$info[$cix][$LCTYPE] = $component->compType;
$info[$cix][$LCUID] = $component->getProperty( Util::$UID );
$info[$cix][$LCPROPS] = $component->getConfig( Util::$PROPINFO );
$info[$cix][$LCSUB] = $component->getConfig( Util::$COMPSINFO );
}
}
return $info;
break;
case Util::$LANGUAGE: // get language for calendar component as defined in [RFC 1766]
if( isset( $this->config[Util::$LANGUAGE] )) {
return $this->config[Util::$LANGUAGE];
}
break;
case Util::$PROPINFO:
$output = [];
if( ! Util::isCompInList( $this->compType, Util::$SUBCOMPS )) {
if( empty( $this->uid )) {
$this->uid = Util::makeUid( $this->getConfig( Util::$UNIQUE_ID ));
}
$output[Util::$UID] = 1;
if( empty( $this->dtstamp )) {
$this->dtstamp = Util::makeDtstamp();
}
$output[Util::$DTSTAMP] = 1;
}
if( ! empty( $this->summary )) {
$output[Util::$SUMMARY] = 1;
}
if( ! empty( $this->description )) {
$output[Util::$DESCRIPTION] = count( $this->description );
}
if( ! empty( $this->dtstart )) {
$output[Util::$DTSTART] = 1;
}
if( ! empty( $this->dtend )) {
$output[Util::$DTEND] = 1;
}
if( ! empty( $this->due )) {
$output[Util::$DUE] = 1;
}
if( ! empty( $this->duration )) {
$output[Util::$DURATION] = 1;
}
if( ! empty( $this->rrule )) {
$output[Util::$RRULE] = count( $this->rrule );
}
if( ! empty( $this->rdate )) {
$output[Util::$RDATE] = count( $this->rdate );
}
if( ! empty( $this->exdate )) {
$output[Util::$EXDATE] = count( $this->exdate );
}
if( ! empty( $this->exrule )) {
$output[Util::$EXRULE] = count( $this->exrule );
}
if( ! empty( $this->action )) {
$output[Util::$ACTION] = 1;
}
if( ! empty( $this->attach )) {
$output[Util::$ATTACH] = count( $this->attach );
}
if( ! empty( $this->attendee )) {
$output[Util::$ATTENDEE] = count( $this->attendee );
}
if( ! empty( $this->categories )) {
$output[Util::$CATEGORIES] = count( $this->categories );
}
if( ! empty( $this->class )) {
$output[Util::$CLASS] = 1;
}
if( ! empty( $this->comment )) {
$output[Util::$COMMENT] = count( $this->comment );
}
if( ! empty( $this->completed )) {
$output[Util::$COMPLETED] = 1;
}
if( ! empty( $this->contact )) {
$output[Util::$CONTACT] = count( $this->contact );
}
if( ! empty( $this->created )) {
$output[Util::$CREATED] = 1;
}
if( ! empty( $this->freebusy )) {
$output[Util::$FREEBUSY] = count( $this->freebusy );
}
if( ! empty( $this->geo )) {
$output[Util::$GEO] = 1;
}
if( ! empty( $this->lastmodified )) {
$output[Util::$LAST_MODIFIED] = 1;
}
if( ! empty( $this->location )) {
$output[Util::$LOCATION] = 1;
}
if( ! empty( $this->organizer )) {
$output[Util::$ORGANIZER] = 1;
}
if( ! empty( $this->percentcomplete )) {
$output[Util::$PERCENT_COMPLETE] = 1;
}
if( ! empty( $this->priority )) {
$output[Util::$PRIORITY] = 1;
}
if( ! empty( $this->recurrenceid )) {
$output[Util::$RECURRENCE_ID] = 1;
}
if( ! empty( $this->relatedto )) {
$output[Util::$RELATED_TO] = count( $this->relatedto );
}
if( ! empty( $this->repeat )) {
$output[Util::$REPEAT] = 1;
}
if( ! empty( $this->requeststatus )) {
$output[Util::$REQUEST_STATUS] = count( $this->requeststatus );
}
if( ! empty( $this->resources )) {
$output[Util::$RESOURCES] = count( $this->resources );
}
if( ! empty( $this->sequence )) {
$output[Util::$SEQUENCE] = 1;
}
if( ! empty( $this->status )) {
$output[Util::$STATUS] = 1;
}
if( ! empty( $this->transp )) {
$output[Util::$TRANSP] = 1;
}
if( ! empty( $this->trigger )) {
$output[Util::$TRIGGER] = 1;
}
if( ! empty( $this->tzid )) {
$output[Util::$TZID] = 1;
}
if( ! empty( $this->tzname )) {
$output[Util::$TZNAME] = count( $this->tzname );
}
if( ! empty( $this->tzoffsetfrom )) {
$output[Util::$TZOFFSETFROM] = 1;
}
if( ! empty( $this->tzoffsetto )) {
$output[Util::$TZOFFSETTO] = 1;
}
if( ! empty( $this->tzurl )) {
$output[Util::$TZURL] = 1;
}
if( ! empty( $this->url )) {
$output[Util::$URL] = 1;
}
if( ! empty( $this->xprop )) {
$output[Util::$X_PROP] = count( $this->xprop );
}
return $output;
break;
case Util::$SETPROPERTYNAMES:
return array_keys( $this->getConfig( Util::$PROPINFO ));
break;
case Util::$TZID:
if( isset( $this->config[Util::$TZID] )) {
return $this->config[Util::$TZID];
}
break;
case Util::$UNIQUE_ID:
if( empty( $this->config[Util::$UNIQUE_ID] )) {
$this->config[Util::$UNIQUE_ID] = ( isset( $_SERVER[Util::$SERVER_NAME] ))
? gethostbyname( $_SERVER[Util::$SERVER_NAME] )
: Util::$LOCALHOST;
}
return $this->config[Util::$UNIQUE_ID];
break;
}
return false;
}
/**
* General component config setting
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.23.12 - 2017-04-22
* @param mixed $config
* @param string $value
* @param bool $softUpdate
* @return bool true on success
*/
public function setConfig( $config, $value = null, $softUpdate = null ) {
if( is_null( $softUpdate )) {
$softUpdate = false;
}
if( is_array( $config )) {
$config = array_change_key_case( $config, CASE_UPPER );
foreach( $config as $cKey => $cValue ) {
if( false === $this->setConfig( $cKey, $cValue, $softUpdate )) {
return false;
}
}
return true;
}
$res = false;
switch( strtoupper( $config )) {
case Util::$ALLOWEMPTY:
$this->config[Util::$ALLOWEMPTY] = $value;
$subcfg = [ Util::$ALLOWEMPTY => $value ];
$res = true;
break;
case Util::$LANGUAGE: // set language for component as defined in [RFC 1766]
$value = trim( $value );
if( empty( $this->config[Util::$LANGUAGE] ) || ! $softUpdate ) {
$this->config[Util::$LANGUAGE] = $value;
}
$subcfg = [ Util::$LANGUAGE => $value ];
$res = true;
break;
case Util::$TZID:
$this->config[Util::$TZID] = trim( $value );
$subcfg = [ Util::$TZID => trim( $value ) ];
$res = true;
break;
case Util::$UNIQUE_ID:
$value = trim( $value );
$this->config[Util::$UNIQUE_ID] = $value;
$subcfg = [ Util::$UNIQUE_ID => $value ];
$res = true;
break;
default: // any unvalid config key.. .
return true;
}
if( ! $res ) {
return false;
}
if( isset( $subcfg ) && ! empty( $this->components )) {
foreach( $subcfg as $cfgkey => $cfgvalue ) {
foreach( $this->components as $cix => $component ) {
$res = $this->components[$cix]->setConfig( $cfgkey, $cfgvalue, $softUpdate );
if( ! $res ) {
break 2;
}
}
}
}
return $res;
}
/**
* Return number of components
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.23.5 - 2017-04-13
* @return int
*/
public function countComponents() {
return ( empty( $this->components )) ? 0 : count( $this->components );
}
/**
* Return new calendar component, included in calendar or component
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.26 - 2018-11-10
* @param string $compType component type
* @return mixed CalendarComponent|bool
*/
public function newComponent( $compType ) {
$config = $this->getConfig();
$ix = ( empty( $this->components ))
? 0
: key( array_slice( $this->components, -1, 1, true )) + 1;
switch( ucfirst( \strtolower( $compType ))) {
case self::VALARM :
$this->components[$ix] = new Valarm( $config );
break;
case self::VEVENT :
$this->components[$ix] = new Vevent( $config );
break;
case self::VTODO :
$this->components[$ix] = new Vtodo( $config );
break;
case self::VJOURNAL :
$this->components[$ix] = new Vjournal( $config );
break;
case self::VFREEBUSY :
$this->components[$ix] = new Vfreebusy( $config );
break;
case self::VTIMEZONE :
array_unshift( $this->components, new Vtimezone( $config ));
$ix = 0;
break;
case self::STANDARD :
array_unshift( $this->components, new Vtimezone( self::STANDARD, $config ));
$ix = 0;
break;
case self::DAYLIGHT :
$this->components[$ix] = new Vtimezone( self::DAYLIGHT, $config );
break;
default:
return false;
}
return $this->components[$ix];
}
/**
* Delete calendar subcomponent from component container
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.26.1 - 2018-11-17
* @param mixed $arg1 ordno / component type / component uid
* @param mixed $arg2 ordno if arg1 = component type
* @return bool true on success
*/
public function deleteComponent( $arg1, $arg2 = false ) {
if( ! isset( $this->components )) {
return false;
}
$argType = $index = null;
if( ctype_digit((string) $arg1 )) {
$argType = self::$INDEX;
$index = (int) $arg1 - 1;
}
elseif( Util::isCompInList( $arg1, Util::$ALLCOMPS )) {
$argType = ucfirst( strtolower( $arg1 ));
$index = ( ! empty( $arg2 ) && ctype_digit((string) $arg2 )) ? (( int ) $arg2 - 1 ) : 0;
}
$cix2dC = 0;
$remove = false;
foreach( $this->components as $cix => $component ) {
if(( self::$INDEX == $argType ) && ( $index == $cix )) {
unset( $this->components[$cix] );
$remove = true;
break;
}
elseif( $argType == $component->compType ) {
if( $index == $cix2dC ) {
unset( $this->components[$cix] );
$remove = true;
break;
}
$cix2dC++;
}
elseif( ! $argType &&
( $arg1 == $component->getProperty( Util::$UID ))) {
unset( $this->components[$cix] );
$remove = true;
break;
}
} // end foreach( $this->components as $cix => $component )
if( $remove ) {
$this->components = array_filter( $this->components );
return true;
}
return false;
}
/**
* Add calendar component as subcomponent to container for subcomponents
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.26.1 - 2018-11-17
* @param object $component CalendarComponent
* @param mixed $arg1 ordno/component type/ component uid
* @param mixed $arg2 ordno if arg1 = component type
* @return bool
*/
public function setComponent( $component, $arg1 = false, $arg2 = false ) {
if( ! isset( $this->components )) {
return false;
}
$component->setConfig( $this->getConfig(), false, true );
if( ! Util::isCompInList( $component->compType, Util::$SUBCOMPS )) {
/* make sure dtstamp and uid is set */
$component->getProperty( Util::$DTSTAMP );
$component->getProperty( Util::$UID );
}
if( ! $arg1 ) { // plain insert, last in chain
$this->components[] = clone $component;
return true;
}
$argType = $index = null;
if( ctype_digit((string) $arg1 )) { // index insert/replace
$argType = self::$INDEX;
$index = (int) $arg1 - 1;
}
elseif( Util::isCompInList( $arg1, Util::$MCOMPS )) {
$argType = ucfirst( \strtolower( $arg1 ));
$index = ( ctype_digit((string) $arg2 )) ? ((int) $arg2 ) - 1 : 0;
}
// else if arg1 is set, arg1 must be an UID
$cix2sC = 0;
foreach( $this->components as $cix => $component2 ) {
if( empty( $component2 )) {
continue;
}
if(( self::$INDEX == $argType ) && ( $index == $cix )) { // index insert/replace
$this->components[$cix] = clone $component;
return true;
}
elseif( $argType == $component2->compType ) { // component Type index insert/replace
if( $index == $cix2sC ) {
$this->components[$cix] = clone $component;
return true;
}
$cix2sC++;
}
elseif( ! $argType && ( $arg1 == $component2->getProperty( Util::$UID ))) {
$this->components[$cix] = clone $component; // UID insert/replace
return true;
}
}
/* arg1=index and not found.. . insert at index .. .*/
if( self::$INDEX == $argType ) {
$this->components[$index] = clone $component;
\ksort( $this->components, SORT_NUMERIC );
}
else { /* not found.. . insert last in chain anyway .. .*/
$this->components[] = clone $component;
}
return true;
}
}

View File

@@ -0,0 +1,53 @@
<?php
/**
* iCalcreator, the PHP class package managing iCal (rfc2445/rfc5445) calendar information.
*
* copyright (c) 2007-2019 Kjell-Inge Gustafsson, kigkonsult, All rights reserved
* Link https://kigkonsult.se
* Package iCalcreator
* Version 2.26.8
* License Subject matter of licence is the software iCalcreator.
* The above copyright, link, package and version notices,
* this licence notice and the invariant [rfc5545] PRODID result use
* as implemented and invoked in iCalcreator shall be included in
* all copies or substantial portions of the iCalcreator.
*
* iCalcreator 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 3 of the License,
* or (at your option) any later version.
*
* iCalcreator 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 iCalcreator. If not, see <https://www.gnu.org/licenses/>.
*
* This file is a part of iCalcreator.
*/
namespace Kigkonsult\Icalcreator;
/**
* interface IcalInterface
*
* @author Kjell-Inge Gustafsson <ical@kigkonsult.se>
* @see https://en.wikipedia.org/wiki/Basic_access_authentication
* @see https://tools.ietf.org/html/rfc7617
*/
interface IcalInterface
{
/**
* Class constants
*/
const VTIMEZONE = 'Vtimezone';
const STANDARD = 'Standard';
const DAYLIGHT = 'Daylight';
const VEVENT = 'Vevent';
const VTODO = 'Vtodo';
const VJOURNAL = 'Vjournal';
const VFREEBUSY = 'Vfreebusy';
const VALARM = 'Valarm';
}

View File

@@ -0,0 +1,237 @@
<?php
/**
* iCalcreator, the PHP class package managing iCal (rfc2445/rfc5445) calendar information.
*
* copyright (c) 2007-2019 Kjell-Inge Gustafsson, kigkonsult, All rights reserved
* Link https://kigkonsult.se
* Package iCalcreator
* Version 2.26.8
* License Subject matter of licence is the software iCalcreator.
* The above copyright, link, package and version notices,
* this licence notice and the invariant [rfc5545] PRODID result use
* as implemented and invoked in iCalcreator shall be included in
* all copies or substantial portions of the iCalcreator.
*
* iCalcreator 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 3 of the License,
* or (at your option) any later version.
*
* iCalcreator 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 iCalcreator. If not, see <https://www.gnu.org/licenses/>.
*
* This file is a part of iCalcreator.
*/
namespace Kigkonsult\Icalcreator;
use Kigkonsult\Icalcreator\Util\Util;
use function array_reverse;
use function array_shift;
use function ctype_lower;
use function ctype_upper;
use function explode;
use function file_put_contents;
use function implode;
use function ksort;
use function is_dir;
use function is_file;
use function is_writable;
use function preg_replace;
use function sprintf;
use function str_replace;
use function strlen;
use function strpos;
use function substr;
use function ucfirst;
/**
* iCalcreator vCard support class
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.26 - 2018-11-10
*/
class IcalvCard
{
/**
* 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.26 - 2018-11-10
* @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')
* @return mixed bool true (if directory set and save ok), string (if not), false on error
* @static
*/
public static function iCal2vCard( $email, $version = null, $directory = null, $ext = null ) {
static $UCMAILTOCOLON = 'MAILTO:';
static $FMTFN = "FN:%s\r\n";
static $FMTN = 'N:%s';
static $V2_1 = '2.1';
static $AT = '@';
static $V4_0 = '4.0';
static $FMTEMAIL = "EMAIL:%s\r\n";
static $BEGINVCARD = "BEGIN:VCARD\r\n";
static $FMTVERSION = "VERSION:%s\r\n";
static $FMTPRODID = "PRODID:-//kigkonsult.se %s\r\n";
static $FMTREV = "REV:%s\r\n";
static $YMDTHISZ = 'Ymd\THis\Z';
static $ENDVCARD = "END:VCARD\r\n";
static $EXPR = '/[^a-z0-9.]/i';
static $FMTFNAME = '%s%s%s.%s';
static $EXTVCF = 'vcf';
if( empty( $version )) {
$version = $V2_1;
}
if( false === ( $pos = strpos( $email, $AT ))) {
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( $UCMAILTOCOLON, null, $email );
$name = $person = substr( $email, 0, $pos );
if( ctype_upper( $name ) || ctype_lower( $name )) {
$name = [ $name ];
}
else {
if( false !== ( $pos = strpos( $name, Util::$DOT ))) {
$name = explode( Util::$DOT, $name );
foreach( $name as $k => $part ) {
$name[$k] = ucfirst( $part );
}
}
else { // split camelCase
$chars = $name;
$name = [ $chars[0] ];
$k = 0;
$len = strlen( $chars );
$x = 1;
while( $x < $len ) {
if( ctype_upper( $chars[$x] )) {
$k += 1;
$name[$k] = null;
}
$name[$k] .= $chars[$x];
$x++;
}
}
}
$FN = sprintf( $FMTFN, implode( utiL::$SP1, $name ));
$name = array_reverse( $name );
$N = sprintf( $FMTN, array_shift( $name ));
$scCnt = 0;
while( null != ( $part = array_shift( $name ))) {
if(( $V4_0 != $version ) || ( 4 > $scCnt )) {
$scCnt += 1;
}
$N .= Util::$SEMIC . $part;
}
while(( $V4_0 == $version ) && ( 4 > $scCnt )) {
$N .= Util::$SEMIC;
$scCnt += 1;
}
$N .= Util::$CRLF;
$EMAIL = sprintf( $FMTEMAIL, $email );
/* create vCard */
$vCard = $BEGINVCARD;
$vCard .= sprintf( $FMTVERSION, $version );
$vCard .= sprintf( $FMTPRODID, ICALCREATOR_VERSION );
$vCard .= $N;
$vCard .= $FN;
$vCard .= $EMAIL;
$vCard .= sprintf( $FMTREV, gmdate( $YMDTHISZ ));
$vCard .= $ENDVCARD;
/* save each vCard as (unique) single file */
if( empty( $directory )) {
return $vCard; /* return vCard */
}
if( empty( $ext )) {
$ext = $EXTVCF;
}
$fprfx = $directory . preg_replace( $EXPR, null, $email );
$cnt = 1;
$dbl = null;
$fName = sprintf( $FMTFNAME, $fprfx, $dbl, $ext );
while( is_file( $fName )) {
$cnt += 1;
$dbl = $cnt;
$fName = sprintf( $FMTFNAME, $fprfx, $dbl, $ext );
}
if( false === file_put_contents( $fName, $vCard )) {
return false;
}
return true;
}
/**
* Convert ATTENDEEs, CONTACTs and ORGANIZERs (in email format) to vCards
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.23.20 - 2017-02-20
* @param Vcalendar $calendar iCalcreator Vcalendar instance
* @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')
* @return mixed bool true (if directory set and save ok), string (if not), false on error
* @static
*/
public static function iCal2vCards( Vcalendar $calendar, $version = null, $directory = null, $ext = null ) {
static $vCardP = [ 'ATTENDEE', 'CONTACT', 'ORGANIZER' ];
static $AT = '@';
static $UCMAILTOCOLON = 'MAILTO:';
$hits = [];
foreach( $vCardP as $prop ) {
$hits2 = $calendar->getProperty( $prop );
foreach( $hits2 as $propValue => $occCnt ) {
if( false === ( $pos = strpos( $propValue, $AT ))) {
continue;
}
$propValue = str_replace( $UCMAILTOCOLON, null, $propValue );
if( isset( $hits[$propValue] )) {
$hits[$propValue] += $occCnt;
}
else {
$hits[$propValue] = $occCnt;
}
}
}
if( empty( $hits )) {
return false;
}
ksort( $hits );
$output = null;
foreach( $hits as $email => $skip ) {
$res = self::iCal2vCard( $email, $version, $directory, $ext );
if( ! empty( $directory ) && ! $res ) {
return false;
}
elseif( ! $res ) {
return $res;
}
else {
$output .= $res;
}
}
if( $directory ) {
return true;
}
return ( empty( $output )) ? false : $output;
}
}

View File

@@ -0,0 +1,511 @@
<?php
/**
* iCalcreator, the PHP class package managing iCal (rfc2445/rfc5445) calendar information.
*
* copyright (c) 2007-2019 Kjell-Inge Gustafsson, kigkonsult, All rights reserved
* Link https://kigkonsult.se
* Package iCalcreator
* Version 2.26.8
* License Subject matter of licence is the software iCalcreator.
* The above copyright, link, package and version notices,
* this licence notice and the invariant [rfc5545] PRODID result use
* as implemented and invoked in iCalcreator shall be included in
* all copies or substantial portions of the iCalcreator.
*
* iCalcreator 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 3 of the License,
* or (at your option) any later version.
*
* iCalcreator 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 iCalcreator. If not, see <https://www.gnu.org/licenses/>.
*
* This file is a part of iCalcreator.
*/
namespace Kigkonsult\Icalcreator;
use Kigkonsult\Icalcreator\Util\Util;
use DateTimeZone;
use DateTime;
use Exception;
use function array_keys;
use function date;
use function end;
use function explode;
use function floor;
use function is_array;
use function is_int;
use function is_null;
use function ksort;
use function reset;
use function sprintf;
use function str_replace;
use function strcasecmp;
use function strpos;
use function strtolower;
use function substr;
use function trim;
/**
* iCalcreator timezone management class
*
* Manages loosely coupled iCalcreator Vcalendar (timezone) functions
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.26 - 2018-11-10
*/
class TimezoneHandler
{
private static $FMTTIMESTAMP = '@%s';
private static $OFFSET = 'offset';
private static $TIME = 'time';
/**
* Create a calendar timezone and standard/daylight components
*
* Result when 'Europe/Stockholm' and no from/to arguments is used as timezone:
* BEGIN:VTIMEZONE
* TZID:Europe/Stockholm
* BEGIN:STANDARD
* DTSTART:20101031T020000
* TZOFFSETFROM:+0200
* TZOFFSETTO:+0100
* TZNAME:CET
* END:STANDARD
* BEGIN:DAYLIGHT
* DTSTART:20100328T030000
* TZOFFSETFROM:+0100
* TZOFFSETTO:+0200
* TZNAME:CEST
* END:DAYLIGHT
* END:VTIMEZONE
*
* Generates components for all transitions in a date range,
* based on contribution by Yitzchok Lavi <icalcreator@onebigsystem.com>
* Additional changes jpirkey
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.26 - 2018-11-10
* @param Vcalendar $calendar iCalcreator calendar instance
* @param string $timezone valid timezone avveptable by PHP5 DateTimeZone
* @param array $xProp *[x-propName => x-propValue]
* @param int $from unix timestamp
* @param int $to unix timestamp
* @return bool
* @static
*/
public static function createTimezone(
Vcalendar $calendar,
$timezone,
$xProp = [],
$from = null,
$to = null
) {
static $Y = 'Y ';
static $YMD = 'Ymd';
static $T000000 = 'T000000';
static $MINUS7MONTH = '-7 month';
static $YMD2 = 'Y-m-d';
static $T235959 = 'T235959';
static $PLUS18MONTH = '+18 month';
static $TS = 'ts';
static $YMDHIS3 = 'Y-m-d-H-i-s';
static $SECONDS = 'seconds';
static $ABBR = 'abbr';
static $ISDST = 'isdst';
static $NOW = 'now';
static $YMDTHISO = 'Y-m-d\TH:i:s O';
if( empty( $timezone )) {
return false;
}
if( ! empty( $from ) && ! is_int( $from )) {
return false;
}
if( ! empty( $to ) && ! is_int( $to )) {
return false;
}
try {
$newTz = new DateTimeZone( $timezone );
$utcTz = new DateTimeZone( Util::$UTC );
}
catch( Exception $e ) {
return false;
}
if( empty( $from ) || empty( $to )) {
$dates = array_keys( $calendar->getProperty( Util::$DTSTART ));
if( empty( $dates )) {
$dates = [ date( $YMD ) ];
}
}
if( ! empty( $from )) {
try {
$timestamp = sprintf( self::$FMTTIMESTAMP, $from );
$dateFrom = new DateTime( $timestamp ); // set lowest date (UTC)
}
catch( Exception $e ) {
return false;
}
}
else {
try {
$from = reset( $dates ); // set lowest date to the lowest dtstart date
$dateFrom = new DateTime( $from . $T000000, $newTz );
$dateFrom->modify( $MINUS7MONTH ); // set $dateFrom to seven month before the lowest date
$dateFrom->setTimezone( $utcTz ); // convert local date to UTC
}
catch( Exception $e ) {
return false;
}
}
$dateFromYmd = $dateFrom->format( $YMD2 );
if( ! empty( $to )) {
try {
$timestamp = sprintf( self::$FMTTIMESTAMP, $to );
$dateTo = new DateTime( $timestamp ); // set end date (UTC)
}
catch( Exception $e ) {
return false;
}
}
else {
try {
$to = end( $dates ); // set highest date to the highest dtstart date
$dateTo = new DateTime( $to . $T235959, $newTz );
}
catch( Exception $e ) {
return false;
}
$dateTo->modify( $PLUS18MONTH ); // set $dateTo to 18 month after the highest date
$dateTo->setTimezone( $utcTz ); // convert local date to UTC
}
$dateToYmd = $dateTo->format( $YMD2 );
$transTemp = [];
$prevOffsetfrom = 0;
$stdIx = $dlghtIx = null;
$prevTrans = false;
$transitions = $newTz->getTransitions();
// For generic timezones, there is no transition
if ( ! $transitions ) {
try {
$timestamp = sprintf( self::$FMTTIMESTAMP, $newTz->timezone );
$date = new \DateTime( $timestamp );
}
catch( \Exception $e ) {
return false;
}
} else {
foreach( $transitions as $tix => $trans ) { // all transitions in date-time order!!
if( 0 > (int) date( $Y, $trans[$TS] )) { // skip negative year... but save offset
$prevOffsetfrom = $trans[self::$OFFSET]; // previous trans offset will be 'next' trans offsetFrom
continue;
}
try {
$timestamp = sprintf( self::$FMTTIMESTAMP, $trans[$TS] );
$date = new DateTime( $timestamp ); // set transition date (UTC)
}
catch( Exception $e ) {
return false;
}
$transDateYmd = $date->format( $YMD2 );
if( $transDateYmd < $dateFromYmd ) {
$prevOffsetfrom = $trans[self::$OFFSET]; // previous trans offset will be 'next' trans offsetFrom
$prevTrans = $trans; // we save it in case we don't find any that match
$prevTrans[Util::$TZOFFSETFROM] = ( 0 < $tix ) ? $transitions[$tix - 1][self::$OFFSET] : 0;
continue;
}
if( $transDateYmd > $dateToYmd ) {
break;
} // loop always (?) breaks here
if( ! empty( $prevOffsetfrom ) || ( 0 == $prevOffsetfrom )) {
$trans[Util::$TZOFFSETFROM] = $prevOffsetfrom; // i.e. set previous offsetto as offsetFrom
$date->modify( $trans[Util::$TZOFFSETFROM] . $SECONDS ); // convert utc date to local date
$d = \explode( Util::$MINUS, $date->format( $YMDHIS3 ));
$trans[self::$TIME] = [
Util::$LCYEAR => (int) $d[0], // set date to array
Util::$LCMONTH => (int) $d[1], // to ease up dtstart and (opt) rdate setting
Util::$LCDAY => (int) $d[2],
Util::$LCHOUR => (int) $d[3],
Util::$LCMIN => (int) $d[4],
Util::$LCSEC => (int) $d[5],
];
}
$prevOffsetfrom = $trans[self::$OFFSET];
if( true !== $trans[$ISDST] ) { // standard timezone
if( ! empty( $stdIx ) && isset( $transTemp[$stdIx][Util::$TZOFFSETFROM] ) &&
( $transTemp[$stdIx][$ABBR] == $trans[$ABBR] ) &&
( $transTemp[$stdIx][Util::$TZOFFSETFROM] == $trans[Util::$TZOFFSETFROM] ) &&
( $transTemp[$stdIx][self::$OFFSET] == $trans[self::$OFFSET] )) {
$transTemp[$stdIx][Util::$RDATE][] = $trans[self::$TIME];
continue; // check for any repeating rdate's (in order)
}
$stdIx = $tix;
} // end standard timezone
else { // daylight timezone
if( ! empty( $dlghtIx ) && isset( $transTemp[$dlghtIx][Util::$TZOFFSETFROM] ) &&
( $transTemp[$dlghtIx][$ABBR] == $trans[$ABBR] ) &&
( $transTemp[$dlghtIx][Util::$TZOFFSETFROM] == $trans[Util::$TZOFFSETFROM] ) &&
( $transTemp[$dlghtIx][self::$OFFSET] == $trans[self::$OFFSET] )) {
$transTemp[$dlghtIx][Util::$RDATE][] = $trans[self::$TIME];
continue; // check for any repeating rdate's (in order)
}
$dlghtIx = $tix;
} // end daylight timezone
$transTemp[$tix] = $trans;
} // end foreach( $transitions as $tix => $trans )
}
$timezoneComp = $calendar->newVtimezone();
$timezoneComp->setproperty( Util::$TZID, $timezone );
if( ! empty( $xProp )) {
foreach( $xProp as $xPropName => $xPropValue ) {
if( Util::isXprefixed( $xPropName )) {
$timezoneComp->setproperty( $xPropName, $xPropValue );
}
}
}
if( empty( $transTemp )) { // if no match is found
if( $prevTrans ) { // we use the last transition (before startdate) for the tz info
try {
$timestamp = sprintf( self::$FMTTIMESTAMP, $prevTrans[$TS] );
$date = new DateTime( $timestamp ); // set transition date (UTC)
}
catch( Exception $e ) {
return false;
}
$date->modify( $prevTrans[Util::$TZOFFSETFROM] . $SECONDS );// convert utc date to local date
$d = explode( Util::$MINUS, $date->format( $YMDHIS3 )
); // set arr-date to ease up dtstart setting
$prevTrans[self::$TIME] = [
Util::$LCYEAR => (int) $d[0],
Util::$LCMONTH => (int) $d[1],
Util::$LCDAY => (int) $d[2],
Util::$LCHOUR => (int) $d[3],
Util::$LCMIN => (int) $d[4],
Util::$LCSEC => (int) $d[5],
];
$transTemp[0] = $prevTrans;
} // end if( $prevTrans )
else { // or we use the timezone identifier to BUILD the standard tz info (?)
try {
$date = new DateTime( $NOW, $newTz );
}
catch( Exception $e ) {
return false;
}
$transTemp[0] = [
self::$TIME => $date->format( $YMDTHISO ),
self::$OFFSET => $date->format( Util::$Z ),
Util::$TZOFFSETFROM => $date->format( Util::$Z ),
$ISDST => false,
];
}
} // end if( empty( $transTemp ))
foreach( $transTemp as $tix => $trans ) { // create standard/daylight subcomponents
$subComp = ( true !== $trans[$ISDST] )
? $timezoneComp->newStandard()
: $timezoneComp->newDaylight();
$subComp->setProperty( Util::$DTSTART, $trans[self::$TIME] );
if( ! empty( $trans[$ABBR] )) {
$subComp->setProperty( Util::$TZNAME, $trans[$ABBR] );
}
if( isset( $trans[Util::$TZOFFSETFROM] )) {
$subComp->setProperty( Util::$TZOFFSETFROM, self::offsetSec2His( $trans[Util::$TZOFFSETFROM] ));
}
$subComp->setProperty( Util::$TZOFFSETTO, self::offsetSec2His( $trans[self::$OFFSET] ));
if( isset( $trans[Util::$RDATE] )) {
$subComp->setProperty( Util::$RDATE, $trans[Util::$RDATE] );
}
}
return true;
}
/**
* Return iCal offset [-/+]hhmm[ss] (string) from UTC offset seconds
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.26 - 2018-11-10
* @param string $seconds
* @return string
* @static
*/
public static function offsetSec2His( $seconds ) {
static $FMT = '%02d';
switch( substr( $seconds, 0, 1 )) {
case Util::$MINUS :
$output = Util::$MINUS;
$seconds = substr( $seconds, 1 );
break;
case Util::$PLUS :
$output = Util::$PLUS;
$seconds = substr( $seconds, 1 );
break;
default :
$output = Util::$PLUS;
break;
}
$output .= sprintf( $FMT, ((int) floor( $seconds / 3600 ))); // hour
$seconds = $seconds % 3600;
$output .= sprintf( $FMT, ((int) floor( $seconds / 60 ))); // min
$seconds = $seconds % 60;
if( 0 < $seconds ) {
$output .= sprintf( $FMT, $seconds ); // sec
}
return $output;
}
/**
* Very basic conversion of a MS timezone to a PHP5 valid (Date-)timezone
* matching (MS) UCT offset and time zone descriptors
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.23.8 - 2017-04-17
* @param string $timezone to convert
* @return bool
* @static
*/
public static function ms2phpTZ( & $timezone ) {
static $REPL1 = [ 'GMT', 'gmt', 'utc' ];
static $REPL2 = [ '(', ')', '&', ',', ' ' ];
static $PUTC = '(UTC';
static $ENDP = ')';
static $TIMEZONE_ID = 'timezone_id';
if( empty( $timezone )) {
return false;
}
$search = str_replace( Util::$QQ, null, $timezone );
$search = str_replace( $REPL1, Util::$UTC, $search );
if( $PUTC != substr( $search, 0, 4 )) {
return false;
}
if( false === ( $pos = strpos( $search, $ENDP ))) {
return false;
}
$searchOffset = substr( $search, 4, ( $pos - 4 ));
$searchOffset = Util::tz2offset( str_replace( Util::$COLON, null, $searchOffset ));
while( Util::$SP1 == $search[( $pos + 1 )] ) {
$pos += 1;
}
$searchText = trim( str_replace( $REPL2, Util::$SP1, substr( $search, ( $pos + 1 ))));
$searchWords = explode( Util::$SP1, $searchText );
try {
$timezoneAbbreviations = DateTimeZone::listAbbreviations();
}
catch( Exception $e ) {
return false;
}
$hits = [];
foreach( $timezoneAbbreviations as $name => $transitions ) {
foreach( $transitions as $cnt => $transition ) {
if( empty( $transition[self::$OFFSET] ) ||
empty( $transition[$TIMEZONE_ID] ) ||
( $transition[self::$OFFSET] != $searchOffset )) {
continue;
}
$cWords = explode( Util::$L, $transition[$TIMEZONE_ID] );
$cPrio = $hitCnt = $rank = 0;
foreach( $cWords as $cWord ) {
if( empty( $cWord )) {
continue;
}
$cPrio += 1;
$sPrio = 0;
foreach( $searchWords as $sWord ) {
if( empty( $sWord ) || ( self::$TIME == strtolower( $sWord ))) {
continue;
}
$sPrio += 1;
if( 0 == strcasecmp( $cWord, $sWord )) {
$hitCnt += 1;
$rank += ( $cPrio + $sPrio );
}
else {
$rank += 10;
}
}
}
if( 0 < $hitCnt ) {
$hits[$rank][] = $transition[$TIMEZONE_ID];
}
} // end foreach( $transitions as $cnt => $transition )
} // end foreach( $timezoneAbbreviations as $name => $transitions )
if( empty( $hits )) {
return false;
}
ksort( $hits );
foreach( $hits as $rank => $tzs ) {
if( ! empty( $tzs )) {
$timezone = reset( $tzs );
return true;
}
}
return false;
}
/**
* Transforms a dateTime from a timezone to another
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.22.23 - 2017-03-04
* @param mixed $date date to alter
* @param string $tzFrom PHP valid 'from' timezone
* @param string $tzTo PHP valid 'to' timezone, default Util::$UTC
* @param string $format date output format, default 'Ymd\THis'
* @return bool true on success, false on error
* @static
*/
public static function transformDateTime( & $date, $tzFrom, $tzTo = null, $format = null ) {
static $YMDTHIS = 'Ymd\THis';
if( is_null( $tzTo )) {
$tzTo = Util::$UTC;
}
elseif( Util::$Z == $tzTo ) {
$tzTo = Util::$UTC;
}
if( is_null( $format )) {
$format = $YMDTHIS;
}
if( is_array( $date ) && isset( $date[Util::$LCTIMESTAMP] )) {
try {
$timestamp = sprintf( self::$FMTTIMESTAMP, $date[Util::$LCTIMESTAMP] );
$d = new DateTime( $timestamp ); // set UTC date
$newTz = new DateTimeZone( $tzFrom );
$d->setTimezone( $newTz ); // convert to 'from' date
}
catch( Exception $e ) {
return false;
}
}
else {
if( Util::isArrayDate( $date )) {
if( isset( $date[Util::$LCtz] )) {
unset( $date[Util::$LCtz] );
}
$date = Util::date2strdate( Util::chkDateArr( $date ));
}
if( Util::$Z == substr( $date, -1 )) {
$date = substr( $date, 0, ( \strlen( $date ) - 2 ));
}
try {
$d = new DateTime( $date, new DateTimeZone( $tzFrom ));
}
catch( Exception $e ) {
return false;
}
}
try {
$newTz = new DateTimeZone( $tzTo );
$d->setTimezone( $newTz );
}
catch( Exception $e ) {
return false;
}
$date = $d->format( $format );
return true;
}
}

View File

@@ -0,0 +1,90 @@
<?php
/**
* iCalcreator, the PHP class package managing iCal (rfc2445/rfc5445) calendar information.
*
* copyright (c) 2007-2019 Kjell-Inge Gustafsson, kigkonsult, All rights reserved
* Link https://kigkonsult.se
* Package iCalcreator
* Version 2.26.8
* License Subject matter of licence is the software iCalcreator.
* The above copyright, link, package and version notices,
* this licence notice and the invariant [rfc5545] PRODID result use
* as implemented and invoked in iCalcreator shall be included in
* all copies or substantial portions of the iCalcreator.
*
* iCalcreator 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 3 of the License,
* or (at your option) any later version.
*
* iCalcreator 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 iCalcreator. If not, see <https://www.gnu.org/licenses/>.
*
* This file is a part of iCalcreator.
*/
namespace Kigkonsult\Icalcreator\Traits;
use Kigkonsult\Icalcreator\Util\Util;
/**
* ACTION property functions
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.26.2 - 2018-11-27
*/
trait ACTIONtrait
{
/**
* @var array component property ACTION value
* @access protected
*/
protected $action = null;
/**
* Return formatted output for calendar component property action
*
* @return string
*/
public function createAction() {
if( empty( $this->action )) {
return null;
}
if( empty( $this->action[Util::$LCvalue] )) {
return ( $this->getConfig( Util::$ALLOWEMPTY )) ? Util::createElement( Util::$ACTION ) : null;
}
return Util::createElement(
Util::$ACTION,
Util::createParams( $this->action[Util::$LCparams] ),
$this->action[Util::$LCvalue]
);
}
/**
* Set calendar component property action
*
* @param string $value "AUDIO" / "DISPLAY" / "EMAIL" / "PROCEDURE" / iana-token / x-name
* @param mixed $params
* @return bool
*/
public function setAction( $value, $params = null ) {
if( empty( $value )) {
if( $this->getConfig( Util::$ALLOWEMPTY )) {
$value = Util::$SP0;
}
else {
return false;
}
}
$this->action = [
Util::$LCvalue => Util::trimTrailNL( $value ),
Util::$LCparams => Util::setParams( $params ),
];
return true;
}
}

View File

@@ -0,0 +1,94 @@
<?php
/**
* iCalcreator, the PHP class package managing iCal (rfc2445/rfc5445) calendar information.
*
* copyright (c) 2007-2019 Kjell-Inge Gustafsson, kigkonsult, All rights reserved
* Link https://kigkonsult.se
* Package iCalcreator
* Version 2.26.8
* License Subject matter of licence is the software iCalcreator.
* The above copyright, link, package and version notices,
* this licence notice and the invariant [rfc5545] PRODID result use
* as implemented and invoked in iCalcreator shall be included in
* all copies or substantial portions of the iCalcreator.
*
* iCalcreator 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 3 of the License,
* or (at your option) any later version.
*
* iCalcreator 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 iCalcreator. If not, see <https://www.gnu.org/licenses/>.
*
* This file is a part of iCalcreator.
*/
namespace Kigkonsult\Icalcreator\Traits;
use Kigkonsult\Icalcreator\Util\Util;
/**
* ATTACH property functions
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.22.23 - 2017-02-02
*/
trait ATTACHtrait
{
/**
* @var array component property ATTACH value
* @access protected
*/
protected $attach = null;
/**
* Return formatted output for calendar component property attach
*
* @return string
*/
public function createAttach() {
if( empty( $this->attach )) {
return null;
}
$output = null;
foreach( $this->attach as $aix => $attachPart ) {
if( ! empty( $attachPart[Util::$LCvalue] )) {
$output .= Util::createElement(
Util::$ATTACH,
Util::createParams( $attachPart[Util::$LCparams] ),
$attachPart[Util::$LCvalue]
);
}
elseif( $this->getConfig( Util::$ALLOWEMPTY )) {
$output .= Util::createElement( Util::$ATTACH );
}
}
return $output;
}
/**
* Set calendar component property attach
*
* @param string $value
* @param array $params
* @param integer $index
* @return bool
*/
public function setAttach( $value, $params = null, $index = null ) {
if( empty( $value )) {
if( $this->getConfig( Util::$ALLOWEMPTY )) {
$value = Util::$SP0;
}
else {
return false;
}
}
Util::setMval( $this->attach, $value, $params, false, $index );
return true;
}
}

View File

@@ -0,0 +1,88 @@
<?php
/**
* iCalcreator, the PHP class package managing iCal (rfc2445/rfc5445) calendar information.
*
* copyright (c) 2007-2019 Kjell-Inge Gustafsson, kigkonsult, All rights reserved
* Link https://kigkonsult.se
* Package iCalcreator
* Version 2.26.8
* License Subject matter of licence is the software iCalcreator.
* The above copyright, link, package and version notices,
* this licence notice and the invariant [rfc5545] PRODID result use
* as implemented and invoked in iCalcreator shall be included in
* all copies or substantial portions of the iCalcreator.
*
* iCalcreator 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 3 of the License,
* or (at your option) any later version.
*
* iCalcreator 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 iCalcreator. If not, see <https://www.gnu.org/licenses/>.
*
* This file is a part of iCalcreator.
*/
namespace Kigkonsult\Icalcreator\Traits;
use Kigkonsult\Icalcreator\Util\Util;
use Kigkonsult\Icalcreator\Util\UtilAttendee;
/**
* ATTENDEE property functions
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.22.23 - 2017-02-17
*/
trait ATTENDEEtrait
{
/**
* @var array component property ATTENDEE value
* @access protected
*/
protected $attendee = null;
/**
* Return formatted output for calendar component property attendee
*
* @return string
*/
public function createAttendee() {
if( empty( $this->attendee )) {
return null;
}
return UtilAttendee::formatAttendee( $this->attendee, $this->getConfig( Util::$ALLOWEMPTY ));
}
/**
* Set calendar component property attach
*
* @param string $value
* @param array $params
* @param integer $index
* @return bool
*/
public function setAttendee( $value, $params = null, $index = null ) {
if( empty( $value )) {
if( $this->getConfig( Util::$ALLOWEMPTY )) {
$value = Util::$SP0;
}
else {
return false;
}
}
Util::setMval(
$this->attendee,
UtilAttendee::calAddressCheck( $value, false ),
UtilAttendee::prepAttendeeParams( $params, $this->compType, $this->getConfig( Util::$LANGUAGE )),
false,
$index
);
return true;
}
}

View File

@@ -0,0 +1,75 @@
<?php
/**
* iCalcreator, the PHP class package managing iCal (rfc2445/rfc5445) calendar information.
*
* copyright (c) 2007-2019 Kjell-Inge Gustafsson, kigkonsult, All rights reserved
* Link https://kigkonsult.se
* Package iCalcreator
* Version 2.26.8
* License Subject matter of licence is the software iCalcreator.
* The above copyright, link, package and version notices,
* this licence notice and the invariant [rfc5545] PRODID result use
* as implemented and invoked in iCalcreator shall be included in
* all copies or substantial portions of the iCalcreator.
*
* iCalcreator 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 3 of the License,
* or (at your option) any later version.
*
* iCalcreator 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 iCalcreator. If not, see <https://www.gnu.org/licenses/>.
*
* This file is a part of iCalcreator.
*/
namespace Kigkonsult\Icalcreator\Traits;
use Kigkonsult\Icalcreator\Util\Util;
use function sprintf;
/**
* CALSCALE property functions
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.22.23 - 2017-02-02
*/
trait CALSCALEtrait
{
/**
* @var string calendar property CALSCALE
* @access protected
*/
protected $calscale = null;
/**
* Return formatted output for calendar property calscale
*
* @return string
*/
public function createCalscale() {
return ( empty( $this->calscale ))
? null
: sprintf( self::$FMTICAL, Util::$CALSCALE, $this->calscale );
}
/**
* Set calendar property calscale
*
* @param string $value
* @return bool
*/
public function setCalscale( $value ) {
if( empty( $value )) {
return false;
}
$this->calscale = $value;
return true;
}
}

View File

@@ -0,0 +1,112 @@
<?php
/**
* iCalcreator, the PHP class package managing iCal (rfc2445/rfc5445) calendar information.
*
* copyright (c) 2007-2019 Kjell-Inge Gustafsson, kigkonsult, All rights reserved
* Link https://kigkonsult.se
* Package iCalcreator
* Version 2.26.8
* License Subject matter of licence is the software iCalcreator.
* The above copyright, link, package and version notices,
* this licence notice and the invariant [rfc5545] PRODID result use
* as implemented and invoked in iCalcreator shall be included in
* all copies or substantial portions of the iCalcreator.
*
* iCalcreator 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 3 of the License,
* or (at your option) any later version.
*
* iCalcreator 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 iCalcreator. If not, see <https://www.gnu.org/licenses/>.
*
* This file is a part of iCalcreator.
*/
namespace Kigkonsult\Icalcreator\Traits;
use Kigkonsult\Icalcreator\Util\Util;
use function implode;
use function is_array;
/**
* CATEGORIES property functions
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.22.23 - 2017-02-02
*/
trait CATEGORIEStrait
{
/**
* @var array component property CATEGORIES value
* @access protected
*/
protected $categories = null;
/**
* Return formatted output for calendar component property categories
*
* @return string
*/
public function createCategories() {
if( empty( $this->categories )) {
return null;
}
$output = null;
$lang = $this->getConfig( Util::$LANGUAGE );
foreach( $this->categories as $cx => $category ) {
if( empty( $category[Util::$LCvalue] )) {
if( $this->getConfig( Util::$ALLOWEMPTY )) {
$output .= Util::createElement( Util::$CATEGORIES );
}
continue;
}
if( is_array( $category[Util::$LCvalue] )) {
foreach( $category[Util::$LCvalue] as $cix => $cValue ) {
$category[Util::$LCvalue][$cix] = Util::strrep( $cValue );
}
$content = implode( Util::$COMMA, $category[Util::$LCvalue] );
}
else {
$content = Util::strrep( $category[Util::$LCvalue] );
}
$output .= Util::createElement(
Util::$CATEGORIES,
Util::createParams(
$category[Util::$LCparams],
[ Util::$LANGUAGE ],
$lang
),
$content
);
}
return $output;
}
/**
* Set calendar component property categories
*
* @param mixed $value
* @param array $params
* @param integer $index
* @return bool
*/
public function setCategories( $value, $params = null, $index = null ) {
if( empty( $value )) {
if( $this->getConfig( Util::$ALLOWEMPTY )) {
$value = Util::$SP0;
}
else {
return false;
}
}
Util::setMval( $this->categories, $value, $params, false, $index );
return true;
}
}

View File

@@ -0,0 +1,97 @@
<?php
/**
* iCalcreator, the PHP class package managing iCal (rfc2445/rfc5445) calendar information.
*
* copyright (c) 2007-2019 Kjell-Inge Gustafsson, kigkonsult, All rights reserved
* Link https://kigkonsult.se
* Package iCalcreator
* Version 2.26.8
* License Subject matter of licence is the software iCalcreator.
* The above copyright, link, package and version notices,
* this licence notice and the invariant [rfc5545] PRODID result use
* as implemented and invoked in iCalcreator shall be included in
* all copies or substantial portions of the iCalcreator.
*
* iCalcreator 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 3 of the License,
* or (at your option) any later version.
*
* iCalcreator 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 iCalcreator. If not, see <https://www.gnu.org/licenses/>.
*
* This file is a part of iCalcreator.
*/
namespace Kigkonsult\Icalcreator\Traits;
use Kigkonsult\Icalcreator\Util\Util;
/**
* CLASS property functions
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.22.23 - 2017-02-17
*/
trait CLASStrait
{
/**
* @var string component property CLASS value
* @access protected
*/
protected $class = null;
/**
* @var string
* @access private
* @static
*/
private static $KLASS = 'class';
/**
* Return formatted output for calendar component property class
*
* @return string
*/
public function createClass() {
if( empty( $this->{self::$KLASS} )) {
return null;
}
if( empty( $this->{self::$KLASS}[Util::$LCvalue] )) {
return ( $this->getConfig( Util::$ALLOWEMPTY )) ? Util::createElement( Util::$CLASS ) : null;
}
return Util::createElement(
Util::$CLASS,
Util::createParams( $this->{self::$KLASS}[Util::$LCparams] ),
$this->{self::$KLASS}[Util::$LCvalue]
);
}
/**
* Set calendar component property class
*
* @param string $value "PUBLIC" / "PRIVATE" / "CONFIDENTIAL" / iana-token / x-name
* @param array $params
* @return bool
*/
public function setClass( $value, $params = null ) {
if( empty( $value )) {
if( $this->getConfig( Util::$ALLOWEMPTY )) {
$value = Util::$SP0;
}
else {
return false;
}
}
$this->{self::$KLASS} = [
Util::$LCvalue => Util::trimTrailNL( $value ),
Util::$LCparams => Util::setParams( $params ),
];
return true;
}
}

View File

@@ -0,0 +1,96 @@
<?php
/**
* iCalcreator, the PHP class package managing iCal (rfc2445/rfc5445) calendar information.
*
* copyright (c) 2007-2019 Kjell-Inge Gustafsson, kigkonsult, All rights reserved
* Link https://kigkonsult.se
* Package iCalcreator
* Version 2.26.8
* License Subject matter of licence is the software iCalcreator.
* The above copyright, link, package and version notices,
* this licence notice and the invariant [rfc5545] PRODID result use
* as implemented and invoked in iCalcreator shall be included in
* all copies or substantial portions of the iCalcreator.
*
* iCalcreator 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 3 of the License,
* or (at your option) any later version.
*
* iCalcreator 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 iCalcreator. If not, see <https://www.gnu.org/licenses/>.
*
* This file is a part of iCalcreator.
*/
namespace Kigkonsult\Icalcreator\Traits;
use Kigkonsult\Icalcreator\Util\Util;
/**
* COMMENT property functions
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.22.23 - 2017-02-02
*/
trait COMMENTtrait
{
/**
* @var array component property COMMENT value
* @access protected
*/
protected $comment = null;
/**
* Return formatted output for calendar component property comment
*
* @return string
*/
public function createComment() {
if( empty( $this->comment )) {
return null;
}
$output = null;
$lang = $this->getConfig( Util::$LANGUAGE );
foreach( $this->comment as $cx => $commentPart ) {
if( empty( $commentPart[Util::$LCvalue] )) {
if( $this->getConfig( Util::$ALLOWEMPTY )) {
$output .= Util::createElement( Util::$COMMENT );
}
continue;
}
$output .= Util::createElement(
Util::$COMMENT,
Util::createParams( $commentPart[Util::$LCparams], Util::$ALTRPLANGARR, $lang ),
Util::strrep( $commentPart[Util::$LCvalue] )
);
}
return $output;
}
/**
* Set calendar component property comment
*
* @param string $value
* @param array $params
* @param integer $index
* @return bool
*/
public function setComment( $value, $params = null, $index = null ) {
if( empty( $value )) {
if( $this->getConfig( Util::$ALLOWEMPTY )) {
$value = Util::$SP0;
}
else {
return false;
}
}
Util::setMval( $this->comment, $value, $params, false, $index );
return true;
}
}

View File

@@ -0,0 +1,104 @@
<?php
/**
* iCalcreator, the PHP class package managing iCal (rfc2445/rfc5445) calendar information.
*
* copyright (c) 2007-2019 Kjell-Inge Gustafsson, kigkonsult, All rights reserved
* Link https://kigkonsult.se
* Package iCalcreator
* Version 2.26.8
* License Subject matter of licence is the software iCalcreator.
* The above copyright, link, package and version notices,
* this licence notice and the invariant [rfc5545] PRODID result use
* as implemented and invoked in iCalcreator shall be included in
* all copies or substantial portions of the iCalcreator.
*
* iCalcreator 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 3 of the License,
* or (at your option) any later version.
*
* iCalcreator 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 iCalcreator. If not, see <https://www.gnu.org/licenses/>.
*
* This file is a part of iCalcreator.
*/
namespace Kigkonsult\Icalcreator\Traits;
use Kigkonsult\Icalcreator\Util\Util;
/**
* COMPLETED property functions
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.22.23 - 2017-02-19
*/
trait COMPLETEDtrait
{
/**
* @var array component property COMPLETED value
* @access protected
*/
protected $completed = null;
/**
* Return formatted output for calendar component property completed
*
* @return string
*/
public function createCompleted() {
if( empty( $this->completed )) {
return null;
}
if( Util::hasNodate( $this->completed )) {
return ( $this->getConfig( Util::$ALLOWEMPTY )) ? Util::createElement( Util::$COMPLETED ) : null;
}
return Util::createElement(
Util::$COMPLETED,
Util::createParams( $this->completed[Util::$LCparams] ),
Util::date2strdate( $this->completed[Util::$LCvalue], 7 )
);
}
/**
* Set calendar component property completed
*
* @param mixed $year
* @param mixed $month
* @param int $day
* @param int $hour
* @param int $min
* @param int $sec
* @param array $params
* @return bool
*/
public function setCompleted(
$year,
$month = null,
$day = null,
$hour = null,
$min = null,
$sec = null,
$params = null
) {
if( empty( $year )) {
if( $this->getConfig( Util::$ALLOWEMPTY )) {
$this->completed = [
Util::$LCvalue => Util::$SP0,
Util::$LCparams => Util::setParams( $params ),
];
return true;
}
else {
return false;
}
}
$this->completed = Util::setDate2( $year, $month, $day, $hour, $min, $sec, $params );
return true;
}
}

View File

@@ -0,0 +1,95 @@
<?php
/**
* iCalcreator, the PHP class package managing iCal (rfc2445/rfc5445) calendar information.
*
* copyright (c) 2007-2019 Kjell-Inge Gustafsson, kigkonsult, All rights reserved
* Link https://kigkonsult.se
* Package iCalcreator
* Version 2.26.8
* License Subject matter of licence is the software iCalcreator.
* The above copyright, link, package and version notices,
* this licence notice and the invariant [rfc5545] PRODID result use
* as implemented and invoked in iCalcreator shall be included in
* all copies or substantial portions of the iCalcreator.
*
* iCalcreator 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 3 of the License,
* or (at your option) any later version.
*
* iCalcreator 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 iCalcreator. If not, see <https://www.gnu.org/licenses/>.
*
* This file is a part of iCalcreator.
*/
namespace Kigkonsult\Icalcreator\Traits;
use Kigkonsult\Icalcreator\Util\Util;
/**
* CONTACT property functions
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.22.23 - 2017-02-02
*/
trait CONTACTtrait
{
/**
* @var array component property CONTACT value
* @access protected
*/
protected $contact = null;
/**
* Return formatted output for calendar component property contact
*
* @return string
*/
public function createContact() {
if( empty( $this->contact )) {
return null;
}
$output = null;
$lang = $this->getConfig( Util::$LANGUAGE );
foreach( $this->contact as $cx => $contact ) {
if( ! empty( $contact[Util::$LCvalue] )) {
$output .= Util::createElement(
Util::$CONTACT,
Util::createParams( $contact[Util::$LCparams], Util::$ALTRPLANGARR, $lang ),
Util::strrep( $contact[Util::$LCvalue] )
);
}
elseif( $this->getConfig( Util::$ALLOWEMPTY )) {
$output .= Util::createElement( Util::$CONTACT );
}
}
return $output;
}
/**
* Set calendar component property contact
*
* @param string $value
* @param array $params
* @param integer $index
* @return bool
*/
public function setContact( $value, $params = null, $index = null ) {
if( empty( $value )) {
if( $this->getConfig( Util::$ALLOWEMPTY )) {
$value = Util::$SP0;
}
else {
return false;
}
}
Util::setMval( $this->contact, Util::trimTrailNL( $value ), $params,false, $index );
return true;
}
}

View File

@@ -0,0 +1,95 @@
<?php
/**
* iCalcreator, the PHP class package managing iCal (rfc2445/rfc5445) calendar information.
*
* copyright (c) 2007-2019 Kjell-Inge Gustafsson, kigkonsult, All rights reserved
* Link https://kigkonsult.se
* Package iCalcreator
* Version 2.26.8
* License Subject matter of licence is the software iCalcreator.
* The above copyright, link, package and version notices,
* this licence notice and the invariant [rfc5545] PRODID result use
* as implemented and invoked in iCalcreator shall be included in
* all copies or substantial portions of the iCalcreator.
*
* iCalcreator 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 3 of the License,
* or (at your option) any later version.
*
* iCalcreator 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 iCalcreator. If not, see <https://www.gnu.org/licenses/>.
*
* This file is a part of iCalcreator.
*/
namespace Kigkonsult\Icalcreator\Traits;
use Kigkonsult\Icalcreator\Util\Util;
use function gmdate;
/**
* CREATED property functions
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.22.23 - 2017-02-02
*/
trait CREATEDtrait
{
/**
* @var array component property CREATED value
* @access protected
*/
protected $created = null;
/**
* Return formatted output for calendar component property created
*
* @return string
*/
public function createCreated() {
if( empty( $this->created )) {
return null;
}
return Util::createElement(
Util::$CREATED,
Util::createParams( $this->created[Util::$LCparams] ),
Util::date2strdate( $this->created[Util::$LCvalue], 7 )
);
}
/**
* Set calendar component property created
*
* @param mixed $year
* @param mixed $month
* @param int $day
* @param int $hour
* @param int $min
* @param int $sec
* @param mixed $params
* @return bool
*/
public function setCreated(
$year = null,
$month = null,
$day = null,
$hour = null,
$min = null,
$sec = null,
$params = null
) {
static $YMDTHIS = 'Ymd\THis';
if( empty( $year )) {
$year = gmdate( $YMDTHIS );
}
$this->created = Util::setDate2( $year, $month, $day, $hour, $min, $sec, $params );
return true;
}
}

View File

@@ -0,0 +1,98 @@
<?php
/**
* iCalcreator, the PHP class package managing iCal (rfc2445/rfc5445) calendar information.
*
* copyright (c) 2007-2019 Kjell-Inge Gustafsson, kigkonsult, All rights reserved
* Link https://kigkonsult.se
* Package iCalcreator
* Version 2.26.8
* License Subject matter of licence is the software iCalcreator.
* The above copyright, link, package and version notices,
* this licence notice and the invariant [rfc5545] PRODID result use
* as implemented and invoked in iCalcreator shall be included in
* all copies or substantial portions of the iCalcreator.
*
* iCalcreator 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 3 of the License,
* or (at your option) any later version.
*
* iCalcreator 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 iCalcreator. If not, see <https://www.gnu.org/licenses/>.
*
* This file is a part of iCalcreator.
*/
namespace Kigkonsult\Icalcreator\Traits;
use Kigkonsult\Icalcreator\Util\Util;
/**
* DESCRIPTION property functions
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.22.23 - 2017-02-02
*/
trait DESCRIPTIONtrait
{
/**
* @var array component property DESCRIPTION value
* @access protected
*/
protected $description = null;
/**
* Return formatted output for calendar component property description
*
* @return string
*/
public function createDescription() {
if( empty( $this->description )) {
return null;
}
$output = null;
$lang = $this->getConfig( Util::$LANGUAGE );
foreach( $this->description as $dx => $description ) {
if( ! empty( $description[Util::$LCvalue] )) {
$output .= Util::createElement(
Util::$DESCRIPTION,
Util::createParams( $description[Util::$LCparams], Util::$ALTRPLANGARR, $lang ),
Util::strrep( $description[Util::$LCvalue] )
);
}
elseif( $this->getConfig( Util::$ALLOWEMPTY )) {
$output .= Util::createElement( Util::$DESCRIPTION );
}
}
return $output;
}
/**
* Set calendar component property description
*
* @param string $value
* @param array $params
* @param integer $index
* @return bool
*/
public function setDescription( $value, $params = null, $index = null ) {
if( empty( $value )) {
if( $this->getConfig( Util::$ALLOWEMPTY )) {
$value = Util::$SP0;
}
else {
return false;
}
}
if( self::VJOURNAL != $this->compType ) {
$index = 1;
}
Util::setMval( $this->description, $value, $params,false, $index );
return true;
}
}

View File

@@ -0,0 +1,112 @@
<?php
/**
* iCalcreator, the PHP class package managing iCal (rfc2445/rfc5445) calendar information.
*
* copyright (c) 2007-2019 Kjell-Inge Gustafsson, kigkonsult, All rights reserved
* Link https://kigkonsult.se
* Package iCalcreator
* Version 2.26.8
* License Subject matter of licence is the software iCalcreator.
* The above copyright, link, package and version notices,
* this licence notice and the invariant [rfc5545] PRODID result use
* as implemented and invoked in iCalcreator shall be included in
* all copies or substantial portions of the iCalcreator.
*
* iCalcreator 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 3 of the License,
* or (at your option) any later version.
*
* iCalcreator 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 iCalcreator. If not, see <https://www.gnu.org/licenses/>.
*
* This file is a part of iCalcreator.
*/
namespace Kigkonsult\Icalcreator\Traits;
use Kigkonsult\Icalcreator\Util\Util;
/**
* DTEND property functions
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.22.23 - 2017-02-02
*/
trait DTENDtrait
{
/**
* @var array component property DTEND value
* @access protected
*/
protected $dtend = null;
/**
* Return formatted output for calendar component property dtend
*
* @return string
*/
public function createDtend() {
if( empty( $this->dtend )) {
return null;
}
if( Util::hasNodate( $this->dtend )) {
return ( $this->getConfig( Util::$ALLOWEMPTY )) ? Util::createElement( Util::$DTEND ) : null;
}
$parno = Util::isParamsValueSet( $this->dtend, Util::$DATE ) ? 3 : null;
return Util::createElement(
Util::$DTEND,
Util::createParams( $this->dtend[Util::$LCparams] ),
Util::date2strdate( $this->dtend[Util::$LCvalue], $parno )
);
}
/**
* Set calendar component property dtend
*
* @param mixed $year
* @param mixed $month
* @param int $day
* @param int $hour
* @param int $min
* @param int $sec
* @param string $tz
* @param array $params
* @return bool
*/
public function setDtend(
$year,
$month = null,
$day = null,
$hour = null,
$min = null,
$sec = null,
$tz = null,
$params = null
) {
if( empty( $year )) {
if( $this->getConfig( Util::$ALLOWEMPTY )) {
$this->dtend = [
Util::$LCvalue => Util::$SP0,
Util::$LCparams => Util::setParams( $params ),
];
return true;
}
else {
return false;
}
}
if( false === ( $tzid = $this->getConfig( Util::$TZID ))) {
$tzid = null;
}
$this->dtend = Util::setDate( $year, $month, $day, $hour, $min, $sec, $tz,
$params, null, null, $tzid
);
return true;
}
}

View File

@@ -0,0 +1,91 @@
<?php
/**
* iCalcreator, the PHP class package managing iCal (rfc2445/rfc5445) calendar information.
*
* copyright (c) 2007-2019 Kjell-Inge Gustafsson, kigkonsult, All rights reserved
* Link https://kigkonsult.se
* Package iCalcreator
* Version 2.26.8
* License Subject matter of licence is the software iCalcreator.
* The above copyright, link, package and version notices,
* this licence notice and the invariant [rfc5545] PRODID result use
* as implemented and invoked in iCalcreator shall be included in
* all copies or substantial portions of the iCalcreator.
*
* iCalcreator 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 3 of the License,
* or (at your option) any later version.
*
* iCalcreator 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 iCalcreator. If not, see <https://www.gnu.org/licenses/>.
*
* This file is a part of iCalcreator.
*/
namespace Kigkonsult\Icalcreator\Traits;
use Kigkonsult\Icalcreator\Util\Util;
/**
* DTSTAMP property functions
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.22.23 - 2017-02-02
*/
trait DTSTAMPtrait
{
/**
* @var array component property DTSTAMP value
* @access protected
*/
protected $dtstamp = null;
/**
* Return formatted output for calendar component property dtstamp
*
* @return string
*/
public function createDtstamp() {
if( Util::hasNodate( $this->dtstamp )) {
$this->dtstamp = Util::makeDtstamp();
}
return Util::createElement(
Util::$DTSTAMP,
Util::createParams( $this->dtstamp[Util::$LCparams] ),
Util::date2strdate( $this->dtstamp[Util::$LCvalue], 7 )
);
}
/**
* Set calendar component property dtstamp
*
* @param mixed $year
* @param mixed $month
* @param int $day
* @param int $hour
* @param int $min
* @param int $sec
* @param array $params
* @return bool
*/
public function setDtstamp(
$year,
$month = null,
$day = null,
$hour = null,
$min = null,
$sec = null,
$params = null
) {
$this->dtstamp = ( empty( $year ))
? Util::makeDtstamp()
: Util::setDate2( $year, $month, $day, $hour, $min, $sec, $params );
return true;
}
}

View File

@@ -0,0 +1,116 @@
<?php
/**
* iCalcreator, the PHP class package managing iCal (rfc2445/rfc5445) calendar information.
*
* copyright (c) 2007-2019 Kjell-Inge Gustafsson, kigkonsult, All rights reserved
* Link https://kigkonsult.se
* Package iCalcreator
* Version 2.26.8
* License Subject matter of licence is the software iCalcreator.
* The above copyright, link, package and version notices,
* this licence notice and the invariant [rfc5545] PRODID result use
* as implemented and invoked in iCalcreator shall be included in
* all copies or substantial portions of the iCalcreator.
*
* iCalcreator 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 3 of the License,
* or (at your option) any later version.
*
* iCalcreator 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 iCalcreator. If not, see <https://www.gnu.org/licenses/>.
*
* This file is a part of iCalcreator.
*/
namespace Kigkonsult\Icalcreator\Traits;
use Kigkonsult\Icalcreator\Util\Util;
/**
* DTSTART property functions
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.22.23 - 2017-02-02
*/
trait DTSTARTtrait
{
/**
* @var array component property DTSTART value
* @access protected
*/
protected $dtstart = null;
/**
* Return formatted output for calendar component property dtstart
*
* @return string
*/
public function createDtstart() {
if( empty( $this->dtstart )) {
return null;
}
if( Util::hasNodate( $this->dtstart )) {
return ( $this->getConfig( Util::$ALLOWEMPTY )) ? Util::createElement( Util::$DTSTART ) : null;
}
if( Util::isCompInList( $this->compType, Util::$TZCOMPS )) {
unset( $this->dtstart[Util::$LCvalue][Util::$LCtz], $this->dtstart[Util::$LCparams][Util::$TZID] );
}
$parno = Util::isParamsValueSet( $this->dtstart, Util::$DATE ) ? 3 : null;
return Util::createElement(
Util::$DTSTART,
Util::createParams( $this->dtstart[Util::$LCparams] ),
Util::date2strdate( $this->dtstart[Util::$LCvalue], $parno )
);
}
/**
* Set calendar component property dtstart
*
* @param mixed $year
* @param mixed $month
* @param int $day
* @param int $hour
* @param int $min
* @param int $sec
* @param string $tz
* @param array $params
* @return bool
*/
public function setDtstart(
$year,
$month = null,
$day = null,
$hour = null,
$min = null,
$sec = null,
$tz = null,
$params = null
) {
if( empty( $year )) {
if( $this->getConfig( Util::$ALLOWEMPTY )) {
$this->dtstart = [
Util::$LCvalue => Util::$SP0,
Util::$LCparams => Util::setParams( $params ),
];
return true;
}
else {
return false;
}
}
if( false === ( $tzid = $this->getConfig( Util::$TZID ))) {
$tzid = null;
}
$this->dtstart = Util::setDate(
$year, $month, $day, $hour, $min, $sec, $tz,
$params, Util::$DTSTART, $this->compType, $tzid
);
return true;
}
}

View File

@@ -0,0 +1,113 @@
<?php
/**
* iCalcreator, the PHP class package managing iCal (rfc2445/rfc5445) calendar information.
*
* copyright (c) 2007-2019 Kjell-Inge Gustafsson, kigkonsult, All rights reserved
* Link https://kigkonsult.se
* Package iCalcreator
* Version 2.26.8
* License Subject matter of licence is the software iCalcreator.
* The above copyright, link, package and version notices,
* this licence notice and the invariant [rfc5545] PRODID result use
* as implemented and invoked in iCalcreator shall be included in
* all copies or substantial portions of the iCalcreator.
*
* iCalcreator 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 3 of the License,
* or (at your option) any later version.
*
* iCalcreator 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 iCalcreator. If not, see <https://www.gnu.org/licenses/>.
*
* This file is a part of iCalcreator.
*/
namespace Kigkonsult\Icalcreator\Traits;
use Kigkonsult\Icalcreator\Util\Util;
/**
* DUE property functions
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.22.23 - 2017-02-02
*/
trait DUEtrait
{
/**
* @var array component property DUE value
* @access protected
*/
protected $due = null;
/**
* Return formatted output for calendar component property due
*
* @return string
*/
public function createDue() {
if( empty( $this->due )) {
return null;
}
if( Util::hasNodate( $this->due )) {
return ( $this->getConfig( Util::$ALLOWEMPTY )) ? Util::createElement( Util::$DUE ) : null;
}
$parno = Util::isParamsValueSet( $this->due, Util::$DATE ) ? 3 : null;
return Util::createElement(
Util::$DUE,
Util::createParams( $this->due[Util::$LCparams] ),
Util::date2strdate( $this->due[Util::$LCvalue], $parno )
);
}
/**
* Set calendar component property due
*
* @param mixed $year
* @param mixed $month
* @param int $day
* @param int $hour
* @param int $min
* @param int $sec
* @param string $tz
* @param array $params
* @return bool
*/
public function setDue(
$year,
$month = null,
$day = null,
$hour = null,
$min = null,
$sec = null,
$tz = null,
$params = null
) {
if( empty( $year )) {
if( $this->getConfig( Util::$ALLOWEMPTY )) {
$this->due = [
Util::$LCvalue => Util::$SP0,
Util::$LCparams => Util::setParams( $params ),
];
return true;
}
else {
return false;
}
}
if( false === ( $tzid = $this->getConfig( Util::$TZID ))) {
$tzid = null;
}
$this->due = Util::setDate(
$year, $month, $day, $hour, $min, $sec, $tz,
$params, null, null, $tzid
);
return true;
}
}

View File

@@ -0,0 +1,184 @@
<?php
/**
* iCalcreator, the PHP class package managing iCal (rfc2445/rfc5445) calendar information.
*
* copyright (c) 2007-2019 Kjell-Inge Gustafsson, kigkonsult, All rights reserved
* Link https://kigkonsult.se
* Package iCalcreator
* Version 2.26.8
* License Subject matter of licence is the software iCalcreator.
* The above copyright, link, package and version notices,
* this licence notice and the invariant [rfc5545] PRODID result use
* as implemented and invoked in iCalcreator shall be included in
* all copies or substantial portions of the iCalcreator.
*
* iCalcreator 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 3 of the License,
* or (at your option) any later version.
*
* iCalcreator 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 iCalcreator. If not, see <https://www.gnu.org/licenses/>.
*
* This file is a part of iCalcreator.
*/
namespace Kigkonsult\Icalcreator\Traits;
use Kigkonsult\Icalcreator\Util\Util;
use Kigkonsult\Icalcreator\Util\UtilDuration;
use DateInterval;
use Exception;
use function count;
use function in_array;
use function is_array;
use function is_string;
use function strlen;
use function substr;
/**
* DURATION property functions
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.26.8 - 2018-12-12
*/
trait DURATIONtrait
{
/**
* @var array component property DURATION value
* @access protected
*/
protected $duration = null;
/**
* Return formatted output for calendar component property duration
*
* @return string
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.26.7 - 2018-11-28
*/
public function createDuration() {
if( ! isset( $this->duration[Util::$LCvalue] )) {
return null;
}
if( isset( $this->duration[Util::$LCvalue]['invert'] )) { // fix pre 7.0.5 bug
$dateInterval = UtilDuration::DateIntervalArr2DateInterval( $this->duration[Util::$LCvalue] );
return Util::createElement(
Util::$DURATION,
Util::createParams( $this->duration[Util::$LCparams] ),
UtilDuration::dateInterval2String( $dateInterval )
);
}
else {
if( $this->getConfig( Util::$ALLOWEMPTY )) {
return Util::createElement( Util::$DURATION );
}
else {
return null;
}
}
}
/**
* Set calendar component property duration
*
* @param mixed $week
* @param mixed $day
* @param int $hour
* @param int $min
* @param int $sec
* @param array $params
* @return bool
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.26.7 - 2018-12-02
*/
public function setDuration(
$week,
$day = null,
$hour = null,
$min = null,
$sec = null,
$params = null
) {
if( empty( $week ) && empty( $day ) && empty( $hour ) && empty( $min ) && empty( $sec )) {
if( $this->getConfig( Util::$ALLOWEMPTY )) {
$week = $day = null;
}
else {
return false;
}
}
if( $week instanceof DateInterval ) {
$this->duration = [
Util::$LCvalue => (array) $week, // fix pre 7.0.5 bug
Util::$LCparams => Util::setParams( $day ),
];
}
elseif( is_array( $week ) && ( 1 <= count( $week ))) {
try {
$dateInterval = new DateInterval(
UtilDuration::duration2str(
UtilDuration::duration2arr( $week )
)
);
$week = UtilDuration::conformDateInterval( $dateInterval );
}
catch( Exception $e ) {
return false;
}
$this->duration = [
Util::$LCvalue => (array) $week, // fix pre 7.0.5 bug
Util::$LCparams => Util::setParams( $day ),
];
}
elseif( is_string( $week ) && ( 3 <= strlen( trim( $week )))) {
$week = Util::trimTrailNL( trim( $week ));
if( in_array( $week[0], Util::$PLUSMINUSARR )) { // can only be positive
$week = substr( $week, 1 );
}
try {
$dateInterval = new DateInterval( $week );
$week = UtilDuration::conformDateInterval( $dateInterval );
}
catch( Exception $e ) {
return false;
}
$this->duration = [
Util::$LCvalue => (array) $week, // fix pre 7.0.5 bug
Util::$LCparams => Util::setParams( $day ),
];
}
else {
try {
$dateInterval = new DateInterval(
UtilDuration::duration2str(
UtilDuration::duration2arr(
[
Util::$LCWEEK => (int) $week,
Util::$LCDAY => (int) $day,
Util::$LCHOUR => (int) $hour,
Util::$LCMIN => (int) $min,
Util::$LCSEC => (int) $sec,
]
)
)
);
$week = UtilDuration::conformDateInterval( $dateInterval );
}
catch( Exception $e ) {
return false;
}
$this->duration = [
Util::$LCvalue => (array) $week, // fix pre 7.0.5 bug
Util::$LCparams => Util::setParams( $params ),
];
}
return true;
}
}

View File

@@ -0,0 +1,84 @@
<?php
/**
* iCalcreator, the PHP class package managing iCal (rfc2445/rfc5445) calendar information.
*
* copyright (c) 2007-2019 Kjell-Inge Gustafsson, kigkonsult, All rights reserved
* Link https://kigkonsult.se
* Package iCalcreator
* Version 2.26.8
* License Subject matter of licence is the software iCalcreator.
* The above copyright, link, package and version notices,
* this licence notice and the invariant [rfc5545] PRODID result use
* as implemented and invoked in iCalcreator shall be included in
* all copies or substantial portions of the iCalcreator.
*
* iCalcreator 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 3 of the License,
* or (at your option) any later version.
*
* iCalcreator 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 iCalcreator. If not, see <https://www.gnu.org/licenses/>.
*
* This file is a part of iCalcreator.
*/
namespace Kigkonsult\Icalcreator\Traits;
use Kigkonsult\Icalcreator\Util\Util;
use Kigkonsult\Icalcreator\Util\UtilRexdate;
/**
* EXDATE property functions
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.22.23 - 2017-02-05
*/
trait EXDATEtrait
{
/**
* @var array component property EXDATE value
* @access protected
*/
protected $exdate = null;
/**
* Return formatted output for calendar component property exdate
*
* @return string
*/
public function createExdate() {
if( empty( $this->exdate )) {
return null;
}
return UtilRexdate::formatExdate( $this->exdate, $this->getConfig( Util::$ALLOWEMPTY ));
}
/**
* Set calendar component property exdate
*
* @param array $exdates
* @param array $params
* @param integer $index
* @return bool
*/
public function setExdate( $exdates, $params = null, $index = null ) {
if( empty( $exdates )) {
if( $this->getConfig( Util::$ALLOWEMPTY )) {
Util::setMval( $this->exdate, Util::$SP0, $params, false, $index );
return true;
}
else {
return false;
}
}
$input = UtilRexdate::prepInputExdate( $exdates, $params );
Util::setMval( $this->exdate, $input[Util::$LCvalue], $input[Util::$LCparams],false, $index );
return true;
}
}

View File

@@ -0,0 +1,85 @@
<?php
/**
* iCalcreator, the PHP class package managing iCal (rfc2445/rfc5445) calendar information.
*
* copyright (c) 2007-2019 Kjell-Inge Gustafsson, kigkonsult, All rights reserved
* Link https://kigkonsult.se
* Package iCalcreator
* Version 2.26.8
* License Subject matter of licence is the software iCalcreator.
* The above copyright, link, package and version notices,
* this licence notice and the invariant [rfc5545] PRODID result use
* as implemented and invoked in iCalcreator shall be included in
* all copies or substantial portions of the iCalcreator.
*
* iCalcreator 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 3 of the License,
* or (at your option) any later version.
*
* iCalcreator 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 iCalcreator. If not, see <https://www.gnu.org/licenses/>.
*
* This file is a part of iCalcreator.
*/
namespace Kigkonsult\Icalcreator\Traits;
use Kigkonsult\Icalcreator\Util\Util;
use Kigkonsult\Icalcreator\Util\UtilRecur;
/**
* EXRULE property functions
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.22.23 - 2017-04-03
*/
trait EXRULEtrait
{
/**
* @var array component property EXRULE value
* @access protected
*/
protected $exrule = null;
/**
* Return formatted output for calendar component property exrule
*
* @return string
*/
public function createExrule() {
return UtilRecur::formatRecur( Util::$EXRULE, $this->exrule, $this->getConfig( Util::$ALLOWEMPTY ));
}
/**
* Set calendar component property exdate
*
* @param array $exruleset
* @param array $params
* @param integer $index
* @return bool
*/
public function setExrule( $exruleset, $params = null, $index = null ) {
if( empty( $exruleset )) {
if( $this->getConfig( Util::$ALLOWEMPTY )) {
$exruleset = Util::$SP0;
}
else {
return false;
}
}
Util::setMval(
$this->exrule,
UtilRecur::setRexrule( $exruleset ),
$params,
false,
$index
);
return true;
}
}

View File

@@ -0,0 +1,235 @@
<?php
/**
* iCalcreator, the PHP class package managing iCal (rfc2445/rfc5445) calendar information.
*
* copyright (c) 2007-2019 Kjell-Inge Gustafsson, kigkonsult, All rights reserved
* Link https://kigkonsult.se
* Package iCalcreator
* Version 2.26.8
* License Subject matter of licence is the software iCalcreator.
* The above copyright, link, package and version notices,
* this licence notice and the invariant [rfc5545] PRODID result use
* as implemented and invoked in iCalcreator shall be included in
* all copies or substantial portions of the iCalcreator.
*
* iCalcreator 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 3 of the License,
* or (at your option) any later version.
*
* iCalcreator 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 iCalcreator. If not, see <https://www.gnu.org/licenses/>.
*
* This file is a part of iCalcreator.
*/
namespace Kigkonsult\Icalcreator\Traits;
use Kigkonsult\Icalcreator\Util\Util;
use Kigkonsult\Icalcreator\Util\UtilDuration;
use DateTime;
use DateTimeZone;
use DateInterval;
use Exception;
use function count;
use function in_array;
use function is_array;
use function is_string;
use function sprintf;
use function strlen;
use function usort;
/**
* FREEBUSY property functions
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.26.8 - 2018-12-12
*/
trait FREEBUSYtrait
{
/**
* @var array component property FREEBUSY value
* @access protected
*/
protected $freebusy = null;
/**
* @var string FREEBUSY param keywords
* @access protected
* @static
*/
protected static $LCFBTYPE = 'fbtype';
protected static $UCFBTYPE = 'FBTYPE';
protected static $FREEBUSYKEYS = [ 'FREE', 'BUSY', 'BUSY-UNAVAILABLE', 'BUSY-TENTATIVE' ];
protected static $FREE = 'FREE';
protected static $BUSY = 'BUSY';
/*
protected static $BUSY_UNAVAILABLE = 'BUSY-UNAVAILABLE';
protected static $BUSY_TENTATIVE = 'BUSY-TENTATIVE';
*/
/**
* Return formatted output for calendar component property freebusy
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.26.7 - 2018-12-02
* @return string
*/
public function createFreebusy() {
static $FMT = ';FBTYPE=%s';
static $SORTER = [ 'Kigkonsult\Icalcreator\Util\VcalendarSortHandler', 'sortRdate1' ];
if( empty( $this->freebusy )) {
return null;
}
$output = null;
foreach( $this->freebusy as $fx => $freebusyPart ) {
if( empty( $freebusyPart[Util::$LCvalue] ) ||
(( 1 == count( $freebusyPart[Util::$LCvalue] )) &&
isset( $freebusyPart[Util::$LCvalue][self::$LCFBTYPE] ))) {
if( $this->getConfig( Util::$ALLOWEMPTY )) {
$output .= Util::createElement( Util::$FREEBUSY );
}
continue;
}
$attributes = $content = null;
if( isset( $freebusyPart[Util::$LCvalue][self::$LCFBTYPE] )) {
$attributes .= sprintf( $FMT, $freebusyPart[Util::$LCvalue][self::$LCFBTYPE] );
unset( $freebusyPart[Util::$LCvalue][self::$LCFBTYPE] );
$freebusyPart[Util::$LCvalue] = array_values( $freebusyPart[Util::$LCvalue] );
}
else {
$attributes .= sprintf( $FMT, self::$BUSY );
}
$attributes .= Util::createParams( $freebusyPart[Util::$LCparams] );
$fno = 1;
$cnt = count( $freebusyPart[Util::$LCvalue] );
if( 1 < $cnt ) {
usort( $freebusyPart[Util::$LCvalue], $SORTER );
}
foreach( $freebusyPart[Util::$LCvalue] as $periodix => $freebusyPeriod ) {
$content .= Util::date2strdate( $freebusyPeriod[0] );
$content .= Util::$L;
if( isset( $freebusyPeriod[1]['invert'] )) { // fix pre 7.0.5 bug
$dateInterval = UtilDuration::DateIntervalArr2DateInterval( $freebusyPeriod[1] );
// period= -> duration
$content .= UtilDuration::dateInterval2String( $dateInterval );
}
else { // period= -> date-time
$content .= Util::date2strdate( $freebusyPeriod[1] );
}
if( $fno < $cnt ) {
$content .= Util::$COMMA;
}
$fno++;
} // end foreach
$output .= Util::createElement( Util::$FREEBUSY, $attributes, $content );
} // end foreach( $this->freebusy as $fx => $freebusyPart )
return $output;
}
/**
* Set calendar component property freebusy
*
* @param string $fbType
* @param array $fbValues
* @param array $params
* @param integer $index
* @return bool
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.26.27 - 2018-12-02
*/
public function setFreebusy( $fbType, $fbValues, $params = null, $index = null ) {
if( empty( $fbValues )) {
if( $this->getConfig( Util::$ALLOWEMPTY )) {
Util::setMval(
$this->freebusy,
Util::$SP0,
$params,
false,
$index
);
return true;
}
else {
return false;
}
}
$fbType = strtoupper( $fbType );
if( ! in_array( $fbType, self::$FREEBUSYKEYS ) && ! Util::isXprefixed( $fbType )) {
$fbType = self::$BUSY;
}
$input = [ self::$LCFBTYPE => $fbType ];
foreach( $fbValues as $fbPeriod ) { // periods => period
if( empty( $fbPeriod )) {
continue;
}
$freebusyPeriod = [];
foreach( $fbPeriod as $fbMember ) { // pairs => singlepart
$freebusyPairMember = [];
switch( true ) {
case ( $fbMember instanceof DateTime ) : // datetime
$fbMember->setTimezone((new DateTimeZone( Util::$UTC )));
$date = Util::dateTime2Str( $fbMember );
Util::strDate2arr( $date );
$freebusyPairMember = $date;
$freebusyPairMember[Util::$LCtz] = Util::$Z;
break;
case ( $fbMember instanceof DateInterval ) : // interval
$freebusyPairMember = (array) $fbMember; // fix pre 7.0.5 bug
break;
case ( is_array( $fbMember )) :
if( Util::isArrayDate( $fbMember )) { // date-time value
$freebusyPairMember = Util::chkDateArr( $fbMember, 7 );
$freebusyPairMember[Util::$LCtz] = Util::$Z;
}
elseif( Util::isArrayTimestampDate( $fbMember )) { // timestamp value
$freebusyPairMember = Util::timestamp2date( $fbMember[Util::$LCTIMESTAMP], 7 );
$freebusyPairMember[Util::$LCtz] = Util::$Z;
}
else { // array format duration
try { // fix pre 7.0.5 bug
$freebusyPairMember = (array) UtilDuration::conformDateInterval(
new DateInterval(
UtilDuration::duration2str(
UtilDuration::duration2arr( $fbMember )
)
)
);
}
catch( Exception $e ) {
return false;
}
}
break;
case ( ! is_string( $fbMember )) :
continue;
break;
case (( 3 <= strlen( trim( $fbMember ))) && ( in_array( $fbMember{0}, UtilDuration::$PREFIXARR ))) :
// string format duration
if( in_array( $fbMember{0}, Util::$PLUSMINUSARR )) { // can only be positive
$fbMember = substr( $fbMember, 1 );
}
try { // fix pre 7.0.5 bug
$freebusyPairMember = (array) UtilDuration::conformDateInterval( new DateInterval( $fbMember ));
}
catch( Exception $e ) {
return false;
}
break;
case ( 8 <= strlen( trim( $fbMember ))) : // text date ex. 2006-08-03 10:12:18
$freebusyPairMember = Util::strDate2ArrayDate( $fbMember, 7 );
unset( $freebusyPairMember[Util::$UNPARSEDTEXT] );
$freebusyPairMember[Util::$LCtz] = Util::$Z;
} // end switch
$freebusyPeriod[] = $freebusyPairMember;
}
$input[] = $freebusyPeriod;
}
Util::setMval( $this->freebusy, $input, $params, false, $index );
return true;
}
}

View File

@@ -0,0 +1,102 @@
<?php
/**
* iCalcreator, the PHP class package managing iCal (rfc2445/rfc5445) calendar information.
*
* copyright (c) 2007-2019 Kjell-Inge Gustafsson, kigkonsult, All rights reserved
* Link https://kigkonsult.se
* Package iCalcreator
* Version 2.26.8
* License Subject matter of licence is the software iCalcreator.
* The above copyright, link, package and version notices,
* this licence notice and the invariant [rfc5545] PRODID result use
* as implemented and invoked in iCalcreator shall be included in
* all copies or substantial portions of the iCalcreator.
*
* iCalcreator 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 3 of the License,
* or (at your option) any later version.
*
* iCalcreator 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 iCalcreator. If not, see <https://www.gnu.org/licenses/>.
*
* This file is a part of iCalcreator.
*/
namespace Kigkonsult\Icalcreator\Traits;
use Kigkonsult\Icalcreator\Util\Util;
use Kigkonsult\Icalcreator\Util\UtilGeo;
use function floatval;
use function is_array;
/**
* GEO property functions
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.22.23 - 2017-02-02
*/
trait GEOtrait
{
/**
* @var array component property GEO value
* @access protected
*/
protected $geo = null;
/**
* Return formatted output for calendar component property geo
*
* @return string
*/
public function createGeo() {
if( empty( $this->geo )) {
return null;
}
if( empty( $this->geo[Util::$LCvalue] )) {
return ( $this->getConfig( Util::$ALLOWEMPTY )) ? Util::createElement( Util::$GEO ) : null;
}
return Util::createElement(
Util::$GEO,
Util::createParams(
$this->geo[Util::$LCparams] ),
UtilGeo::geo2str2( $this->geo[Util::$LCvalue][UtilGeo::$LATITUDE], UtilGeo::$geoLatFmt ) .
Util::$SEMIC .
UtilGeo::geo2str2( $this->geo[Util::$LCvalue][UtilGeo::$LONGITUDE], UtilGeo::$geoLongFmt ));
}
/**
* Set calendar component property geo
*
* @param mixed $latitude
* @param mixed $longitude
* @param array $params
* @return bool
*/
public function setGeo( $latitude, $longitude, $params = null ) {
if( isset( $latitude ) && isset( $longitude )) {
if( ! is_array( $this->geo )) {
$this->geo = [];
}
$this->geo[Util::$LCvalue][UtilGeo::$LATITUDE] = floatval( $latitude );
$this->geo[Util::$LCvalue][UtilGeo::$LONGITUDE] = floatval( $longitude );
$this->geo[Util::$LCparams] = Util::setParams( $params );
}
elseif( $this->getConfig( Util::$ALLOWEMPTY )) {
$this->geo = [
Util::$LCvalue => Util::$SP0,
Util::$LCparams => Util::setParams( $params ),
];
}
else {
return false;
}
return true;
}
}

View File

@@ -0,0 +1,95 @@
<?php
/**
* iCalcreator, the PHP class package managing iCal (rfc2445/rfc5445) calendar information.
*
* copyright (c) 2007-2019 Kjell-Inge Gustafsson, kigkonsult, All rights reserved
* Link https://kigkonsult.se
* Package iCalcreator
* Version 2.26.8
* License Subject matter of licence is the software iCalcreator.
* The above copyright, link, package and version notices,
* this licence notice and the invariant [rfc5545] PRODID result use
* as implemented and invoked in iCalcreator shall be included in
* all copies or substantial portions of the iCalcreator.
*
* iCalcreator 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 3 of the License,
* or (at your option) any later version.
*
* iCalcreator 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 iCalcreator. If not, see <https://www.gnu.org/licenses/>.
*
* This file is a part of iCalcreator.
*/
namespace Kigkonsult\Icalcreator\Traits;
use Kigkonsult\Icalcreator\Util\Util;
use function gmdate;
/**
* LAST-MODIFIED property functions
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.22.23 - 2017-02-02
*/
trait LAST_MODIFIEDtrait
{
/**
* @var array component property LAST-MODIFIED value
* @access protected
*/
protected $lastmodified = null;
/**
* Return formatted output for calendar component property last-modified
*
* @return string
*/
public function createLastModified() {
if( empty( $this->lastmodified )) {
return null;
}
return Util::createElement(
Util::$LAST_MODIFIED,
Util::createParams( $this->lastmodified[Util::$LCparams] ),
Util::date2strdate( $this->lastmodified[Util::$LCvalue], 7 )
);
}
/**
* Set calendar component property completed
*
* @param mixed $year
* @param mixed $month
* @param int $day
* @param int $hour
* @param int $min
* @param int $sec
* @param array $params
* @return bool
*/
public function setLastModified(
$year = null,
$month = null,
$day = null,
$hour = null,
$min = null,
$sec = null,
$params = null
) {
static $TMDTHIS = 'Ymd\THis';
if( empty( $year )) {
$year = gmdate( $TMDTHIS );
}
$this->lastmodified = Util::setDate2( $year, $month, $day, $hour, $min, $sec, $params );
return true;
}
}

View File

@@ -0,0 +1,94 @@
<?php
/**
* iCalcreator, the PHP class package managing iCal (rfc2445/rfc5445) calendar information.
*
* copyright (c) 2007-2019 Kjell-Inge Gustafsson, kigkonsult, All rights reserved
* Link https://kigkonsult.se
* Package iCalcreator
* Version 2.26.8
* License Subject matter of licence is the software iCalcreator.
* The above copyright, link, package and version notices,
* this licence notice and the invariant [rfc5545] PRODID result use
* as implemented and invoked in iCalcreator shall be included in
* all copies or substantial portions of the iCalcreator.
*
* iCalcreator 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 3 of the License,
* or (at your option) any later version.
*
* iCalcreator 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 iCalcreator. If not, see <https://www.gnu.org/licenses/>.
*
* This file is a part of iCalcreator.
*/
namespace Kigkonsult\Icalcreator\Traits;
use Kigkonsult\Icalcreator\Util\Util;
/**
* LOCATION property functions
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.22.23 - 2017-02-17
*/
trait LOCATIONtrait
{
/**
* @var array component property LOCATION value
* @access protected
*/
protected $location = null;
/**
* Return formatted output for calendar component property location
*
* @return string
*/
public function createLocation() {
if( empty( $this->location )) {
return null;
}
if( empty( $this->location[Util::$LCvalue] )) {
return ( $this->getConfig( Util::$ALLOWEMPTY )) ? Util::createElement( Util::$LOCATION ) : null;
}
return Util::createElement(
Util::$LOCATION,
Util::createParams(
$this->location[Util::$LCparams],
Util::$ALTRPLANGARR,
$this->getConfig( Util::$LANGUAGE )
),
Util::strrep( $this->location[Util::$LCvalue] )
);
}
/**
* Set calendar component property location
*
* @param string $value
* @param array $params
* @return bool
*/
public function setLocation( $value, $params = null ) {
if( empty( $value )) {
if( $this->getConfig( Util::$ALLOWEMPTY )) {
$value = Util::$SP0;
}
else {
return false;
}
}
$this->location = [
Util::$LCvalue => Util::trimTrailNL( $value ),
Util::$LCparams => Util::setParams( $params ),
];
return true;
}
}

View File

@@ -0,0 +1,75 @@
<?php
/**
* iCalcreator, the PHP class package managing iCal (rfc2445/rfc5445) calendar information.
*
* copyright (c) 2007-2019 Kjell-Inge Gustafsson, kigkonsult, All rights reserved
* Link https://kigkonsult.se
* Package iCalcreator
* Version 2.26.8
* License Subject matter of licence is the software iCalcreator.
* The above copyright, link, package and version notices,
* this licence notice and the invariant [rfc5545] PRODID result use
* as implemented and invoked in iCalcreator shall be included in
* all copies or substantial portions of the iCalcreator.
*
* iCalcreator 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 3 of the License,
* or (at your option) any later version.
*
* iCalcreator 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 iCalcreator. If not, see <https://www.gnu.org/licenses/>.
*
* This file is a part of iCalcreator.
*/
namespace Kigkonsult\Icalcreator\Traits;
use Kigkonsult\Icalcreator\Util\Util;
use function sprintf;
/**
* METHOD property functions
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.22.23 - 2017-02-02
*/
trait METHODtrait
{
/**
* @var string calendar property METHOD
* @access protected
*/
protected $method = null;
/**
* Return formatted output for calendar property method
*
* @return string
*/
public function createMethod() {
return ( empty( $this->method ))
? null
: sprintf( self::$FMTICAL, Util::$METHOD, $this->method );
}
/**
* Set calendar property method
*
* @param string $value
* @return bool
*/
public function setMethod( $value ) {
if( empty( $value )) {
return false;
}
$this->method = $value;
return true;
}
}

View File

@@ -0,0 +1,108 @@
<?php
/**
* iCalcreator, the PHP class package managing iCal (rfc2445/rfc5445) calendar information.
*
* copyright (c) 2007-2019 Kjell-Inge Gustafsson, kigkonsult, All rights reserved
* Link https://kigkonsult.se
* Package iCalcreator
* Version 2.26.8
* License Subject matter of licence is the software iCalcreator.
* The above copyright, link, package and version notices,
* this licence notice and the invariant [rfc5545] PRODID result use
* as implemented and invoked in iCalcreator shall be included in
* all copies or substantial portions of the iCalcreator.
*
* iCalcreator 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 3 of the License,
* or (at your option) any later version.
*
* iCalcreator 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 iCalcreator. If not, see <https://www.gnu.org/licenses/>.
*
* This file is a part of iCalcreator.
*/
namespace Kigkonsult\Icalcreator\Traits;
use Kigkonsult\Icalcreator\Util\Util;
use Kigkonsult\Icalcreator\Util\UtilAttendee;
/**
* ORGANIZER property functions
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.22.23 - 2017-04-03
*/
trait ORGANIZERtrait
{
/**
* @var array component property ORGANIZER value
* @access protected
*/
protected $organizer = null;
/**
* Return formatted output for calendar component property organizer
*
* @return string
*/
public function createOrganizer() {
if( empty( $this->organizer )) {
return null;
}
if( empty( $this->organizer[Util::$LCvalue] )) {
return ( $this->getConfig( Util::$ALLOWEMPTY )) ? Util::createElement( Util::$ORGANIZER ) : null;
}
return Util::createElement(
Util::$ORGANIZER,
Util::createParams(
$this->organizer[Util::$LCparams],
[
Util::$CN,
Util::$DIR,
Util::$SENT_BY,
Util::$LANGUAGE,
],
$this->getConfig( Util::$LANGUAGE )
),
$this->organizer[Util::$LCvalue]
);
}
/**
* Set calendar component property organizer
*
* @param string $value
* @param array $params
* @return bool
*/
public function setOrganizer( $value, $params = null ) {
if( empty( $value )) {
if( $this->getConfig( Util::$ALLOWEMPTY )) {
$value = Util::$SP0;
}
else {
return false;
}
}
$value = UtilAttendee::calAddressCheck( $value, false );
$this->organizer = [
Util::$LCvalue => $value,
Util::$LCparams => Util::setParams( $params ),
];
if( isset( $this->organizer[Util::$LCparams][Util::$SENT_BY] )) {
$this->organizer[Util::$LCparams][Util::$SENT_BY] =
UtilAttendee::calAddressCheck(
$this->organizer[Util::$LCparams][Util::$SENT_BY],
false
);
}
return true;
}
}

View File

@@ -0,0 +1,95 @@
<?php
/**
* iCalcreator, the PHP class package managing iCal (rfc2445/rfc5445) calendar information.
*
* copyright (c) 2007-2019 Kjell-Inge Gustafsson, kigkonsult, All rights reserved
* Link https://kigkonsult.se
* Package iCalcreator
* Version 2.26.8
* License Subject matter of licence is the software iCalcreator.
* The above copyright, link, package and version notices,
* this licence notice and the invariant [rfc5545] PRODID result use
* as implemented and invoked in iCalcreator shall be included in
* all copies or substantial portions of the iCalcreator.
*
* iCalcreator 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 3 of the License,
* or (at your option) any later version.
*
* iCalcreator 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 iCalcreator. If not, see <https://www.gnu.org/licenses/>.
*
* This file is a part of iCalcreator.
*/
namespace Kigkonsult\Icalcreator\Traits;
use Kigkonsult\Icalcreator\Util\Util;
use function is_numeric;
/**
* PERCENT-COMPLETE property functions
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.22.23 - 2017-02-05
*/
trait PERCENT_COMPLETEtrait
{
/**
* @var array component property PERCENT_COMPLETE value
* @access protected
*/
protected $percentcomplete = null;
/**
* Return formatted output for calendar component property percent-complete
*
* @return string
*/
public function createPercentComplete() {
if( ! isset( $this->percentcomplete ) ||
( empty( $this->percentcomplete ) && ! is_numeric( $this->percentcomplete ))) {
return null;
}
if( ! isset( $this->percentcomplete[Util::$LCvalue] ) ||
( empty( $this->percentcomplete[Util::$LCvalue] ) &&
! is_numeric( $this->percentcomplete[Util::$LCvalue] ))) {
return ( $this->getConfig( Util::$ALLOWEMPTY )) ? Util::createElement( Util::$PERCENT_COMPLETE ) : null;
}
return Util::createElement(
Util::$PERCENT_COMPLETE,
Util::createParams( $this->percentcomplete[Util::$LCparams] ),
$this->percentcomplete[Util::$LCvalue]
);
}
/**
* Set calendar component property percent-complete
*
* @param int $value
* @param array $params
* @return bool
*/
public function setPercentComplete( $value, $params = null ) {
if( empty( $value ) && ! is_numeric( $value )) {
if( $this->getConfig( Util::$ALLOWEMPTY )) {
$value = Util::$SP0;
}
else {
return false;
}
}
$this->percentcomplete = [
Util::$LCvalue => $value,
Util::$LCparams => Util::setParams( $params ),
];
return true;
}
}

View File

@@ -0,0 +1,94 @@
<?php
/**
* iCalcreator, the PHP class package managing iCal (rfc2445/rfc5445) calendar information.
*
* copyright (c) 2007-2019 Kjell-Inge Gustafsson, kigkonsult, All rights reserved
* Link https://kigkonsult.se
* Package iCalcreator
* Version 2.26.8
* License Subject matter of licence is the software iCalcreator.
* The above copyright, link, package and version notices,
* this licence notice and the invariant [rfc5545] PRODID result use
* as implemented and invoked in iCalcreator shall be included in
* all copies or substantial portions of the iCalcreator.
*
* iCalcreator 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 3 of the License,
* or (at your option) any later version.
*
* iCalcreator 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 iCalcreator. If not, see <https://www.gnu.org/licenses/>.
*
* This file is a part of iCalcreator.
*/
namespace Kigkonsult\Icalcreator\Traits;
use Kigkonsult\Icalcreator\Util\Util;
use function is_numeric;
/**
* PRIORITY property functions
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.22.23 - 2017-02-02
*/
trait PRIORITYtrait
{
/**
* @var array component property PRIORITY value
* @access protected
*/
protected $priority = null;
/**
* Return formatted output for calendar component property priority
*
* @return string
*/
public function createPriority() {
if( ! isset( $this->priority ) ||
( empty( $this->priority ) && ! is_numeric( $this->priority ))) {
return null;
}
if( ! isset( $this->priority[Util::$LCvalue] ) ||
( empty( $this->priority[Util::$LCvalue] ) && ! is_numeric( $this->priority[Util::$LCvalue] ))) {
return ( $this->getConfig( Util::$ALLOWEMPTY )) ? Util::createElement( Util::$PRIORITY ) : null;
}
return Util::createElement(
Util::$PRIORITY,
Util::createParams( $this->priority[Util::$LCparams] ),
$this->priority[Util::$LCvalue]
);
}
/**
* Set calendar component property priority
*
* @param int $value
* @param array $params
* @return bool
*/
public function setPriority( $value, $params = null ) {
if( empty( $value ) && ! is_numeric( $value )) {
if( $this->getConfig( Util::$ALLOWEMPTY )) {
$value = Util::$SP0;
}
else {
return false;
}
}
$this->priority = [
Util::$LCvalue => $value,
Util::$LCparams => Util::setParams( $params ),
];
return true;
}
}

View File

@@ -0,0 +1,93 @@
<?php
/**
* iCalcreator, the PHP class package managing iCal (rfc2445/rfc5445) calendar information.
*
* copyright (c) 2007-2019 Kjell-Inge Gustafsson, kigkonsult, All rights reserved
* Link https://kigkonsult.se
* Package iCalcreator
* Version 2.26.8
* License Subject matter of licence is the software iCalcreator.
* The above copyright, link, package and version notices,
* this licence notice and the invariant [rfc5545] PRODID result use
* as implemented and invoked in iCalcreator shall be included in
* all copies or substantial portions of the iCalcreator.
*
* iCalcreator 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 3 of the License,
* or (at your option) any later version.
*
* iCalcreator 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 iCalcreator. If not, see <https://www.gnu.org/licenses/>.
*
* This file is a part of iCalcreator.
*/
namespace Kigkonsult\Icalcreator\Traits;
use Kigkonsult\Icalcreator\Util\Util;
use function sprintf;
use function strtoupper;
/**
* PRODID property functions
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.22.23 - 2017-03-15
*/
trait PRODIDtrait
{
/**
* @var string calendar property PRODID
* @access protected
*/
protected $prodid = null;
/**
* Return formatted output for calendar property prodid
*
* @return string
*/
public function createProdid() {
if( ! isset( $this->prodid )) {
$this->makeProdid();
}
return Util::createElement( Util::$PRODID, null, $this->prodid );
}
/**
* Create default value for calendar prodid,
* Do NOT alter or remove this method or the invoke of this method,
* a licence violation.
*
* [rfc5545]
* "Conformance: The property MUST be specified once in an iCalendar object.
* Description: The vendor of the implementation SHOULD assure that this
* is a globally unique identifier; using some technique such as an FPI
* value, as defined in [ISO 9070]."
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.26.2 - 2018-11-29
*/
public function makeProdid() {
static $FMT = '-//%s//NONSGML kigkonsult.se %s//%s';
if( false !== ( $lang = $this->getConfig( Util::$LANGUAGE ))) {
$lang = strtoupper( $lang );
}
else {
$lang = Util::$SP0;
}
$this->prodid = sprintf(
$FMT,
$this->getConfig( Util::$UNIQUE_ID ),
ICALCREATOR_VERSION,
$lang
);
}
}

View File

@@ -0,0 +1,84 @@
<?php
/**
* iCalcreator, the PHP class package managing iCal (rfc2445/rfc5445) calendar information.
*
* copyright (c) 2007-2019 Kjell-Inge Gustafsson, kigkonsult, All rights reserved
* Link https://kigkonsult.se
* Package iCalcreator
* Version 2.26.8
* License Subject matter of licence is the software iCalcreator.
* The above copyright, link, package and version notices,
* this licence notice and the invariant [rfc5545] PRODID result use
* as implemented and invoked in iCalcreator shall be included in
* all copies or substantial portions of the iCalcreator.
*
* iCalcreator 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 3 of the License,
* or (at your option) any later version.
*
* iCalcreator 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 iCalcreator. If not, see <https://www.gnu.org/licenses/>.
*
* This file is a part of iCalcreator.
*/
namespace Kigkonsult\Icalcreator\Traits;
use Kigkonsult\Icalcreator\Util\Util;
use Kigkonsult\Icalcreator\Util\UtilRexdate;
/**
* RDATE property functions
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.22.23 - 2017-02-26
*/
trait RDATEtrait
{
/**
* @var array component property RDATE value
* @access protected
*/
protected $rdate = null;
/**
* Return formatted output for calendar component property rdate
*
* @return string
*/
public function createRdate() {
if( empty( $this->rdate )) {
return null;
}
return UtilRexdate::formatRdate( $this->rdate, $this->getConfig( Util::$ALLOWEMPTY ), $this->compType );
}
/**
* Set calendar component property rdate
*
* @param array $rdates
* @param array $params
* @param integer $index
* @return bool
*/
public function setRdate( $rdates, $params = null, $index = null ) {
if( empty( $rdates )) {
if( $this->getConfig( Util::$ALLOWEMPTY )) {
Util::setMval( $this->rdate, Util::$SP0, $params, false, $index );
return true;
}
else {
return false;
}
}
$input = UtilRexdate::prepInputRdate( $rdates, $params, $this->compType );
Util::setMval( $this->rdate, $input[Util::$LCvalue], $input[Util::$LCparams], false, $index );
return true;
}
}

View File

@@ -0,0 +1,111 @@
<?php
/**
* iCalcreator, the PHP class package managing iCal (rfc2445/rfc5445) calendar information.
*
* copyright (c) 2007-2019 Kjell-Inge Gustafsson, kigkonsult, All rights reserved
* Link https://kigkonsult.se
* Package iCalcreator
* Version 2.26.8
* License Subject matter of licence is the software iCalcreator.
* The above copyright, link, package and version notices,
* this licence notice and the invariant [rfc5545] PRODID result use
* as implemented and invoked in iCalcreator shall be included in
* all copies or substantial portions of the iCalcreator.
*
* iCalcreator 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 3 of the License,
* or (at your option) any later version.
*
* iCalcreator 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 iCalcreator. If not, see <https://www.gnu.org/licenses/>.
*
* This file is a part of iCalcreator.
*/
namespace Kigkonsult\Icalcreator\Traits;
use Kigkonsult\Icalcreator\Util\Util;
/**
* RECURRENCE-ID property functions
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.22.23 - 2017-02-05
*/
trait RECURRENCE_IDtrait
{
/**
* @var array component property RECURRENCE_ID value
* @access protected
*/
protected $recurrenceid = null;
/**
* Return formatted output for calendar component property recurrence-id
*
* @return string
*/
public function createRecurrenceid() {
if( empty( $this->recurrenceid )) {
return null;
}
if( empty( $this->recurrenceid[Util::$LCvalue] )) {
return ( $this->getConfig( Util::$ALLOWEMPTY )) ? Util::createElement( Util::$RECURRENCE_ID ) : null;
}
return Util::createElement(
Util::$RECURRENCE_ID,
Util::createParams( $this->recurrenceid[Util::$LCparams] ),
Util::date2strdate(
$this->recurrenceid[Util::$LCvalue],
Util::isParamsValueSet( $this->recurrenceid, Util::$DATE ) ? 3 : null )
);
}
/**
* Set calendar component property recurrence-id
*
* @param mixed $year
* @param mixed $month
* @param int $day
* @param int $hour
* @param int $min
* @param int $sec
* @param string $tz
* @param array $params
* @return bool
*/
public function setRecurrenceid(
$year,
$month = null,
$day = null,
$hour = null,
$min = null,
$sec = null,
$tz = null,
$params = null
) {
if( empty( $year )) {
if( $this->getConfig( Util::$ALLOWEMPTY )) {
$this->recurrenceid = [
Util::$LCvalue => Util::$SP0,
Util::$LCparams => null,
];
return true;
}
else {
return false;
}
}
$this->recurrenceid = Util::setDate(
$year, $month, $day, $hour, $min, $sec, $tz,
$params,null, null, $this->getConfig( Util::$TZID )
);
return true;
}
}

View File

@@ -0,0 +1,99 @@
<?php
/**
* iCalcreator, the PHP class package managing iCal (rfc2445/rfc5445) calendar information.
*
* copyright (c) 2007-2019 Kjell-Inge Gustafsson, kigkonsult, All rights reserved
* Link https://kigkonsult.se
* Package iCalcreator
* Version 2.26.8
* License Subject matter of licence is the software iCalcreator.
* The above copyright, link, package and version notices,
* this licence notice and the invariant [rfc5545] PRODID result use
* as implemented and invoked in iCalcreator shall be included in
* all copies or substantial portions of the iCalcreator.
*
* iCalcreator 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 3 of the License,
* or (at your option) any later version.
*
* iCalcreator 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 iCalcreator. If not, see <https://www.gnu.org/licenses/>.
*
* This file is a part of iCalcreator.
*/
namespace Kigkonsult\Icalcreator\Traits;
use Kigkonsult\Icalcreator\Util\Util;
/**
* RELATED-TO property functions
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.22.23 - 2017-02-17
*/
trait RELATED_TOtrait
{
/**
* @var array component property RELATED_TO value
* @access protected
*/
protected $relatedto = null;
/**
* Return formatted output for calendar component property related-to
*
* @return string
*/
public function createRelatedTo() {
if( empty( $this->relatedto )) {
return null;
}
$output = null;
foreach( $this->relatedto as $rx => $relation ) {
if( ! empty( $relation[Util::$LCvalue] )) {
$output .= Util::createElement(
Util::$RELATED_TO,
Util::createParams( $relation[Util::$LCparams] ),
Util::strrep( $relation[Util::$LCvalue] )
);
}
elseif( $this->getConfig( Util::$ALLOWEMPTY )) {
$output .= Util::createElement( Util::$RELATED_TO );
}
}
return $output;
}
/**
* Set calendar component property related-to
*
* @param string $value
* @param array $params
* @param int $index
* @return bool
*/
public function setRelatedTo( $value, $params = [], $index = null ) {
static $RELTYPE = 'RELTYPE';
static $PARENT = 'PARENT';
if( empty( $value )) {
if( $this->getConfig( Util::$ALLOWEMPTY )) {
$value = Util::$SP0;
}
else {
return false;
}
}
if( ! empty( $params )) {
Util::existRem( $params, $RELTYPE, $PARENT, true ); // remove default
}
Util::setMval( $this->relatedto, Util::trimTrailNL( $value ), $params, false, $index );
return true;
}
}

View File

@@ -0,0 +1,94 @@
<?php
/**
* iCalcreator, the PHP class package managing iCal (rfc2445/rfc5445) calendar information.
*
* copyright (c) 2007-2019 Kjell-Inge Gustafsson, kigkonsult, All rights reserved
* Link https://kigkonsult.se
* Package iCalcreator
* Version 2.26.8
* License Subject matter of licence is the software iCalcreator.
* The above copyright, link, package and version notices,
* this licence notice and the invariant [rfc5545] PRODID result use
* as implemented and invoked in iCalcreator shall be included in
* all copies or substantial portions of the iCalcreator.
*
* iCalcreator 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 3 of the License,
* or (at your option) any later version.
*
* iCalcreator 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 iCalcreator. If not, see <https://www.gnu.org/licenses/>.
*
* This file is a part of iCalcreator.
*/
namespace Kigkonsult\Icalcreator\Traits;
use Kigkonsult\Icalcreator\Util\Util;
use function is_numeric;
/**
* REPEAT property functions
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.22.23 - 2017-02-05
*/
trait REPEATtrait
{
/**
* @var array component property REPEAT value
* @access protected
*/
protected $repeat = null;
/**
* Return formatted output for calendar component property repeat
*
* @return string
*/
public function createRepeat() {
if( ! isset( $this->repeat ) ||
( empty( $this->repeat ) && ! is_numeric( $this->repeat ))) {
return null;
}
if( ! isset( $this->repeat[Util::$LCvalue] ) ||
( empty( $this->repeat[Util::$LCvalue] ) && ! is_numeric( $this->repeat[Util::$LCvalue] ))) {
return ( $this->getConfig( Util::$ALLOWEMPTY )) ? Util::createElement( Util::$REPEAT ) : null;
}
return Util::createElement(
Util::$REPEAT,
Util::createParams( $this->repeat[Util::$LCparams] ),
$this->repeat[Util::$LCvalue]
);
}
/**
* Set calendar component property repeat
*
* @param string $value
* @param array $params
* @return bool
*/
public function setRepeat( $value, $params = null ) {
if( empty( $value ) && ! is_numeric( $value )) {
if( $this->getConfig( Util::$ALLOWEMPTY )) {
$value = Util::$SP0;
}
else {
return false;
}
}
$this->repeat = [
Util::$LCvalue => $value,
Util::$LCparams => Util::setParams( $params ),
];
return true;
}
}

View File

@@ -0,0 +1,125 @@
<?php
/**
* iCalcreator, the PHP class package managing iCal (rfc2445/rfc5445) calendar information.
*
* copyright (c) 2007-2019 Kjell-Inge Gustafsson, kigkonsult, All rights reserved
* Link https://kigkonsult.se
* Package iCalcreator
* Version 2.26.8
* License Subject matter of licence is the software iCalcreator.
* The above copyright, link, package and version notices,
* this licence notice and the invariant [rfc5545] PRODID result use
* as implemented and invoked in iCalcreator shall be included in
* all copies or substantial portions of the iCalcreator.
*
* iCalcreator 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 3 of the License,
* or (at your option) any later version.
*
* iCalcreator 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 iCalcreator. If not, see <https://www.gnu.org/licenses/>.
*
* This file is a part of iCalcreator.
*/
namespace Kigkonsult\Icalcreator\Traits;
use Kigkonsult\Icalcreator\Util\Util;
use function number_format;
/**
* REQUEST-STATUS property functions
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.22.23 - 2017-02-19
*/
trait REQUEST_STATUStrait
{
/**
* @var array component property REQUEST-STATUS value
* @access protected
*/
protected $requeststatus = null;
/**
* @var string Request-status properties
* @access private
* @static
*/
private static $STATCODE = 'statcode';
private static $TEXT = 'text';
private static $EXTDATA = 'extdata';
/**
* Return formatted output for calendar component property request-status
*
* @return string
*/
public function createRequestStatus() {
if( empty( $this->requeststatus )) {
return null;
}
$output = null;
$lang = $this->getConfig( Util::$LANGUAGE );
foreach( $this->requeststatus as $rx => $rStat ) {
if( empty( $rStat[Util::$LCvalue][self::$STATCODE] )) {
if( $this->getConfig( Util::$ALLOWEMPTY )) {
$output .= Util::createElement( Util::$REQUEST_STATUS );
}
continue;
}
$content = number_format(
(float) $rStat[Util::$LCvalue][self::$STATCODE],
2,
Util::$DOT,
null
);
$content .= Util::$SEMIC . Util::strrep( $rStat[Util::$LCvalue][self::$TEXT] );
if( isset( $rStat[Util::$LCvalue][self::$EXTDATA] )) {
$content .= Util::$SEMIC . Util::strrep( $rStat[Util::$LCvalue][self::$EXTDATA] );
}
$output .= Util::createElement(
Util::$REQUEST_STATUS,
Util::createParams( $rStat[Util::$LCparams], [ Util::$LANGUAGE ], $lang ),
$content
);
}
return $output;
}
/**
* Set calendar component property request-status
*
* @param float $statcode
* @param string $text
* @param string $extdata
* @param array $params
* @param integer $index
* @return bool
*/
public function setRequestStatus( $statcode, $text, $extdata = null, $params = null, $index = null ) {
if( empty( $statcode ) || empty( $text )) {
if( $this->getConfig( Util::$ALLOWEMPTY )) {
$statcode = $text = Util::$SP0;
}
else {
return false;
}
}
$input = [
self::$STATCODE => $statcode,
self::$TEXT => Util::trimTrailNL( $text ),
];
if( $extdata ) {
$input[self::$EXTDATA] = Util::trimTrailNL( $extdata );
}
Util::setMval( $this->requeststatus, $input, $params, false, $index );
return true;
}
}

View File

@@ -0,0 +1,116 @@
<?php
/**
* iCalcreator, the PHP class package managing iCal (rfc2445/rfc5445) calendar information.
*
* copyright (c) 2007-2019 Kjell-Inge Gustafsson, kigkonsult, All rights reserved
* Link https://kigkonsult.se
* Package iCalcreator
* Version 2.26.8
* License Subject matter of licence is the software iCalcreator.
* The above copyright, link, package and version notices,
* this licence notice and the invariant [rfc5545] PRODID result use
* as implemented and invoked in iCalcreator shall be included in
* all copies or substantial portions of the iCalcreator.
*
* iCalcreator 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 3 of the License,
* or (at your option) any later version.
*
* iCalcreator 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 iCalcreator. If not, see <https://www.gnu.org/licenses/>.
*
* This file is a part of iCalcreator.
*/
namespace Kigkonsult\Icalcreator\Traits;
use Kigkonsult\Icalcreator\Util\Util;
use function implode;
use function is_array;
/**
* RESOURCES property functions
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.22.23 - 2017-02-17
*/
trait RESOURCEStrait
{
/**
* @var array component property RESOURCES value
* @access protected
*/
protected $resources = null;
/**
* Return formatted output for calendar component property resources
*
* @return string
*/
public function createResources() {
if( empty( $this->resources )) {
return null;
}
$output = null;
$lang = $this->getConfig( Util::$LANGUAGE );
foreach( $this->resources as $rx => $resource ) {
if( empty( $resource[Util::$LCvalue] )) {
if( $this->getConfig( Util::$ALLOWEMPTY )) {
$output .= Util::createElement( Util::$RESOURCES );
}
continue;
}
if( is_array( $resource[Util::$LCvalue] )) {
foreach( $resource[Util::$LCvalue] as $rix => $rValue ) {
$resource[Util::$LCvalue][$rix] = Util::strrep( $rValue );
}
$content = implode( Util::$COMMA, $resource[Util::$LCvalue] );
}
else {
$content = Util::strrep( $resource[Util::$LCvalue] );
}
$output .= Util::createElement(
Util::$RESOURCES,
Util::createParams( $resource[Util::$LCparams], Util::$ALTRPLANGARR, $lang ),
$content
);
}
return $output;
}
/**
* Set calendar component property recources
*
* @param mixed $value
* @param array $params
* @param integer $index
* @return bool
*/
public function setResources( $value, $params = null, $index = null ) {
if( empty( $value )) {
if( $this->getConfig( Util::$ALLOWEMPTY )) {
$value = Util::$SP0;
}
else {
return false;
}
}
if( is_array( $value )) {
foreach( $value as & $valuePart ) {
$valuePart = Util::trimTrailNL( $valuePart );
}
}
else {
$value = Util::trimTrailNL( $value );
}
Util::setMval( $this->resources, $value, $params, false, $index );
return true;
}
}

View File

@@ -0,0 +1,79 @@
<?php
/**
* iCalcreator, the PHP class package managing iCal (rfc2445/rfc5445) calendar information.
*
* copyright (c) 2007-2019 Kjell-Inge Gustafsson, kigkonsult, All rights reserved
* Link https://kigkonsult.se
* Package iCalcreator
* Version 2.26.8
* License Subject matter of licence is the software iCalcreator.
* The above copyright, link, package and version notices,
* this licence notice and the invariant [rfc5545] PRODID result use
* as implemented and invoked in iCalcreator shall be included in
* all copies or substantial portions of the iCalcreator.
*
* iCalcreator 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 3 of the License,
* or (at your option) any later version.
*
* iCalcreator 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 iCalcreator. If not, see <https://www.gnu.org/licenses/>.
*
* This file is a part of iCalcreator.
*/
namespace Kigkonsult\Icalcreator\Traits;
use Kigkonsult\Icalcreator\Util\Util;
use Kigkonsult\Icalcreator\Util\UtilRecur;
/**
* RRULE property functions
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.22.23 - 2017-04-03
*/
trait RRULEtrait
{
/**
* @var array component property RRULE value
* @access protected
*/
protected $rrule = null;
/**
* Return formatted output for calendar component property rrule
*
* @return string
*/
public function createRrule() {
return UtilRecur::formatRecur( Util::$RRULE, $this->rrule, $this->getConfig( Util::$ALLOWEMPTY ));
}
/**
* Set calendar component property rrule
*
* @param array $rruleset
* @param array $params
* @param integer $index
* @return bool
*/
public function setRrule( $rruleset, $params = null, $index = null ) {
if( empty( $rruleset )) {
if( $this->getConfig( Util::$ALLOWEMPTY )) {
$rruleset = Util::$SP0;
}
else {
return false;
}
}
Util::setMval( $this->rrule, UtilRecur::setRexrule( $rruleset ), $params,false, $index );
return true;
}
}

View File

@@ -0,0 +1,93 @@
<?php
/**
* iCalcreator, the PHP class package managing iCal (rfc2445/rfc5445) calendar information.
*
* copyright (c) 2007-2019 Kjell-Inge Gustafsson, kigkonsult, All rights reserved
* Link https://kigkonsult.se
* Package iCalcreator
* Version 2.26.8
* License Subject matter of licence is the software iCalcreator.
* The above copyright, link, package and version notices,
* this licence notice and the invariant [rfc5545] PRODID result use
* as implemented and invoked in iCalcreator shall be included in
* all copies or substantial portions of the iCalcreator.
*
* iCalcreator 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 3 of the License,
* or (at your option) any later version.
*
* iCalcreator 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 iCalcreator. If not, see <https://www.gnu.org/licenses/>.
*
* This file is a part of iCalcreator.
*/
namespace Kigkonsult\Icalcreator\Traits;
use Kigkonsult\Icalcreator\Util\Util;
use function is_numeric;
/**
* SEQUENCE property functions
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.22.23 - 2017-02-24
*/
trait SEQUENCEtrait
{
/**
* @var array component property SEQUENCE value
* @access protected
*/
protected $sequence = null;
/**
* Return formatted output for calendar component property sequence
*
* @return string
*/
public function createSequence() {
if( ! isset( $this->sequence ) ||
( empty( $this->sequence ) && ! is_numeric( $this->sequence ))) {
return null;
}
if(( ! isset( $this->sequence[Util::$LCvalue] ) ||
( empty( $this->sequence[Util::$LCvalue] ) && ! is_numeric( $this->sequence[Util::$LCvalue] ))) &&
( Util::$ZERO != $this->sequence[Util::$LCvalue] )) {
return ( $this->getConfig( Util::$ALLOWEMPTY )) ? Util::createElement( Util::$SEQUENCE ) : null;
}
return Util::createElement(
Util::$SEQUENCE,
Util::createParams( $this->sequence[Util::$LCparams] ),
$this->sequence[Util::$LCvalue]
);
}
/**
* Set calendar component property sequence
*
* @param int $value
* @param array $params
* @return bool
*/
public function setSequence( $value = null, $params = null ) {
if(( empty( $value ) && ! is_numeric( $value )) && ( Util::$ZERO != $value )) {
$value = ( isset( $this->sequence[Util::$LCvalue] ) &&
( -1 < $this->sequence[Util::$LCvalue] ))
? $this->sequence[Util::$LCvalue] + 1
: Util::$ZERO;
}
$this->sequence = [
Util::$LCvalue => $value,
Util::$LCparams => Util::setParams( $params ),
];
return true;
}
}

View File

@@ -0,0 +1,90 @@
<?php
/**
* iCalcreator, the PHP class package managing iCal (rfc2445/rfc5445) calendar information.
*
* copyright (c) 2007-2019 Kjell-Inge Gustafsson, kigkonsult, All rights reserved
* Link https://kigkonsult.se
* Package iCalcreator
* Version 2.26.8
* License Subject matter of licence is the software iCalcreator.
* The above copyright, link, package and version notices,
* this licence notice and the invariant [rfc5545] PRODID result use
* as implemented and invoked in iCalcreator shall be included in
* all copies or substantial portions of the iCalcreator.
*
* iCalcreator 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 3 of the License,
* or (at your option) any later version.
*
* iCalcreator 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 iCalcreator. If not, see <https://www.gnu.org/licenses/>.
*
* This file is a part of iCalcreator.
*/
namespace Kigkonsult\Icalcreator\Traits;
use Kigkonsult\Icalcreator\Util\Util;
/**
* STATUS property functions
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.22.23 - 2017-02-02
*/
trait STATUStrait
{
/**
* @var array component property STATUS value
* @access protected
*/
protected $status = null;
/**
* Return formatted output for calendar component property status
*
* @return string
*/
public function createStatus() {
if( empty( $this->status )) {
return null;
}
if( empty( $this->status[Util::$LCvalue] )) {
return ( $this->getConfig( Util::$ALLOWEMPTY )) ? Util::createElement( Util::$STATUS ) : null;
}
return Util::createElement(
Util::$STATUS,
Util::createParams( $this->status[Util::$LCparams] ),
$this->status[Util::$LCvalue]
);
}
/**
* Set calendar component property status
*
* @param string $value
* @param array $params
* @return bool
*/
public function setStatus( $value, $params = null ) {
if( empty( $value )) {
if( $this->getConfig( Util::$ALLOWEMPTY )) {
$value = Util::$SP0;
}
else {
return false;
}
}
$this->status = [
Util::$LCvalue => Util::trimTrailNL( $value ),
Util::$LCparams => Util::setParams( $params ),
];
return true;
}
}

View File

@@ -0,0 +1,94 @@
<?php
/**
* iCalcreator, the PHP class package managing iCal (rfc2445/rfc5445) calendar information.
*
* copyright (c) 2007-2019 Kjell-Inge Gustafsson, kigkonsult, All rights reserved
* Link https://kigkonsult.se
* Package iCalcreator
* Version 2.26.8
* License Subject matter of licence is the software iCalcreator.
* The above copyright, link, package and version notices,
* this licence notice and the invariant [rfc5545] PRODID result use
* as implemented and invoked in iCalcreator shall be included in
* all copies or substantial portions of the iCalcreator.
*
* iCalcreator 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 3 of the License,
* or (at your option) any later version.
*
* iCalcreator 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 iCalcreator. If not, see <https://www.gnu.org/licenses/>.
*
* This file is a part of iCalcreator.
*/
namespace Kigkonsult\Icalcreator\Traits;
use Kigkonsult\Icalcreator\Util\Util;
/**
* SUMMARY property functions
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.22.23 - 2017-02-02
*/
trait SUMMARYtrait
{
/**
* @var array component property SUMMARY value
* @access protected
*/
protected $summary = null;
/**
* Return formatted output for calendar component property summary
*
* @return string
*/
public function createSummary() {
if( empty( $this->summary )) {
return null;
}
if( empty( $this->summary[Util::$LCvalue] )) {
return ( $this->getConfig( Util::$ALLOWEMPTY )) ? Util::createElement( Util::$SUMMARY ) : null;
}
return Util::createElement(
Util::$SUMMARY,
Util::createParams(
$this->summary[Util::$LCparams],
Util::$ALTRPLANGARR,
$this->getConfig( Util::$LANGUAGE )
),
Util::strrep( $this->summary[Util::$LCvalue] )
);
}
/**
* Set calendar component property summary
*
* @param string $value
* @param array $params
* @return bool
*/
public function setSummary( $value, $params = null ) {
if( empty( $value )) {
if( $this->getConfig( Util::$ALLOWEMPTY )) {
$value = Util::$SP0;
}
else {
return false;
}
}
$this->summary = [
Util::$LCvalue => $value,
Util::$LCparams => Util::setParams( $params ),
];
return true;
}
}

View File

@@ -0,0 +1,90 @@
<?php
/**
* iCalcreator, the PHP class package managing iCal (rfc2445/rfc5445) calendar information.
*
* copyright (c) 2007-2019 Kjell-Inge Gustafsson, kigkonsult, All rights reserved
* Link https://kigkonsult.se
* Package iCalcreator
* Version 2.26.8
* License Subject matter of licence is the software iCalcreator.
* The above copyright, link, package and version notices,
* this licence notice and the invariant [rfc5545] PRODID result use
* as implemented and invoked in iCalcreator shall be included in
* all copies or substantial portions of the iCalcreator.
*
* iCalcreator 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 3 of the License,
* or (at your option) any later version.
*
* iCalcreator 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 iCalcreator. If not, see <https://www.gnu.org/licenses/>.
*
* This file is a part of iCalcreator.
*/
namespace Kigkonsult\Icalcreator\Traits;
use Kigkonsult\Icalcreator\Util\Util;
/**
* TRANSP property functions
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.22.23 - 2017-02-17
*/
trait TRANSPtrait
{
/**
* @var array component property TRANSP value
* @access protected
*/
protected $transp = null;
/**
* Return formatted output for calendar component property transp
*
* @return string
*/
public function createTransp() {
if( empty( $this->transp )) {
return null;
}
if( empty( $this->transp[Util::$LCvalue] )) {
return ( $this->getConfig( Util::$ALLOWEMPTY )) ? Util::createElement( Util::$TRANSP ) : null;
}
return Util::createElement(
Util::$TRANSP,
Util::createParams( $this->transp[Util::$LCparams] ),
$this->transp[Util::$LCvalue]
);
}
/**
* Set calendar component property transp
*
* @param string $value
* @param array $params
* @return bool
*/
public function setTransp( $value, $params = null ) {
if( empty( $value )) {
if( $this->getConfig( Util::$ALLOWEMPTY )) {
$value = Util::$SP0;
}
else {
return false;
}
}
$this->transp = [
Util::$LCvalue => Util::trimTrailNL( $value ),
Util::$LCparams => Util::setParams( $params ),
];
return true;
}
}

View File

@@ -0,0 +1,427 @@
<?php
/**
* iCalcreator, the PHP class package managing iCal (rfc2445/rfc5445) calendar information.
*
* copyright (c) 2007-2019 Kjell-Inge Gustafsson, kigkonsult, All rights reserved
* Link https://kigkonsult.se
* Package iCalcreator
* Version 2.26.8
* License Subject matter of licence is the software iCalcreator.
* The above copyright, link, package and version notices,
* this licence notice and the invariant [rfc5545] PRODID result use
* as implemented and invoked in iCalcreator shall be included in
* all copies or substantial portions of the iCalcreator.
*
* iCalcreator 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 3 of the License,
* or (at your option) any later version.
*
* iCalcreator 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 iCalcreator. If not, see <https://www.gnu.org/licenses/>.
*
* This file is a part of iCalcreator.
*/
namespace Kigkonsult\Icalcreator\Traits;
use Kigkonsult\Icalcreator\Util\Util;
use Kigkonsult\Icalcreator\Util\UtilDuration;
use DateTime;
use DateTimeZone;
use DateInterval;
use Exception;
use function array_key_exists;
use function checkdate;
use function in_array;
use function is_array;
use function is_null;
use function is_string;
use function strcasecmp;
use function substr;
/**
* TRIGGER property functions
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.26.8 - 2018-12-12
*/
trait TRIGGERtrait
{
/**
* @var array component property TRIGGER value
* @access protected
*/
protected $trigger = null;
/**
* Return formatted output for calendar component property trigger
*
* @return string
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.26.7 - 2018-12-02
*/
public function createTrigger() {
static $RELATED_END = 'RELATED=END';
if( empty( $this->trigger )) {
return null;
}
if( empty( $this->trigger[Util::$LCvalue] )) {
return ( $this->getConfig( Util::$ALLOWEMPTY )) ? Util::createElement( Util::$TRIGGER ) : null;
}
if( isset( $this->trigger[Util::$LCvalue]['invert'] )) { // fix pre 7.0.5 bug
$dateInterval = UtilDuration::DateIntervalArr2DateInterval( $this->trigger[Util::$LCvalue] );
return Util::createElement(
Util::$TRIGGER,
Util::createParams( $this->trigger[Util::$LCparams] ),
UtilDuration::dateInterval2String( $dateInterval, true )
);
}
$content = $attributes = null;
if( isset( $this->trigger[Util::$LCvalue][Util::$LCYEAR] ) &&
isset( $this->trigger[Util::$LCvalue][Util::$LCMONTH] ) &&
isset( $this->trigger[Util::$LCvalue][Util::$LCDAY] )) {
$content .= Util::date2strdate( $this->trigger[Util::$LCvalue] );
}
else {
if( true !== $this->trigger[Util::$LCvalue][UtilDuration::$RELATEDSTART] ) {
$attributes .= Util::$SEMIC . $RELATED_END;
}
if( $this->trigger[Util::$LCvalue][UtilDuration::$BEFORE] ) {
$content .= Util::$MINUS;
}
$content .= UtilDuration::duration2str( $this->trigger[Util::$LCvalue] );
}
$attributes .= Util::createParams( $this->trigger[Util::$LCparams] );
return Util::createElement( Util::$TRIGGER, $attributes, $content );
}
/**
* Set calendar component property trigger
*
* @param mixed $year
* @param mixed $month
* @param int $day
* @param int $week
* @param int $hour
* @param int $min
* @param int $sec
* @param bool $relatedStart
* @param bool $before
* @param array $params
* @return bool
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.26.7 - 2018-12-01
*/
public function setTrigger(
$year = null,
$month = null,
$day = null,
$week = null,
$hour = null,
$min = null,
$sec = null,
$relatedStart = null,
$before = null,
$params = null
) {
if( empty( $year ) &&
( empty( $month ) || is_array( $month )) &&
empty( $day ) && empty( $week ) && empty( $hour ) && empty( $min ) && empty( $sec )) {
if( $this->getConfig( Util::$ALLOWEMPTY )) {
$this->trigger = [
Util::$LCvalue => Util::$SP0,
Util::$LCparams => Util::setParams( $month ),
];
return true;
}
else {
return false;
}
}
if( is_null( $relatedStart )) {
$relatedStart = true;
}
if( is_null( $before )) {
$before = true;
}
$isArrayDate = $isArrayDuration = $isStringDate = $isStringDuration = false;
if( is_array( $year ) && ( is_array( $month ) || empty( $month ))) {
$params = Util::setParams( $month );
if( array_key_exists( Util::$LCYEAR, $year ) && // identify date(-time)
array_key_exists( Util::$LCMONTH, $year ) &&
array_key_exists( Util::$LCDAY, $year ) &&
! array_key_exists( Util::$LCWEEK, $year ) &&
isset( $params[Util::$VALUE] ) && ( Util::$DATE_TIME == $params[Util::$VALUE] )) {
$isArrayDate = true;
}
else {
$isArrayDuration = true;
}
}
elseif( is_string( $year ) && ! empty( $year ) && ( is_array( $month ) || empty( $month ))) {
$year = trim( $year );
$params = Util::setParams( $month );
if( in_array( $year[0], UtilDuration::$PREFIXARR ) &&
( ! isset( $params[Util::$VALUE] ) || ( Util::$DATE_TIME != $params[Util::$VALUE] ))) {
$isStringDuration = true;
}
else {
$isStringDate = true;
}
}
switch( true ) {
case ( $year instanceof DateInterval ) :
try {
$dateInterval = UtilDuration::conformDateInterval( $year );
}
catch( Exception $e ) {
return false; // todo
}
$params = Util::setParams( $month );
if( true != self::isDurationRelatedEnd( $params )) {
unset( $params[UtilDuration::$RELATED] ); // remove default
}
unset( $params[Util::$VALUE] ); // remove default
$this->trigger[Util::$LCvalue] = (array) $dateInterval; // fix pre 7.0.5 bug
$this->trigger[Util::$LCparams] = $params;
return true;
break;
case ( $year instanceof DateTime ) :
$params = Util::setParams( $month );
$params[Util::$VALUE] = Util::$DATE_TIME;
try {
$year->setTimezone( new DateTimeZone( Util::$UTC ) );
}
catch( Exception $e ) {
return false; // todo
}
$date = Util::dateTime2Str( $year );
Util::strDate2arr( $date );
foreach( (array) $date as $k => $v ) { // populate all method args
$$k = $v;
}
unset( $week );
break;
case( $isArrayDate ) : // populate all method args
$params = Util::setParams( $month );
$SSYY = ( array_key_exists( Util::$LCYEAR, $year )) ? $year[Util::$LCYEAR] : null;
$month = ( array_key_exists( Util::$LCMONTH, $year )) ? $year[Util::$LCMONTH] : null;
$day = ( array_key_exists( Util::$LCDAY, $year )) ? $year[Util::$LCDAY] : null;
$week = ( array_key_exists( Util::$LCWEEK, $year )) ? $year[Util::$LCWEEK] : null;
$hour = ( array_key_exists( Util::$LCHOUR, $year )) ? $year[Util::$LCHOUR] : 0; //null;
$min = ( array_key_exists( Util::$LCMIN, $year )) ? $year[Util::$LCMIN] : 0; //null;
$sec = ( array_key_exists( Util::$LCSEC, $year )) ? $year[Util::$LCSEC] : 0; //null;
$year = $SSYY;
break;
case( Util::isArrayTimestampDate( $year )) : // timestamp UTC
$params = Util::setParams( $month );
$params[Util::$VALUE] = Util::$DATE_TIME;
$date = Util::timestamp2date( $year, 7 );
foreach( $date as $k => $v ) { // populate all method args
$$k = $v;
}
unset( $week );
break;
case ( $isArrayDuration ) :
$before = false;
if( array_key_exists( UtilDuration::$BEFORE, $year ) &&
( false !== $year[UtilDuration::$BEFORE] )) {
$before = true;
}
try {
$dateInterval1 = new DateInterval(
$durationString = UtilDuration::duration2str(
UtilDuration::duration2arr( $year )
)
);
$dateInterval1->invert = ( $before ) ? 1 : 0;
$dateInterval = UtilDuration::conformDateInterval( $dateInterval1 );
}
catch( Exception $e ) {
return false; // todo
}
$params = Util::setParams( $month );
if( true != ( $relatedStart = self::isDurationRelatedEnd( $params ))) {
$relatedStart = ( ! array_key_exists( UtilDuration::$RELATEDSTART, $year ) ||
( false !== $year[UtilDuration::$RELATEDSTART] ));
}
if( $relatedStart ) {
unset( $params[UtilDuration::$RELATED] ); // remove default
}
else {
$params[UtilDuration::$RELATED] = UtilDuration::$END;
}
unset( $params[Util::$VALUE] ); // remove default
$this->trigger[Util::$LCvalue] = (array) $dateInterval; // fix pre 7.0.5 bug
$this->trigger[Util::$LCparams] = $params;
return true;
break;
case( $isStringDuration ) : // duration in a string
$before = ( Util::$MINUS == $year[0] ) ? true : false;
if( UtilDuration::$P != $year[0] ) {
$year = substr( $year, 1 );
}
try {
$dateInterval1 = new DateInterval( $year );
$dateInterval1->invert = ( $before ) ? 1 : 0;
$dateInterval = UtilDuration::conformDateInterval( $dateInterval1 );
}
catch( Exception $e ) {
return false; // todo
}
$params = Util::setParams( $month );
if( true != self::isDurationRelatedEnd( $params )) {
unset( $params[UtilDuration::$RELATED] ); // remove default
}
unset( $params[Util::$VALUE] ); // remove default
$this->trigger = [
Util::$LCvalue => (array) $dateInterval, // fix pre 7.0.5 bug
Util::$LCparams => $params
];
return true;
break;
case( $isStringDate ) :
$params = Util::setParams( $month );
$date = Util::strDate2ArrayDate( $year, 7 ); // date in a string
unset( $year, $month, $week, $day, $date[Util::$UNPARSEDTEXT] );
if( empty( $date )) {
$sec = 0;
}
else {
foreach( $date as $k => $v ) {
$$k = $v;
}
}
break;
default : // single values in function input parameters
$params = Util::setParams( $params );
break;
} // end switch( true )
if( isset( $params[Util::$VALUE] ) && ( Util::$DATE_TIME == $params[Util::$VALUE] ) &&
! empty( $year ) && ! empty( $month ) && ! empty( $day )) { // && empty( $week )) { // date !
if( ! checkdate( $month, $day, $year )) {
return false; // todo
}
$params[Util::$VALUE] = Util::$DATE_TIME;
$hour = ( $hour ) ? $hour : 0;
$min = ( $min ) ? $min : 0;
$sec = ( $sec ) ? $sec : 0;
$this->trigger = [ Util::$LCparams => $params ];
$this->trigger[Util::$LCvalue] = [
Util::$LCYEAR => (int) $year,
Util::$LCMONTH => (int) $month,
Util::$LCDAY => (int) $day,
Util::$LCHOUR => (int) $hour,
Util::$LCMIN => (int) $min,
Util::$LCSEC => (int) $sec,
Util::$LCtz => Util::$Z,
];
return true;
}
else { // if( ! empty( $week ) || ( 0 == $week )) { // duration
if( $relatedStart && ! self::isDurationRelatedEnd( $params )) {
unset( $params[UtilDuration::$RELATED] ); // remove default
}
else {
$params[UtilDuration::$RELATED] = UtilDuration::$END;
}
unset( $params[Util::$VALUE] ); // Util::$DURATION default
if( ! isset( $week )) {
$week = 0;
}
$duration = self::variables2Array(
$year, $month, $day, $week, $hour, $min, $sec
);
try {
$dateInterval1 = new DateInterval(
$durationString = UtilDuration::duration2str(
UtilDuration::duration2arr( $duration )
)
);
if( $before ) {
$dateInterval1->invert = 1;
}
$dateInterval = UtilDuration::conformDateInterval( $dateInterval1 );
}
catch( Exception $e ) {
return false; // todo
}
$this->trigger[Util::$LCvalue] = (array) $dateInterval; // fix pre 7.0.5 bug
$this->trigger[Util::$LCparams] = $params;
}
return true;
}
/**
* Return array of the argument variables
*
* @param int $year
* @param int $month
* @param int $day
* @param int $week
* @param int $hour
* @param int $min
* @param int $sec
* @return array
* @access private
* @static
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.26.7 - 2018-11-30
*/
private static function variables2Array(
$year = null,
$month = null,
$day = null,
$week = null,
$hour = null,
$min = null,
$sec = null
) {
$result = [ Util::$LCSEC => 0 ];
if( ! empty( $year )) {
$result[Util::$LCWEEK] = $year;
}
if( ! empty( $month )) {
$result[Util::$LCWEEK] = $month;
}
if( ! empty( $week )) {
$result[Util::$LCWEEK] = $week;
}
if( ! empty( $day )) {
$result[Util::$LCDAY] = $day;
}
if( ! empty( $hour )) {
$result[Util::$LCHOUR] = $hour;
}
if( ! empty( $min )) {
$result[Util::$LCMIN] = $min;
}
if( ! empty( $sec )) {
$result[Util::$LCSEC] = $sec;
}
return $result;
}
/**
* Return bool true if duration i9s related END
*
* @param null|array $params
* @return bool
* @access private
* @static
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.26.7 - 2018-12-01
*/
private static function isDurationRelatedEnd( $params ) {
return ( is_array( $params ) &&
isset( $params[UtilDuration::$RELATED] ) &&
( 0 == strcasecmp( UtilDuration::$END, $params[UtilDuration::$RELATED] )));
}
}

View File

@@ -0,0 +1,91 @@
<?php
/**
* iCalcreator, the PHP class package managing iCal (rfc2445/rfc5445) calendar information.
*
* copyright (c) 2007-2019 Kjell-Inge Gustafsson, kigkonsult, All rights reserved
* Link https://kigkonsult.se
* Package iCalcreator
* Version 2.26.8
* License Subject matter of licence is the software iCalcreator.
* The above copyright, link, package and version notices,
* this licence notice and the invariant [rfc5545] PRODID result use
* as implemented and invoked in iCalcreator shall be included in
* all copies or substantial portions of the iCalcreator.
*
* iCalcreator 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 3 of the License,
* or (at your option) any later version.
*
* iCalcreator 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 iCalcreator. If not, see <https://www.gnu.org/licenses/>.
*
* This file is a part of iCalcreator.
*/
namespace Kigkonsult\Icalcreator\Traits;
use Kigkonsult\Icalcreator\Util\Util;
/**
* TZID property functions
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.22.23 - 2017-02-05
*/
trait TZIDtrait
{
/**
* @var array component property TZID value
* @access protected
*/
protected $tzid = null;
/**
* Return formatted output for calendar component property tzid
*
* @return string
*/
public function createTzid() {
if( empty( $this->tzid )) {
return null;
}
if( empty( $this->tzid[Util::$LCvalue] )) {
return ( $this->getConfig( Util::$ALLOWEMPTY )) ? Util::createElement( Util::$TZID ) : null;
}
return Util::createElement(
Util::$TZID,
Util::createParams( $this->tzid[Util::$LCparams] ),
Util::strrep( $this->tzid[Util::$LCvalue] )
);
}
/**
* Set calendar component property tzid
*
* @since 2.23.12 - 2017-04-22
* @param string $value
* @param array $params
* @return bool
*/
public function setTzid( $value, $params = null ) {
if( empty( $value )) {
if( $this->getConfig( Util::$ALLOWEMPTY )) {
$value = Util::$SP0;
}
else {
return false;
}
}
$this->tzid = [
Util::$LCvalue => trim( Util::trimTrailNL( $value )),
Util::$LCparams => Util::setParams( $params ),
];
return true;
}
}

View File

@@ -0,0 +1,101 @@
<?php
/**
* iCalcreator, the PHP class package managing iCal (rfc2445/rfc5445) calendar information.
*
* copyright (c) 2007-2019 Kjell-Inge Gustafsson, kigkonsult, All rights reserved
* Link https://kigkonsult.se
* Package iCalcreator
* Version 2.26.8
* License Subject matter of licence is the software iCalcreator.
* The above copyright, link, package and version notices,
* this licence notice and the invariant [rfc5545] PRODID result use
* as implemented and invoked in iCalcreator shall be included in
* all copies or substantial portions of the iCalcreator.
*
* iCalcreator 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 3 of the License,
* or (at your option) any later version.
*
* iCalcreator 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 iCalcreator. If not, see <https://www.gnu.org/licenses/>.
*
* This file is a part of iCalcreator.
*/
namespace Kigkonsult\Icalcreator\Traits;
use Kigkonsult\Icalcreator\Util\Util;
/**
* TZNAME property functions
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.22.23 - 2017-02-17
*/
trait TZNAMEtrait
{
/**
* @var array component property TZNAME value
* @access protected
*/
protected $tzname = null;
/**
* Return formatted output for calendar component property tzname
*
* @return string
*/
public function createTzname() {
if( empty( $this->tzname )) {
return null;
}
$output = null;
$lang = $this->getConfig( Util::$LANGUAGE );
foreach( $this->tzname as $tzx => $theName ) {
if( ! empty( $theName[Util::$LCvalue] )) {
$output .= Util::createElement(
Util::$TZNAME,
Util::createParams( $theName[Util::$LCparams], [ Util::$LANGUAGE ], $lang ),
Util::strrep( $theName[Util::$LCvalue] )
);
}
elseif( $this->getConfig( Util::$ALLOWEMPTY )) {
$output .= Util::createElement( Util::$TZNAME );
}
}
return $output;
}
/**
* Set calendar component property tzname
*
* @param string $value
* @param array $params
* @param integer $index
* @return bool
*/
public function setTzname( $value, $params = null, $index = null ) {
if( empty( $value )) {
if( $this->getConfig( Util::$ALLOWEMPTY )) {
$value = Util::$SP0;
}
else {
return false;
}
}
Util::setMval(
$this->tzname,
Util::trimTrailNL( $value ),
$params,
false,
$index
);
return true;
}
}

View File

@@ -0,0 +1,90 @@
<?php
/**
* iCalcreator, the PHP class package managing iCal (rfc2445/rfc5445) calendar information.
*
* copyright (c) 2007-2019 Kjell-Inge Gustafsson, kigkonsult, All rights reserved
* Link https://kigkonsult.se
* Package iCalcreator
* Version 2.26.8
* License Subject matter of licence is the software iCalcreator.
* The above copyright, link, package and version notices,
* this licence notice and the invariant [rfc5545] PRODID result use
* as implemented and invoked in iCalcreator shall be included in
* all copies or substantial portions of the iCalcreator.
*
* iCalcreator 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 3 of the License,
* or (at your option) any later version.
*
* iCalcreator 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 iCalcreator. If not, see <https://www.gnu.org/licenses/>.
*
* This file is a part of iCalcreator.
*/
namespace Kigkonsult\Icalcreator\Traits;
use Kigkonsult\Icalcreator\Util\Util;
/**
* TZOFFSETFROM property functions
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.22.23 - 2017-02-05
*/
trait TZOFFSETFROMtrait
{
/**
* @var array component property TZOFFSETFROM value
* @access protected
*/
protected $tzoffsetfrom = null;
/**
* Return formatted output for calendar component property tzoffsetfrom
*
* @return string
*/
public function createTzoffsetfrom() {
if( empty( $this->tzoffsetfrom )) {
return null;
}
if( empty( $this->tzoffsetfrom[Util::$LCvalue] )) {
return ( $this->getConfig( Util::$ALLOWEMPTY )) ? Util::createElement( Util::$TZOFFSETFROM ) : null;
}
return Util::createElement(
Util::$TZOFFSETFROM,
Util::createParams( $this->tzoffsetfrom[Util::$LCparams] ),
$this->tzoffsetfrom[Util::$LCvalue]
);
}
/**
* Set calendar component property tzoffsetfrom
*
* @param string $value
* @param array $params
* @return bool
*/
public function setTzoffsetfrom( $value, $params = null ) {
if( empty( $value )) {
if( $this->getConfig( Util::$ALLOWEMPTY )) {
$value = Util::$SP0;
}
else {
return false;
}
}
$this->tzoffsetfrom = [
Util::$LCvalue => $value,
Util::$LCparams => Util::setParams( $params ),
];
return true;
}
}

View File

@@ -0,0 +1,90 @@
<?php
/**
* iCalcreator, the PHP class package managing iCal (rfc2445/rfc5445) calendar information.
*
* copyright (c) 2007-2019 Kjell-Inge Gustafsson, kigkonsult, All rights reserved
* Link https://kigkonsult.se
* Package iCalcreator
* Version 2.26.8
* License Subject matter of licence is the software iCalcreator.
* The above copyright, link, package and version notices,
* this licence notice and the invariant [rfc5545] PRODID result use
* as implemented and invoked in iCalcreator shall be included in
* all copies or substantial portions of the iCalcreator.
*
* iCalcreator 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 3 of the License,
* or (at your option) any later version.
*
* iCalcreator 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 iCalcreator. If not, see <https://www.gnu.org/licenses/>.
*
* This file is a part of iCalcreator.
*/
namespace Kigkonsult\Icalcreator\Traits;
use Kigkonsult\Icalcreator\Util\Util;
/**
* TZOFFSETTO property functions
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.22.23 - 2017-02-02
*/
trait TZOFFSETTOtrait
{
/**
* @var array component property TZOFFSETTO value
* @access protected
*/
protected $tzoffsetto = null;
/**
* Return formatted output for calendar component property tzoffsetto
*
* @return string
*/
public function createTzoffsetto() {
if( empty( $this->tzoffsetto )) {
return null;
}
if( empty( $this->tzoffsetto[Util::$LCvalue] )) {
return ( $this->getConfig( Util::$ALLOWEMPTY )) ? Util::createElement( Util::$TZOFFSETTO ) : null;
}
return Util::createElement(
Util::$TZOFFSETTO,
Util::createParams( $this->tzoffsetto[Util::$LCparams] ),
$this->tzoffsetto[Util::$LCvalue]
);
}
/**
* Set calendar component property tzoffsetto
*
* @param string $value
* @param array $params
* @return bool
*/
public function setTzoffsetto( $value, $params = null ) {
if( empty( $value )) {
if( $this->getConfig( Util::$ALLOWEMPTY )) {
$value = Util::$SP0;
}
else {
return false;
}
}
$this->tzoffsetto = [
Util::$LCvalue => $value,
Util::$LCparams => Util::setParams( $params ),
];
return true;
}
}

View File

@@ -0,0 +1,90 @@
<?php
/**
* iCalcreator, the PHP class package managing iCal (rfc2445/rfc5445) calendar information.
*
* copyright (c) 2007-2019 Kjell-Inge Gustafsson, kigkonsult, All rights reserved
* Link https://kigkonsult.se
* Package iCalcreator
* Version 2.26.8
* License Subject matter of licence is the software iCalcreator.
* The above copyright, link, package and version notices,
* this licence notice and the invariant [rfc5545] PRODID result use
* as implemented and invoked in iCalcreator shall be included in
* all copies or substantial portions of the iCalcreator.
*
* iCalcreator 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 3 of the License,
* or (at your option) any later version.
*
* iCalcreator 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 iCalcreator. If not, see <https://www.gnu.org/licenses/>.
*
* This file is a part of iCalcreator.
*/
namespace Kigkonsult\Icalcreator\Traits;
use Kigkonsult\Icalcreator\Util\Util;
/**
* TZURL property functions
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.22.23 - 2017-02-05
*/
trait TZURLtrait
{
/**
* @var array component property TZURL value
* @access protected
*/
protected $tzurl = null;
/**
* Return formatted output for calendar component property tzurl
*
* @return string
*/
public function createTzurl() {
if( empty( $this->tzurl )) {
return null;
}
if( empty( $this->tzurl[Util::$LCvalue] )) {
return ( $this->getConfig( Util::$ALLOWEMPTY )) ? Util::createElement( Util::$TZURL ) : null;
}
return Util::createElement(
Util::$TZURL,
Util::createParams( $this->tzurl[Util::$LCparams] ),
$this->tzurl[Util::$LCvalue]
);
}
/**
* Set calendar component property tzurl
*
* @param string $value
* @param array $params
* @return bool
*/
public function setTzurl( $value, $params = null ) {
if( empty( $value )) {
if( $this->getConfig( Util::$ALLOWEMPTY )) {
$value = Util::$SP0;
}
else {
return false;
}
}
$this->tzurl = [
Util::$LCvalue => $value,
Util::$LCparams => Util::setParams( $params ),
];
return true;
}
}

View File

@@ -0,0 +1,84 @@
<?php
/**
* iCalcreator, the PHP class package managing iCal (rfc2445/rfc5445) calendar information.
*
* copyright (c) 2007-2019 Kjell-Inge Gustafsson, kigkonsult, All rights reserved
* Link https://kigkonsult.se
* Package iCalcreator
* Version 2.26.8
* License Subject matter of licence is the software iCalcreator.
* The above copyright, link, package and version notices,
* this licence notice and the invariant [rfc5545] PRODID result use
* as implemented and invoked in iCalcreator shall be included in
* all copies or substantial portions of the iCalcreator.
*
* iCalcreator 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 3 of the License,
* or (at your option) any later version.
*
* iCalcreator 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 iCalcreator. If not, see <https://www.gnu.org/licenses/>.
*
* This file is a part of iCalcreator.
*/
namespace Kigkonsult\Icalcreator\Traits;
use Kigkonsult\Icalcreator\Util\Util;
/**
* UID property functions
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.23.20 - 2017-02-17
*/
trait UIDtrait
{
/**
* @var array component property UID value
* @access protected
*/
protected $uid = null;
/**
* Return formatted output for calendar component property uid
*
* If uid is missing, uid is created
*
* @return string
*/
public function createUid() {
if( empty( $this->uid )) {
$this->uid = Util::makeUid( $this->getConfig( Util::$UNIQUE_ID ));
}
return Util::createElement(
Util::$UID,
Util::createParams( $this->uid[Util::$LCparams] ),
$this->uid[Util::$LCvalue]
);
}
/**
* Set calendar component property uid
*
* @param string $value
* @param array $params
* @return bool
*/
public function setUid( $value, $params = null ) {
if( empty( $value ) && ( Util::$ZERO != $value )) {
return false;
} // no allowEmpty check here !!!!
$this->uid = [
Util::$LCvalue => Util::trimTrailNL( $value ),
Util::$LCparams => Util::setParams( $params ),
];
return true;
}
}

View File

@@ -0,0 +1,98 @@
<?php
/**
* iCalcreator, the PHP class package managing iCal (rfc2445/rfc5445) calendar information.
*
* copyright (c) 2007-2019 Kjell-Inge Gustafsson, kigkonsult, All rights reserved
* Link https://kigkonsult.se
* Package iCalcreator
* Version 2.26.8
* License Subject matter of licence is the software iCalcreator.
* The above copyright, link, package and version notices,
* this licence notice and the invariant [rfc5545] PRODID result use
* as implemented and invoked in iCalcreator shall be included in
* all copies or substantial portions of the iCalcreator.
*
* iCalcreator 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 3 of the License,
* or (at your option) any later version.
*
* iCalcreator 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 iCalcreator. If not, see <https://www.gnu.org/licenses/>.
*
* This file is a part of iCalcreator.
*/
namespace Kigkonsult\Icalcreator\Traits;
use Kigkonsult\Icalcreator\Util\Util;
use function filter_var;
use function substr;
/**
* URL property functions
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.22.23 - 2017-02-05
*/
trait URLtrait
{
/**
* @var array component property URL value
* @access protected
*/
protected $url = null;
/**
* Return formatted output for calendar component property url
*
* @return string
*/
public function createUrl() {
if( empty( $this->url )) {
return null;
}
if( empty( $this->url[Util::$LCvalue] )) {
return ( $this->getConfig( Util::$ALLOWEMPTY )) ? Util::createElement( Util::$URL ) : null;
}
return Util::createElement(
Util::$URL,
Util::createParams( $this->url[Util::$LCparams] ),
$this->url[Util::$LCvalue]
);
}
/**
* Set calendar component property url
*
* @param string $value
* @param array $params
* @return bool
*/
public function setUrl( $value, $params = null ) {
static $URN = 'urn';
if( ! empty( $value )) {
if( ! filter_var( $value, FILTER_VALIDATE_URL ) &&
( 0 != strcasecmp( $URN, substr( $value, 0, 3 )))) {
return false;
}
}
elseif( $this->getConfig( Util::$ALLOWEMPTY )) {
$value = Util::$SP0;
}
else {
return false;
}
$this->url = [
Util::$LCvalue => $value,
Util::$LCparams => Util::setParams( $params ),
];
return true;
}
}

View File

@@ -0,0 +1,77 @@
<?php
/**
* iCalcreator, the PHP class package managing iCal (rfc2445/rfc5445) calendar information.
*
* copyright (c) 2007-2019 Kjell-Inge Gustafsson, kigkonsult, All rights reserved
* Link https://kigkonsult.se
* Package iCalcreator
* Version 2.26.8
* License Subject matter of licence is the software iCalcreator.
* The above copyright, link, package and version notices,
* this licence notice and the invariant [rfc5545] PRODID result use
* as implemented and invoked in iCalcreator shall be included in
* all copies or substantial portions of the iCalcreator.
*
* iCalcreator 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 3 of the License,
* or (at your option) any later version.
*
* iCalcreator 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 iCalcreator. If not, see <https://www.gnu.org/licenses/>.
*
* This file is a part of iCalcreator.
*/
namespace Kigkonsult\Icalcreator\Traits;
use Kigkonsult\Icalcreator\Util\Util;
/**
* VERSION property functions
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.22.23 - 2017-02-18
*/
trait VERSIONtrait
{
/**
* Property Name: VERSION
*
* Description: A value of "2.0" corresponds to this memo.
*
* @var string calendar property VERSION
* @access protected
*/
protected $version = '2.0';
/**
* Return formatted output for calendar property version
*
* If version is missing, version is set
*
* @return string
*/
public function createVersion() {
return sprintf( self::$FMTICAL, Util::$VERSION, $this->version );
}
/**
* Set (another?) calendar version
*
* @param string $value
* @return bool
*/
public function setVersion( $value ) {
if( empty( $value )) {
return false;
}
$this->version = $value;
return true;
}
}

View File

@@ -0,0 +1,166 @@
<?php
/**
* iCalcreator, the PHP class package managing iCal (rfc2445/rfc5445) calendar information.
*
* copyright (c) 2007-2019 Kjell-Inge Gustafsson, kigkonsult, All rights reserved
* Link https://kigkonsult.se
* Package iCalcreator
* Version 2.26.8
* License Subject matter of licence is the software iCalcreator.
* The above copyright, link, package and version notices,
* this licence notice and the invariant [rfc5545] PRODID result use
* as implemented and invoked in iCalcreator shall be included in
* all copies or substantial portions of the iCalcreator.
*
* iCalcreator 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 3 of the License,
* or (at your option) any later version.
*
* iCalcreator 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 iCalcreator. If not, see <https://www.gnu.org/licenses/>.
*
* This file is a part of iCalcreator.
*/
namespace Kigkonsult\Icalcreator\Traits;
use Kigkonsult\Icalcreator\Util\Util;
use function count;
use function implode;
use function is_array;
use function is_numeric;
use function strtoupper;
/**
* X-property functions
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.22.23 - 2017-02-02
*/
trait X_PROPtrait
{
/**
* @var array component property X-property value
* @access protected
*/
protected $xprop = null;
/**
* Return formatted output for calendar/component property x-prop
*
* @return string
*/
public function createXprop() {
if( empty( $this->xprop ) || ! is_array( $this->xprop )) {
return null;
}
$output = null;
$lang = $this->getConfig( Util::$LANGUAGE );
foreach( $this->xprop as $label => $xpropPart ) {
if( ! isset( $xpropPart[Util::$LCvalue] ) ||
( empty( $xpropPart[Util::$LCvalue] ) && ! is_numeric( $xpropPart[Util::$LCvalue] ))) {
if( $this->getConfig( Util::$ALLOWEMPTY )) {
$output .= Util::createElement( $label );
}
continue;
}
if( is_array( $xpropPart[Util::$LCvalue] )) {
foreach( $xpropPart[Util::$LCvalue] as $pix => $theXpart ) {
$xpropPart[Util::$LCvalue][$pix] = Util::strrep( $theXpart );
}
$xpropPart[Util::$LCvalue] = implode( Util::$COMMA, $xpropPart[Util::$LCvalue] );
}
else {
$xpropPart[Util::$LCvalue] = Util::strrep( $xpropPart[Util::$LCvalue] );
}
$output .= Util::createElement(
$label,
Util::createParams( $xpropPart[Util::$LCparams], [ Util::$LANGUAGE ], $lang ),
Util::trimTrailNL( $xpropPart[Util::$LCvalue] )
);
}
return $output;
}
/**
* Set calendar property x-prop
*
* @param string $label
* @param string $value
* @param array $params optional
* @return bool
*/
public function setXprop( $label, $value, $params = null ) {
if( empty( $label ) || ! Util::isXprefixed( $label )) {
return false;
}
if( empty( $value ) && ! is_numeric( $value )) {
if( $this->getConfig( Util::$ALLOWEMPTY )) {
$value = Util::$SP0;
}
else {
return false;
}
}
$xprop = [ Util::$LCvalue => $value ];
$xprop[Util::$LCparams] = Util::setParams( $params );
if( ! is_array( $this->xprop )) {
$this->xprop = [];
}
$this->xprop[strtoupper( $label )] = $xprop;
return true;
}
/**
* Delete component property X-prop value
*
* @param string $propName
* @param array $xProp component X-property
* @param int $propix removal counter
* @param array $propdelix
* @access protected
* @return bool
* @static
*/
protected static function deleteXproperty( $propName, & $xProp, & $propix, & $propdelix ) {
$reduced = [];
if( $propName != Util::$X_PROP ) {
if( ! isset( $xProp[$propName] )) {
unset( $propdelix[$propName] );
return false;
}
foreach( $xProp as $k => $xValue ) {
if(( $k != $propName ) && ! empty( $xValue )) {
$reduced[$k] = $xValue;
}
}
}
else {
if( count( $xProp ) <= $propix ) {
unset( $propdelix[$propName] );
return false;
}
$xpropno = 0;
foreach( $xProp as $xPropKey => $xPropValue ) {
if( $propix != $xpropno ) {
$reduced[$xPropKey] = $xPropValue;
}
$xpropno++;
}
}
$xProp = $reduced;
if( empty( $xProp )) {
$xProp = null;
unset( $propdelix[$propName] );
return false;
}
return true;
}
}

View File

@@ -0,0 +1,226 @@
<?php
/**
* iCalcreator, the PHP class package managing iCal (rfc2445/rfc5445) calendar information.
*
* copyright (c) 2007-2019 Kjell-Inge Gustafsson, kigkonsult, All rights reserved
* Link https://kigkonsult.se
* Package iCalcreator
* Version 2.26.8
* License Subject matter of licence is the software iCalcreator.
* The above copyright, link, package and version notices,
* this licence notice and the invariant [rfc5545] PRODID result use
* as implemented and invoked in iCalcreator shall be included in
* all copies or substantial portions of the iCalcreator.
*
* iCalcreator 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 3 of the License,
* or (at your option) any later version.
*
* iCalcreator 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 iCalcreator. If not, see <https://www.gnu.org/licenses/>.
*
* This file is a part of iCalcreator.
*/
namespace Kigkonsult\Icalcreator\Util;
use DateTime;
use DateTimeZone;
use Exception;
use Kigkonsult\Icalcreator\Util\Util;
use function date_default_timezone_get;
use function explode;
use function get_object_vars;
use function is_array;
use function is_object;
use function substr;
/**
* iCalcreator::selectComponent dateTime support class
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.26 - 2018-11-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 = [];
/**
* @link https://php.net/manual/en/language.oop5.cloning.php#116329
*/
public function __clone()
{
$object_vars = get_object_vars( $this );
foreach( $object_vars as $attr_name => $attr_value ) {
if( is_object($this->$attr_name )) {
$this->$attr_name = clone $this->$attr_name;
}
else if( is_array( $this->$attr_name )) {
// Note: This copies only one dimension arrays
foreach( $this->$attr_name as &$attr_array_value ) {
if( is_object( $attr_array_value )) {
$attr_array_value = clone $attr_array_value;
}
unset( $attr_array_value);
}
}
}
}
/**
* Return time (His) array
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.23.20 - 2017-02-07
* @return array
*/
public function getTime() {
static $H_I_S = 'H:i:s';
$res = [];
foreach( explode( Util::$COLON, $this->format( $H_I_S )) as $t ) {
$res[] = (int) $t;
}
return $res;
}
/**
* set date and time from YmdHis string
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.26.2 - 2018-11-14
* @param string $YmdHisString
*/
public function setDateTimeFromString( $YmdHisString ) {
$this->setDate(
(int) substr( $YmdHisString, 0, 4 ),
(int) substr( $YmdHisString, 4, 2 ),
(int) substr( $YmdHisString, 6, 2 )
);
$this->setTime(
(int) substr( $YmdHisString, 8, 2 ),
(int) substr( $YmdHisString, 10, 2 ),
(int) substr( $YmdHisString, 12, 2 )
);
}
/**
* 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
* @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.26 - 2018-11-10
* @param array $date
* @param array $params
* @param array $tz
* @param string $dtstartTz
* @return IcaldateTime
* @static
*/
public static function factory( array $date, $params = null, $tz = null, $dtstartTz = null ) {
static $YMDHIS = 'YmdHis';
static $YMD = 'Ymd';
static $Y_M_D = 'Y-m-d';
if( isset( $params[Util::$TZID] ) && ! empty( $params[Util::$TZID] )) {
$tz = ( Util::$Z == $params[Util::$TZID] ) ? Util::$UTC : $params[Util::$TZID];
}
elseif( isset( $tz[Util::$LCtz] ) && ! empty( $tz[Util::$LCtz] )) {
$tz = ( Util::$Z == $tz[Util::$LCtz] ) ? Util::$UTC : $tz[Util::$LCtz];
}
else {
$tz = date_default_timezone_get();
}
$strdate = Util::getYMDString( $date );
if( isset( $date[Util::$LCHOUR] )) {
$strdate .= Util::$T;
$strdate .= Util::getHisString( $date );
}
try {
$timezone = new DateTimeZone( $tz );
$iCaldateTime = new IcaldateTime( $strdate, $timezone );
}
catch( Exception $e ) {
$iCaldateTime = new IcaldateTime( $strdate );
}
if( ! empty( $dtstartTz )) {
if( Util::$Z == $dtstartTz ) {
$dtstartTz = Util::$UTC;
}
// set the same timezone as dtstart
if( $dtstartTz != $iCaldateTime->getTimezoneName()) {
try {
$timezone = new DateTimeZone( $dtstartTz );
$iCaldateTime->setTimezone( $timezone );
}
catch( Exception $e ) {
} // ??
}
}
if( Util::isParamsValueSet( [ Util::$LCparams => $params ], Util::$DATE )) {
$iCaldateTime->dateFormat = $Y_M_D;
$iCaldateTime->key = $iCaldateTime->format( $YMD );
}
else {
$iCaldateTime->key = $iCaldateTime->format( $YMDHIS );
}
return $iCaldateTime;
}
/**
* Return clone
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.26.2 - 2018-11-14
* @return static
*/
public function getClone() {
return clone $this;
}
}

View File

@@ -0,0 +1,278 @@
<?php
/**
* iCalcreator, the PHP class package managing iCal (rfc2445/rfc5445) calendar information.
*
* copyright (c) 2007-2019 Kjell-Inge Gustafsson, kigkonsult, All rights reserved
* Link https://kigkonsult.se
* Package iCalcreator
* Version 2.26.8
* License Subject matter of licence is the software iCalcreator.
* The above copyright, link, package and version notices,
* this licence notice and the invariant [rfc5545] PRODID result use
* as implemented and invoked in iCalcreator shall be included in
* all copies or substantial portions of the iCalcreator.
*
* iCalcreator 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 3 of the License,
* or (at your option) any later version.
*
* iCalcreator 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 iCalcreator. If not, see <https://www.gnu.org/licenses/>.
*
* This file is a part of iCalcreator.
*/
namespace Kigkonsult\Icalcreator\Util;
use Kigkonsult\Icalcreator\Vcalendar;
use function array_change_key_case;
use function array_keys;
use function ctype_digit;
use function filter_var;
use function in_array;
use function is_array;
use function sprintf;
use function strcasecmp;
use function strpos;
use function substr;
use function trim;
/**
* iCalcreator attendee support class
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.26 - 2018-11-10
*/
class UtilAttendee
{
/**
* Return string after a cal-address check, prefix mail address with MAILTO
*
* Acceps other prefix ftp://, http://, file://, gopher://, news:, nntp://, telnet://, wais://, prospero:// etc
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.26 - 2018-11-10
* @param string $value
* @param bool $trimQuotes
* @return string
* @static
* @TODO fix in Util::splitContent() ??
*/
public static function calAddressCheck( $value, $trimQuotes = true ) {
static $MAILTOCOLON = 'MAILTO:';
$value = trim( $value );
if( $trimQuotes ) {
$value = trim( $value, Util::$QQ );
}
switch( true ) {
case( empty( $value )) :
break;
case( 0 == strcasecmp( $MAILTOCOLON, substr( $value, 0, 7 ))) :
$value = $MAILTOCOLON . substr( $value, 7 ); // accept mailto:
break;
case( false !== ( $pos = strpos( substr( $value, 0, 9 ), Util::$COLON ))) :
break; // accept (as is) from list above
case( filter_var( $value, FILTER_VALIDATE_EMAIL )) :
$value = $MAILTOCOLON . $value; // accept mail address
break;
default : // accept as is...
break;
}
return $value;
}
/**
* Return formatted output for calendar component property attendee
*
* @param array $attendeeData
* @param bool $allowEmpty
* @return string
* @static
*/
public static function formatAttendee( array $attendeeData, $allowEmpty ) {
static $FMTQVALUE = '"%s"';
static $FMTKEYVALUE = ';%s=%s';
static $FMTKEYEQ = ';%s=';
static $FMTDIREQ = ';%s=%s%s%s';
$output = null;
foreach( $attendeeData as $ax => $attendeePart ) {
if( empty( $attendeePart[Util::$LCvalue] )) {
if( $allowEmpty ) {
$output .= Util::createElement( Util::$ATTENDEE );
}
continue;
}
$attributes = $content = null;
foreach( $attendeePart as $pLabel => $pValue ) {
if( Util::$LCvalue == $pLabel ) {
$content .= $pValue;
continue;
}
if(( Util::$LCparams != $pLabel ) ||
( ! is_array( $pValue ))) {
continue;
}
foreach( $pValue as $pLabel2 => $pValue2 ) { // fix (opt) quotes
if( is_array( $pValue2 ) ||
in_array( $pLabel2, Util::$ATTENDEEPARKEYS )) {
continue;
} // DELEGATED-FROM, DELEGATED-TO, MEMBER
if(( false !== strpos( $pValue2, Util::$COLON )) ||
( false !== strpos( $pValue2, Util::$SEMIC )) ||
( false !== strpos( $pValue2, Util::$COMMA ))) {
$pValue[$pLabel2] = sprintf( $FMTQVALUE, $pValue2 );
}
}
/* set attenddee parameters in rfc2445 order */
if( isset( $pValue[Util::$CUTYPE] )) {
$attributes .= sprintf( $FMTKEYVALUE, Util::$CUTYPE, $pValue[Util::$CUTYPE] );
}
if( isset( $pValue[Util::$MEMBER] )) {
$attributes .= sprintf( $FMTKEYEQ, Util::$MEMBER ) .
self::getQuotedListItems( $pValue[Util::$MEMBER] );
}
if( isset( $pValue[Util::$ROLE] )) {
$attributes .= sprintf( $FMTKEYVALUE, Util::$ROLE, $pValue[Util::$ROLE] );
}
if( isset( $pValue[Util::$PARTSTAT] )) {
$attributes .= sprintf( $FMTKEYVALUE, Util::$PARTSTAT, $pValue[Util::$PARTSTAT] );
}
if( isset( $pValue[Util::$RSVP] )) {
$attributes .= sprintf( $FMTKEYVALUE, Util::$RSVP, $pValue[Util::$RSVP] );
}
if( isset( $pValue[Util::$DELEGATED_TO] )) {
$attributes .= sprintf( $FMTKEYEQ, Util::$DELEGATED_TO ) .
self::getQuotedListItems( $pValue[Util::$DELEGATED_TO] );
}
if( isset( $pValue[Util::$DELEGATED_FROM] )) {
$attributes .= sprintf( $FMTKEYEQ, Util::$DELEGATED_FROM ) .
self::getQuotedListItems( $pValue[Util::$DELEGATED_FROM] );
}
if( isset( $pValue[Util::$SENT_BY] )) {
$attributes .= sprintf( $FMTKEYVALUE, Util::$SENT_BY, $pValue[Util::$SENT_BY] );
}
if( isset( $pValue[Util::$CN] )) {
$attributes .= sprintf( $FMTKEYVALUE, Util::$CN, $pValue[Util::$CN] );
}
if( isset( $pValue[Util::$DIR] )) {
$delim = ( false === \strpos( $pValue[Util::$DIR], Util::$QQ )) ? Util::$QQ : null;
$attributes .= sprintf( $FMTDIREQ, Util::$DIR, $delim, $pValue[Util::$DIR], $delim );
}
if( isset( $pValue[Util::$LANGUAGE] )) {
$attributes .= sprintf( $FMTKEYVALUE, Util::$LANGUAGE, $pValue[Util::$LANGUAGE] );
}
$xparams = [];
foreach( $pValue as $pLabel2 => $pValue2 ) {
if( ctype_digit((string) $pLabel2 )) {
$xparams[] = $pValue2;
}
elseif( ! in_array( $pLabel2, Util::$ATTENDEEPARALLKEYS )) {
$xparams[$pLabel2] = $pValue2;
}
}
if( empty( $xparams )) {
continue;
}
ksort( $xparams, SORT_STRING );
foreach( $xparams as $pLabel2 => $pValue2 ) {
if( ctype_digit((string) $pLabel2 )) {
$attributes .= Util::$SEMIC . $pValue2;
} // ??
else {
$attributes .= sprintf( $FMTKEYVALUE, $pLabel2, $pValue2 );
}
}
} // end foreach( $attendeePart )) as $pLabel => $pValue )
$output .= Util::createElement( Util::$ATTENDEE, $attributes, $content );
} // end foreach( $attendeeData as $ax => $attendeePart )
return $output;
}
/**
* Return string of comma-separated quoted array members
*
* @param array $list
* @return string
* @access private
* @static
*/
private static function getQuotedListItems( array $list ) {
static $FMTQVALUE = '"%s"';
static $FMTCOMMAQVALUE = ',"%s"';
$strList = null;
foreach( $list as $x => $v ) {
$strList .= ( 0 < $x ) ? sprintf( $FMTCOMMAQVALUE, $v ) : sprintf( $FMTQVALUE, $v );
}
return $strList;
}
/**
* Return formatted output for calendar component property attendee
*
* @param array $params
* @param string $compType
* @param string $lang
* @return array
* @static
*/
public static function prepAttendeeParams( $params, $compType, $lang ) {
static $NONXPROPCOMPS = null;
if( is_null( $NONXPROPCOMPS )) {
$NONXPROPCOMPS = [ Vcalendar::VFREEBUSY, Vcalendar::VALARM ];
}
$params2 = [];
if( is_array( $params )) {
$optArr = [];
$params = array_change_key_case( $params, CASE_UPPER );
foreach( $params as $pLabel => $optParamValue ) {
if( ! Util::isXprefixed( $pLabel ) &&
Util::isCompInList( $compType, $NONXPROPCOMPS )) {
continue;
}
switch( $pLabel ) {
case Util::$MEMBER:
case Util::$DELEGATED_TO:
case Util::$DELEGATED_FROM:
if( ! is_array( $optParamValue )) {
$optParamValue = [ $optParamValue ];
}
foreach(( array_keys( $optParamValue )) as $px ) {
$optArr[$pLabel][] = self::calAddressCheck( $optParamValue[$px] );
}
break;
default:
if( Util::$SENT_BY == $pLabel ) {
$optParamValue = self::calAddressCheck( $optParamValue );
}
else {
$optParamValue = trim( $optParamValue, Util::$QQ );
}
$params2[$pLabel] = $optParamValue;
break;
} // end switch( $pLabel.. .
} // end foreach( $params as $pLabel => $optParamValue )
foreach( $optArr as $pLabel => $pValue ) {
$params2[$pLabel] = $pValue;
}
} // end if( is_array($params ))
// remove defaults
Util::existRem( $params2, Util::$CUTYPE, Util::$INDIVIDUAL );
Util::existRem( $params2, Util::$PARTSTAT, Util::$NEEDS_ACTION );
Util::existRem( $params2, Util::$ROLE, Util::$REQ_PARTICIPANT );
Util::existRem( $params2, Util::$RSVP, Util::$false );
// check language setting
if( isset( $params2[Util::$CN] ) &&
! isset( $params2[Util::$LANGUAGE] ) &&
! empty( $lang )) {
$params2[Util::$LANGUAGE] = $lang;
}
return $params2;
}
}

View File

@@ -0,0 +1,613 @@
<?php
/**
* iCalcreator, the PHP class package managing iCal (rfc2445/rfc5445) calendar information.
*
* copyright (c) 2007-2019 Kjell-Inge Gustafsson, kigkonsult, All rights reserved
* Link https://kigkonsult.se
* Package iCalcreator
* Version 2.26.8
* License Subject matter of licence is the software iCalcreator.
* The above copyright, link, package and version notices,
* this licence notice and the invariant [rfc5545] PRODID result use
* as implemented and invoked in iCalcreator shall be included in
* all copies or substantial portions of the iCalcreator.
*
* iCalcreator 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 3 of the License,
* or (at your option) any later version.
*
* iCalcreator 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 iCalcreator. If not, see <https://www.gnu.org/licenses/>.
*
* This file is a part of iCalcreator.
*/
namespace Kigkonsult\Icalcreator\Util;
use DateInterval;
use DateTime;
use Exception;
use function array_key_exists;
use function ctype_digit;
use function date;
use function explode;
use function floor;
use function mktime;
use function strcasecmp;
use function strlen;
use function strtoupper;
use function substr;
use function trim;
/**
* iCalcreator duration utility/support class
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.26.8 - 2018-12-12
*/
class UtilDuration
{
/**
* Class constant
*/
const INTERVAL_ISO8601 = 'P%yY%mM%dDT%hH%iM%sS';
/**
* @var string iCal TRIGGER param keywords
* @static
*/
public static $RELATED = 'RELATED';
public static $START = 'START';
public static $END = 'END';
public static $RELATEDSTART = 'relatedStart';
public static $BEFORE = 'before';
/**
* @var string duration keys etc
* @access private
* @static
*/
private static $Y = 'Y';
private static $T = 'T';
private static $W = 'W';
private static $D = 'D';
private static $H = 'H';
private static $M = 'M';
private static $S = 'S';
private static $PT0H0M0S = 'PT0H0M0S';
/**
* @var string misc
* @static
*/
public static $P = 'P';
public static $PREFIXARR = [ 'P', '+', '-' ];
/**
* Return DateInterval as string
*
* @param DateInterval $dateInterval
* @param bool $showOptSign
* @return string
* @static
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.16.7 - 2018-11-26
*/
public static function dateInterval2String( DateInterval $dateInterval, $showOptSign=false ) {
$result = UtilDuration::$P;
if( 0 < $dateInterval->y ) {
$result .= $dateInterval->y . UtilDuration::$Y;
}
if( 0 < $dateInterval->m ) {
$result .= $dateInterval->m . UtilDuration::$M;
}
if( 0 < $dateInterval->d ) {
if( empty( $dateInterval->y ) && empty( $dateInterval->m ) && ( 0 == ( $dateInterval->d % 7 ))) {
$result .= (int) floor( $dateInterval->d / 7 ) . UtilDuration::$W;
}
else {
$result .= $dateInterval->d . UtilDuration::$D;
}
}
if( empty( $dateInterval->h ) && empty( $dateInterval->i ) && empty( $dateInterval->s )) {
if( UtilDuration::$P == $result ) {
$result = UtilDuration::$PT0H0M0S;
}
return ( $showOptSign && ( 0 < $dateInterval->invert )) ? Util::$MINUS . $result : $result;
}
$result .= UtilDuration::$T;
if( 0 < $dateInterval->h ) {
$result .= $dateInterval->h . UtilDuration::$H;
}
if( 0 < $dateInterval->i ) {
$result .= $dateInterval->i . UtilDuration::$M;
}
if( 0 < $dateInterval->s ) {
$result .= $dateInterval->s . UtilDuration::$S;
}
return ( $showOptSign && ( 0 < $dateInterval->invert )) ? Util::$MINUS . $result : $result;
}
/**
* Return conform DateInterval
*
* @param DateInterval $dateInterval
* @return DateInterval
* @static
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.16.7 - 2018-11-27
* @todo error mgnt
*/
public static function conformDateInterval( DateInterval $dateInterval ) {
static $NOW = 'now';
try {
$dateTime1 = new DateTime( $NOW );
}
catch( Exception $e ) {
return $dateInterval; // todo error mgnt
}
$dateTime2 = clone $dateTime1;
UtilDuration::modifyDateTimeFromDateInterval( $dateTime2, $dateInterval );
$dateInterval2 = $dateTime1->diff( $dateTime2 );
return ( false !== $dateInterval2 ) ? $dateInterval2 : $dateInterval;
}
/**
* Modify DateTime from DateInterval
*
* @param DateTime $dateTime
* @param DateInterval $dateInterval
* @access private
* @static
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.26.7 - 2018-12-01
*/
private static function modifyDateTimeFromDateInterval(
DateTime $dateTime,
DateInterval $dateInterval ) {
static $PLS = 's';
$operator = ( 0 < $dateInterval->invert ) ? Util::$MINUS : Util::$PLUS;
if( 0 < $dateInterval->y ) {
$plural = ( 1 < $dateInterval->y ) ? $PLS : Util::$SP0;
$dateTime->modify( $operator . $dateInterval->y . Util::$SP1 . Util::$LCYEAR . $plural );
}
if( 0 < $dateInterval->m ) {
$plural = ( 1 < $dateInterval->m ) ? $PLS : Util::$SP0;
$dateTime->modify( $operator . $dateInterval->m . Util::$SP1 . Util::$LCMONTH . $plural );
}
if( 0 < $dateInterval->d ) {
$plural = ( 1 < $dateInterval->d ) ? $PLS : Util::$SP0;
$dateTime->modify( $operator . $dateInterval->d . Util::$SP1 . Util::$LCDAY . $plural );
}
if( 0 < $dateInterval->h ) {
$plural = ( 1 < $dateInterval->h ) ? $PLS : Util::$SP0;
$dateTime->modify( $operator . $dateInterval->h . Util::$SP1 . Util::$LCHOUR . $plural );
}
if( 0 < $dateInterval->i ) {
$plural = ( 1 < $dateInterval->i ) ? $PLS : Util::$SP0;
$dateTime->modify( $operator . $dateInterval->i . Util::$SP1 . Util::$LCMIN . $plural );
}
if( 0 < $dateInterval->s ) {
$plural = ( 1 < $dateInterval->s ) ? $PLS : Util::$SP0;
$dateTime->modify( $operator . $dateInterval->s . Util::$SP1 . Util::$LCSEC . $plural );
}
}
/**
* Modify DateTime from DateInterval
*
* @param array $dateIntervalArr
* @return DateInterval
* @static
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.26.7 - 2018-12-01
*/
public static function DateIntervalArr2DateInterval( array $dateIntervalArr ) {
try {
$dateInterval = new DateInterval( 'P0D' );
}
catch( Exception $e ) { // ??
// todo
}
foreach( $dateIntervalArr as $key => $value ) {
$dateInterval->{$key} = $value;
}
return $dateInterval;
}
/**
* Return datetime array (in internal format) for startdate + DateInterval
*
* @param array $startDate
* @param DateInterval $dateInterval
* @return array, date format
* @static
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.26.7 - 2018-11-26
*/
public static function dateInterval2date( array $startDate, DateInterval $dateInterval ) {
static $FMT = 'Y-m-d H:i:s';
$dateOnly = (
isset( $startDate[Util::$LCHOUR] ) ||
isset( $startDate[Util::$LCMIN] ) ||
isset( $startDate[Util::$LCSEC] )) ? false : true;
if( ! isset( $startDate[Util::$LCHOUR] )) {
$startDate[Util::$LCHOUR] = 0;
}
if( ! isset( $startDate[Util::$LCMIN] )) {
$startDate[Util::$LCMIN] = 0;
}
if( ! isset( $startDate[Util::$LCSEC] )) {
$startDate[Util::$LCSEC] = 0;
}
$tz = ( isset( $startDate[Util::$LCtz] )) ? $startDate[Util::$LCtz] : null;
$dateTime = DateTime::createFromFormat(
$FMT,
Util::getYMDHISEString( $startDate )
);
UtilDuration::modifyDateTimeFromDateInterval( $dateTime, $dateInterval );
$dateTimeArr = Util::dateTime2Arr( $dateTime, [], false );
$dateTimeArr = $dateTimeArr[Util::$LCvalue];
if( ! empty( $tz )) {
$dateTimeArr[Util::$LCtz] = $tz;
}
if( $dateOnly &&
(( 0 == $dateTimeArr[Util::$LCHOUR] ) &&
( 0 == $dateTimeArr[Util::$LCMIN] ) &&
( 0 == $dateTimeArr[Util::$LCSEC] ))) {
unset( $dateTimeArr[Util::$LCHOUR], $dateTimeArr[Util::$LCMIN], $dateTimeArr[Util::$LCSEC] );
}
return $dateTimeArr;
}
/**
* Return DateInterval as (extrnal) array
*
* @param DateInterval $dateInterval
* @return array
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.16.7 - 2018-12-04
*/
public static function dateInterval2arr( DateInterval $dateInterval ) {
$result = [];
if( 0 < $dateInterval->y ) {
$result[Util::$LCYEAR] = $dateInterval->y;
}
if( 0 < $dateInterval->m ) {
$result[Util::$LCMONTH] = $dateInterval->m;
}
if( 0 < $dateInterval->d ) {
$result[Util::$LCDAY] = $dateInterval->d;
}
if( 0 < $dateInterval->h ) {
$result[Util::$LCHOUR] = $dateInterval->h;
}
if( 0 < $dateInterval->i ) {
$result[Util::$LCMIN] = $dateInterval->i;
}
if( 0 < $dateInterval->s ) {
$result[Util::$LCSEC] = $dateInterval->s;
}
// separate duration (arr) from datetime (arr)
if( ! UtilDuration::issetAndNotEmpty( $result, Util::$LCWEEK )) {
$result[Util::$LCWEEK] = 0;
}
return $result;
}
/**
* Return array (in internal format) for a (array) duration (only W+D+HMS)
*
* @param array $duration
* @return array
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.16.7 - 2018-11-26
* @todo error mgnt
*/
public static function duration2arr( $duration ) {
$dateTime1 = new DateTime();
$dateTime2 = clone $dateTime1;
foreach( $duration as $durKey => $durValue ) {
if( empty( $durValue )) {
continue;
}
switch( $durKey ) {
case Util::$ZERO:
case Util::$LCWEEK:
$durValue *= 7;
$dateTime2->modify( Util::$PLUS . $durValue . Util::$SP1 . Util::$LCDAY );
break;
case '1':
case Util::$LCDAY:
$dateTime2->modify( Util::$PLUS . $durValue . Util::$SP1 . Util::$LCDAY );
break;
case '2':
case Util::$LCHOUR:
$dateTime2->modify( Util::$PLUS . $durValue . Util::$SP1 . Util::$LCHOUR );
break;
case '3':
case Util::$LCMIN:
$dateTime2->modify( Util::$PLUS . $durValue . Util::$SP1 . Util::$LCMIN );
break;
case '4':
case Util::$LCSEC:
$dateTime2->modify( Util::$PLUS . $durValue . Util::$SP1 . Util::$LCSEC );
break;
}
}
$diffStr = UtilDuration::dateInterval2String( $dateTime1->diff( $dateTime2 ));
$result = UtilDuration::durationStr2arr( $diffStr, false );
if( ! UtilDuration::issetAndNotEmpty( $result, Util::$LCYEAR ) &&
! UtilDuration::issetAndNotEmpty( $result, Util::$LCMONTH ) &&
UtilDuration::issetAndNotEmpty( $result, Util::$LCDAY ) &&
( 7 <= $result[Util::$LCDAY] )) {
$weeks = (int) floor( $result[Util::$LCDAY] / 7 );
if( 1 <= $weeks ) {
$result[Util::$LCWEEK] = $weeks;
$days = $result[Util::$LCDAY] % 7;
if( 0 < $days ) {
$result[Util::$LCDAY] = $days;
}
else {
unset( $result[Util::$LCDAY] );
}
}
}
if( empty( $result[Util::$LCYEAR] ) && empty( $result[Util::$LCMONTH] )) {
unset( $result[Util::$LCYEAR], $result[Util::$LCMONTH] );
}
if( empty( $result[Util::$LCDAY] )) {
unset( $result[Util::$LCDAY] );
}
if( empty( $result[Util::$LCHOUR] ) && empty( $result[Util::$LCMIN] ) && empty( $result[Util::$LCSEC] )) {
unset( $result[Util::$LCHOUR], $result[Util::$LCMIN], $result[Util::$LCSEC] );
}
// separate duration (arr) from datetime (arr)
if( ! UtilDuration::issetAndNotEmpty( $result, Util::$LCWEEK )) {
$result[Util::$LCWEEK] = 0;
}
return $result;
}
/**
* Return datetime array (in internal format) for startdate + duration
*
* @param array $startDate
* @param array $duration
* @return array, date format
* @static
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.26.7 - 2018-11-26
*/
public static function duration2date( $startDate, $duration ) {
$dateOnly = (
isset( $startDate[Util::$LCHOUR] ) ||
isset( $startDate[Util::$LCMIN] ) ||
isset( $startDate[Util::$LCSEC] )) ? false : true;
$startDate[Util::$LCHOUR] = ( isset( $startDate[Util::$LCHOUR] ))
? $startDate[Util::$LCHOUR] : 0;
$startDate[Util::$LCMIN] = ( isset( $startDate[Util::$LCMIN] ))
? $startDate[Util::$LCMIN] : 0;
$startDate[Util::$LCSEC] = ( isset( $startDate[Util::$LCSEC] ))
? $startDate[Util::$LCSEC] : 0;
if( UtilDuration::issetAndNotEmpty( $duration, Util::$LCYEAR )) {
$startDate[Util::$LCYEAR] += $duration[Util::$LCYEAR];
}
if( UtilDuration::issetAndNotEmpty( $duration, Util::$LCMONTH )) {
$startDate[Util::$LCMONTH] += $duration[Util::$LCMONTH];
}
if( UtilDuration::issetAndNotEmpty( $duration, Util::$LCWEEK )) {
$startDate[Util::$LCDAY] += ( $duration[Util::$LCWEEK] * 7 );
}
if( UtilDuration::issetAndNotEmpty( $duration, Util::$LCDAY )) {
$startDate[Util::$LCDAY] += $duration[Util::$LCDAY];
}
if( UtilDuration::issetAndNotEmpty( $duration, Util::$LCHOUR )) {
$startDate[Util::$LCHOUR] += $duration[Util::$LCHOUR];
}
if( UtilDuration::issetAndNotEmpty( $duration, Util::$LCMIN )) {
$startDate[Util::$LCMIN] += $duration[Util::$LCMIN];
}
if( UtilDuration::issetAndNotEmpty( $duration, Util::$LCSEC )) {
$startDate[Util::$LCSEC] += $duration[Util::$LCSEC];
}
$date = date(
Util::$YMDHIS3,
mktime(
(int) $startDate[Util::$LCHOUR],
(int) $startDate[Util::$LCMIN],
(int) $startDate[Util::$LCSEC],
(int) $startDate[Util::$LCMONTH],
(int) $startDate[Util::$LCDAY],
(int) $startDate[Util::$LCYEAR]
)
);
$d = explode( Util::$MINUS, $date );
$dtEnd2 = [
Util::$LCYEAR => $d[0],
Util::$LCMONTH => $d[1],
Util::$LCDAY => $d[2],
Util::$LCHOUR => $d[3],
Util::$LCMIN => $d[4],
Util::$LCSEC => $d[5],
];
if( isset( $startDate[Util::$LCtz] )) {
$dtEnd2[Util::$LCtz] = $startDate[Util::$LCtz];
}
if( $dateOnly &&
(( 0 == $dtEnd2[Util::$LCHOUR] ) &&
( 0 == $dtEnd2[Util::$LCMIN] ) &&
( 0 == $dtEnd2[Util::$LCSEC] ))) {
unset( $dtEnd2[Util::$LCHOUR], $dtEnd2[Util::$LCMIN], $dtEnd2[Util::$LCSEC] );
}
return $dtEnd2;
}
/**
* Return an iCal formatted string from (internal array) duration
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.26.7 - 2018-11-26
* @param array $duration , array( year, month, day, week, day, hour, min, sec )
* @return string
* @static
*/
public static function duration2str( array $duration ) {
if( ! isset( $duration[Util::$LCYEAR] ) &&
! isset( $duration[Util::$LCMONTH] ) &&
! isset( $duration[Util::$LCDAY] ) &&
! isset( $duration[Util::$LCWEEK] ) &&
! isset( $duration[Util::$LCHOUR] ) &&
! isset( $duration[Util::$LCMIN] ) &&
! isset( $duration[Util::$LCSEC] )) {
return null;
}
if( UtilDuration::issetAndNotEmpty( $duration, Util::$LCWEEK )) {
$result = UtilDuration::$P . $duration[Util::$LCWEEK] . UtilDuration::$W;
}
else {
$result = UtilDuration::$P;
if( UtilDuration::issetAndNotEmpty( $duration, Util::$LCYEAR ) ) {
$result .= $duration[Util::$LCYEAR] . UtilDuration::$Y;
}
if( UtilDuration::issetAndNotEmpty( $duration, Util::$LCMONTH ) ) {
$result .= $duration[Util::$LCMONTH] . UtilDuration::$M;
}
}
if( UtilDuration::issetAndNotEmpty( $duration, Util::$LCDAY )) {
$result .= $duration[Util::$LCDAY] . UtilDuration::$D;
}
$hourIsSet = ( UtilDuration::issetAndNotEmpty( $duration, Util::$LCHOUR ));
$minIsSet = ( UtilDuration::issetAndNotEmpty( $duration, Util::$LCMIN ));
$secIsSet = ( UtilDuration::issetAndNotEmpty( $duration, Util::$LCSEC ));
if( $hourIsSet || $minIsSet || $secIsSet ) {
$result .= UtilDuration::$T;
}
if( $hourIsSet ) {
$result .= $duration[Util::$LCHOUR] . UtilDuration::$H;
}
if( $minIsSet ) {
$result .= $duration[Util::$LCMIN] . UtilDuration::$M;
}
if( $secIsSet ) {
$result .= $duration[Util::$LCSEC] . UtilDuration::$S;
}
if( UtilDuration::$P == $result ) {
$result = UtilDuration::$PT0H0M0S;
}
return $result;
}
/**
* Return array (in internal format) from string duration
*
* @param string $duration
* @param bool $reCheck
* @return array|bool false on error
* @static
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.26.7 - 2018-11-26
*/
public static function durationStr2arr( $duration, $reCheck=true ) {
$duration = (string) trim( $duration );
while( 0 != strcasecmp( UtilDuration::$P, $duration[0] )) {
if( 0 < strlen( $duration )) {
$duration = substr( $duration, 1 );
}
else {
return false;
} // no leading P !?!?
}
$duration = substr( $duration, 1 ); // skip P
$result = [];
$val = null;
$timePart = false;
$durLen = strlen( $duration );
for( $ix = 0; $ix < $durLen; $ix++ ) {
switch( strtoupper( $duration[$ix] )) {
case UtilDuration::$Y :
if( ! empty( $val )) {
$result[Util::$LCYEAR] = $val;
}
$val = null;
break;
case UtilDuration::$W :
if( ! empty( $val )) {
$result[Util::$LCWEEK] = $val;
}
$val = null;
break;
case UtilDuration::$D :
if( ! empty( $val )) {
$result[Util::$LCDAY] = $val;
}
$val = null;
break;
case UtilDuration::$T :
$timePart = true;
$val = null;
break;
case UtilDuration::$H :
if( ! empty( $val )) {
$result[Util::$LCHOUR] = $val;
}
$val = null;
break;
case UtilDuration::$M :
if( ! empty( $val )) {
if( ! $timePart ) {
$result[Util::$LCMONTH] = $val;
}
else {
$result[Util::$LCMIN] = $val;
}
}
$val = null;
break;
case UtilDuration::$S :
if( ! empty( $val )) {
$result[Util::$LCSEC] = $val;
}
$val = null;
break;
default:
if( ! ctype_digit( $duration[$ix] )) {
return false;
} // unknown duration control character !?!?
else {
$val .= $duration[$ix];
}
}
}
// separate duration (arr) from datetime (arr)
if( ! isset( $result[Util::$LCWEEK] )) {
$result[Util::$LCWEEK] = 0;
}
return ( $reCheck) ? UtilDuration::duration2arr( $result ) : $result ;
}
/**
* Return bool true if value is isset and not empty
*
* @param array $array
* @param string $key
* @return bool
* @static
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.26.7 - 2018-11-26
*/
private static function issetAndNotEmpty( array $array, $key ) {
if( ! array_key_exists( $key, $array )) {
return false;
}
return ( isset( $array[$key] ) && ! empty( $array[$key] ));
}
}

View File

@@ -0,0 +1,73 @@
<?php
/**
* iCalcreator, the PHP class package managing iCal (rfc2445/rfc5445) calendar information.
*
* copyright (c) 2007-2019 Kjell-Inge Gustafsson, kigkonsult, All rights reserved
* Link https://kigkonsult.se
* Package iCalcreator
* Version 2.26.8
* License Subject matter of licence is the software iCalcreator.
* The above copyright, link, package and version notices,
* this licence notice and the invariant [rfc5545] PRODID result use
* as implemented and invoked in iCalcreator shall be included in
* all copies or substantial portions of the iCalcreator.
*
* iCalcreator 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 3 of the License,
* or (at your option) any later version.
*
* iCalcreator 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 iCalcreator. If not, see <https://www.gnu.org/licenses/>.
*
* This file is a part of iCalcreator.
*/
namespace Kigkonsult\Icalcreator\Util;
use function abs;
use function sprintf;
use function rtrim;
/**
* iCalcreator geo support class
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.26 - 2018-11-10
*/
class UtilGeo
{
/**
* @var string GEO vars: output format for geo latitude and longitude (before rtrim) etc
* @access public
* @static
*/
public static $geoLatFmt = '%09.6f';
public static $geoLongFmt = '%8.6f';
public static $LATITUDE = 'latitude';
public static $LONGITUDE = 'longitude';
/**
* Return formatted geo output
*
* @param float $ll
* @param string $format
* @return string
* @access public
* @static
*/
public static function geo2str2( $ll, $format ) {
if( 0.0 < $ll ) {
$sign = Util::$PLUS;
}
else {
$sign = ( 0.0 > $ll ) ? Util::$MINUS : null;
}
return rtrim( rtrim( $sign . sprintf( $format, abs( $ll )), Util::$ZERO ), Util::$DOT );
}
}

View File

@@ -0,0 +1,984 @@
<?php
/**
* iCalcreator, the PHP class package managing iCal (rfc2445/rfc5445) calendar information.
*
* copyright (c) 2007-2019 Kjell-Inge Gustafsson, kigkonsult, All rights reserved
* Link https://kigkonsult.se
* Package iCalcreator
* Version 2.26.8
* License Subject matter of licence is the software iCalcreator.
* The above copyright, link, package and version notices,
* this licence notice and the invariant [rfc5545] PRODID result use
* as implemented and invoked in iCalcreator shall be included in
* all copies or substantial portions of the iCalcreator.
*
* iCalcreator 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 3 of the License,
* or (at your option) any later version.
*
* iCalcreator 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 iCalcreator. If not, see <https://www.gnu.org/licenses/>.
*
* This file is a part of iCalcreator.
*/
namespace Kigkonsult\Icalcreator\Util;
use DateTime;
use DateTimeZone;
use function array_change_key_case;
use function array_keys;
use function checkdate;
use function count;
use function ctype_digit;
use function date;
use function end;
use function get_class;
use function implode;
use function in_array;
use function is_array;
use function is_null;
use function is_string;
use function mktime;
use function sprintf;
use function strcasecmp;
use function strlen;
use function strtoupper;
use function substr;
use function trim;
use function usort;
/**
* iCalcreator recur support class
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.26 - 2018-11-10
*/
class UtilRecur
{
/**
* Static values for recurrence FREQuence
*
* @access private
* @static
*/
private static $DAILY = 'DAILY';
private static $WEEKLY = 'WEEKLY';
private static $MONTHLY = 'MONTHLY';
private static $YEARLY = 'YEARLY';
//private static $SECONDLY = 'SECONDLY';
//private static $MINUTELY = 'MINUTELY';
//private static $HOURLY = 'HOURLY';
private static $DAYNAMES = [ 'SU', 'MO', 'TU', 'WE', 'TH', 'FR', 'SA' ];
private static $YEARCNT_UP = 'yearcnt_up';
private static $YEARCNT_DOWN = 'yearcnt_down';
private static $MONTHDAYNO_UP = 'monthdayno_up';
private static $MONTHDAYNO_DOWN = 'monthdayno_down';
private static $MONTHCNT_DOWN = 'monthcnt_down';
private static $YEARDAYNO_UP = 'yeardayno_up';
private static $YEARDAYNO_DOWN = 'yeardayno_down';
private static $WEEKNO_UP = 'weekno_up';
private static $WEEKNO_DOWN = 'weekno_down';
/**
* Sort recur dates
*
* @param string $byDayA
* @param string $byDayB
* @return int
* @access private
* @static
*/
private static function recurBydaySort( $byDayA, $byDayB ) {
static $days = [
'SU' => 0,
'MO' => 1,
'TU' => 2,
'WE' => 3,
'TH' => 4,
'FR' => 5,
'SA' => 6,
];
return ( $days[substr( $byDayA, -2 )] < $days[substr( $byDayB, -2 )] ) ? -1 : 1;
}
/**
* Return formatted output for calendar component property data value type recur
*
* @param string $recurlabel
* @param array $recurData
* @param bool $allowEmpty
* @return string
* @static
*/
public static function formatRecur( $recurlabel, $recurData, $allowEmpty ) {
static $FMTFREQEQ = 'FREQ=%s';
static $FMTDEFAULTEQ = ';%s=%s';
static $FMTOTHEREQ = ';%s=';
static $RECURBYDAYSORTER = null;
if( is_null( $RECURBYDAYSORTER )) {
$RECURBYDAYSORTER = [ get_class(), 'recurBydaySort' ];
}
if( empty( $recurData )) {
return null;
}
$output = null;
foreach( $recurData as $rx => $theRule ) {
if( empty( $theRule[Util::$LCvalue] )) {
if( $allowEmpty ) {
$output .= Util::createElement( $recurlabel );
}
continue;
}
$attributes = ( isset( $theRule[Util::$LCparams] ))
? Util::createParams( $theRule[Util::$LCparams] )
: null;
$content1 = $content2 = null;
foreach( $theRule[Util::$LCvalue] as $ruleLabel => $ruleValue ) {
$ruleLabel = strtoupper( $ruleLabel );
switch( $ruleLabel ) {
case Util::$FREQ :
$content1 .= sprintf( $FMTFREQEQ, $ruleValue );
break;
case Util::$UNTIL :
$parno = ( isset( $ruleValue[Util::$LCHOUR] )) ? 7 : 3;
$content2 .= sprintf( $FMTDEFAULTEQ, Util::$UNTIL,
Util::date2strdate( $ruleValue, $parno )
);
break;
case Util::$COUNT :
case Util::$INTERVAL :
case Util::$WKST :
$content2 .= sprintf( $FMTDEFAULTEQ, $ruleLabel, $ruleValue );
break;
case Util::$BYDAY :
$byday = [ Util::$SP0 ];
$bx = 0;
foreach( $ruleValue as $bix => $bydayPart ) {
if( ! empty( $byday[$bx] ) && // new day
! ctype_digit( substr( $byday[$bx], -1 )) ) {
$byday[++$bx] = Util::$SP0;
}
if( ! is_array( $bydayPart )) // day without order number
{
$byday[$bx] .= (string) $bydayPart;
}
else { // day with order number
foreach( $bydayPart as $bix2 => $bydayPart2 ) {
$byday[$bx] .= (string) $bydayPart2;
}
}
} // end foreach( $ruleValue as $bix => $bydayPart )
if( 1 < count( $byday )) {
usort( $byday, $RECURBYDAYSORTER );
}
$content2 .= sprintf( $FMTDEFAULTEQ, Util::$BYDAY, implode( Util::$COMMA, $byday ));
break;
default : // BYSECOND/BYMINUTE/BYHOUR/BYMONTHDAY/BYYEARDAY/BYWEEKNO/BYMONTH/BYSETPOS...
if( is_array( $ruleValue )) {
$content2 .= sprintf( $FMTOTHEREQ, $ruleLabel );
$content2 .= implode( Util::$COMMA, $ruleValue );
}
else {
$content2 .= sprintf( $FMTDEFAULTEQ, $ruleLabel, $ruleValue );
}
break;
} // end switch( $ruleLabel )
} // end foreach( $theRule[Util::$LCvalue] )) as $ruleLabel => $ruleValue )
$output .= Util::createElement( $recurlabel, $attributes, $content1 . $content2 );
} // end foreach( $recurData as $rx => $theRule )
return $output;
}
/**
* Convert input format for EXRULE and RRULE to internal format
*
* @param array $rexrule
* @return array
* @static
* @since 2.26.7 - 2018-11-23
*/
public static function setRexrule( $rexrule ) {
static $BYSECOND = 'BYSECOND';
static $BYMINUTE = 'BYMINUTE';
static $BYHOUR = 'BYHOUR';
$input = [];
if( empty( $rexrule )) {
return $input;
}
$rexrule = array_change_key_case( $rexrule, CASE_UPPER );
foreach( $rexrule as $rexruleLabel => $rexruleValue ) {
if( Util::$UNTIL != $rexruleLabel ) {
$input[$rexruleLabel] = $rexruleValue;
}
else {
if( $rexruleValue instanceof DateTime ) {
$rexruleValue->setTimezone((new DateTimeZone( Util::$UTC ))); // ensure UTC
$rexruleValue = Util::dateTime2Str( $rexruleValue );
}
else {
Util::strDate2arr( $rexruleValue );
}
if( Util::isArrayTimestampDate( $rexruleValue )) { // timestamp, always date-time UTC
$input[$rexruleLabel] = Util::timestamp2date( $rexruleValue, 7, Util::$UTC );
}
elseif( Util::isArrayDate( $rexruleValue )) { // date or UTC date-time
$parno = ( isset( $rexruleValue[Util::$LCHOUR] ) ||
isset( $rexruleValue[4] )) ? 7 : 3;
$d = Util::chkDateArr( $rexruleValue, $parno );
if(( 3 < $parno ) &&
isset( $d[Util::$LCtz] ) &&
( Util::$Z != $d[Util::$LCtz] ) &&
Util::isOffset( $d[Util::$LCtz] )) {
$input[$rexruleLabel] = Util::ensureArrDatetime( [Util::$LCvalue => $d], $d[Util::$LCtz],7 );
unset( $input[$rexruleLabel][Util::$UNPARSEDTEXT] );
}
else {
$input[$rexruleLabel] = $d;
}
}
elseif( 8 <= strlen( trim( $rexruleValue )) ) { // ex. textual date-time 2006-08-03 10:12:18 => UTC
$input[$rexruleLabel] = Util::strDate2ArrayDate( $rexruleValue );
unset( $input[$rexruleLabel][Util::$UNPARSEDTEXT] );
}
if(( 3 < count( $input[$rexruleLabel] )) &&
! isset( $input[$rexruleLabel][Util::$LCtz] )) {
$input[$rexruleLabel][Util::$LCtz] = Util::$Z;
}
}
} // end foreach( $rexrule as $rexruleLabel => $rexruleValue )
/* set recurrence rule specification in rfc2445 order */
$input2 = [];
if( isset( $input[Util::$FREQ] )) {
$input2[Util::$FREQ] = $input[Util::$FREQ];
}
if( isset( $input[Util::$UNTIL] )) {
$input2[Util::$UNTIL] = $input[Util::$UNTIL];
}
elseif( isset( $input[Util::$COUNT] )) {
$input2[Util::$COUNT] = $input[Util::$COUNT];
}
if( isset( $input[Util::$INTERVAL] )) {
$input2[Util::$INTERVAL] = $input[Util::$INTERVAL];
}
if( isset( $input[$BYSECOND] )) {
$input2[$BYSECOND] = $input[$BYSECOND];
}
if( isset( $input[$BYMINUTE] )) {
$input2[$BYMINUTE] = $input[$BYMINUTE];
}
if( isset( $input[$BYHOUR] )) {
$input2[$BYHOUR] = $input[$BYHOUR];
}
if( isset( $input[Util::$BYDAY] )) {
if( ! is_array( $input[Util::$BYDAY] )) { // ensure upper case.. .
$input2[Util::$BYDAY] = \strtoupper( $input[Util::$BYDAY] );
}
else {
foreach( $input[Util::$BYDAY] as $BYDAYx => $BYDAYv ) {
if( 0 == strcasecmp( Util::$DAY, $BYDAYx )) {
$input2[Util::$BYDAY][Util::$DAY] = strtoupper( $BYDAYv );
}
elseif( ! is_array( $BYDAYv )) {
$input2[Util::$BYDAY][$BYDAYx] = $BYDAYv;
}
else {
foreach( $BYDAYv as $BYDAYx2 => $BYDAYv2 ) {
if( 0 == strcasecmp( Util::$DAY, $BYDAYx2 )) {
$input2[Util::$BYDAY][$BYDAYx][Util::$DAY] = strtoupper( $BYDAYv2 );
}
else {
$input2[Util::$BYDAY][$BYDAYx][$BYDAYx2] = $BYDAYv2;
}
}
}
}
}
} // end if( isset( $input[Util::$BYDAY] ))
if( isset( $input[Util::$BYMONTHDAY] )) {
$input2[Util::$BYMONTHDAY] = $input[Util::$BYMONTHDAY];
}
if( isset( $input[Util::$BYYEARDAY] )) {
$input2[Util::$BYYEARDAY] = $input[Util::$BYYEARDAY];
}
if( isset( $input[Util::$BYWEEKNO] )) {
$input2[Util::$BYWEEKNO] = $input[Util::$BYWEEKNO];
}
if( isset( $input[Util::$BYMONTH] )) {
$input2[Util::$BYMONTH] = $input[Util::$BYMONTH];
}
if( isset( $input[Util::$BYSETPOS] )) {
$input2[Util::$BYSETPOS] = $input[Util::$BYSETPOS];
}
if( isset( $input[Util::$WKST] )) {
$input2[Util::$WKST] = $input[Util::$WKST];
}
return $input2;
}
/**
* Update array $result with dates based on a recur pattern
*
* If missing, UNTIL is set 1 year from startdate (emergency break)
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.26 - 2018-11-10
* @param array $result array to update, array([Y-m-d] => bool)
* @param array $recur pattern for recurrency (only value part, params ignored)
* @param mixed $wDate component start date, string / array / (datetime) obj
* @param mixed $fcnStart start date, string / array / (datetime) obj
* @param mixed $fcnEnd end date, string / array / (datetime) obj
* @static
* @todo BYHOUR, BYMINUTE, BYSECOND, WEEKLY at year end/start OR not at all
*/
public static function recur2date(
& $result,
$recur,
$wDate,
$fcnStart,
$fcnEnd = false
) {
static $YEAR2DAYARR = [ 'YEARLY', 'MONTHLY', 'WEEKLY', 'DAILY' ];
static $SU = 'SU';
static $HIS = '%02d%02d%02d';
self::reFormatDate( $wDate );
$wDateYMD = Util::getYMDString( $wDate );
$wDateHis = Util::getHisString( $wDate );
$untilHis = $wDateHis;
self::reFormatDate( $fcnStart );
$fcnStartYMD = Util::getYMDString( $fcnStart );
if( ! empty( $fcnEnd )) {
self::reFormatDate( $fcnEnd );
}
else {
$fcnEnd = $fcnStart;
$fcnEnd[Util::$LCYEAR] += 1;
}
$fcnEndYMD = Util::getYMDString( $fcnEnd );
if( ! isset( $recur[Util::$COUNT] ) && ! isset( $recur[Util::$UNTIL] )) {
$recur[Util::$UNTIL] = $fcnEnd;
} // create break
if( isset( $recur[Util::$UNTIL] )) {
foreach( $recur[Util::$UNTIL] as $k => $v ) {
if( ctype_digit( $v )) {
$recur[Util::$UNTIL][$k] = (int) $v;
}
}
unset( $recur[Util::$UNTIL][Util::$LCtz] );
if( $fcnEnd > $recur[Util::$UNTIL] ) {
$fcnEnd = $recur[Util::$UNTIL]; // emergency break
$fcnEndYMD = Util::getYMDString( $fcnEnd );
}
if( isset( $recur[Util::$UNTIL][Util::$LCHOUR] )) {
$untilHis = Util::getHisString( $recur[Util::$UNTIL] );
}
else {
$untilHis = sprintf( $HIS, 23, 59, 59 );
}
} // end if( isset( $recur[Util::$UNTIL] ))
if( $wDateYMD > $fcnEndYMD ) {
return []; // nothing to do.. .
}
if( ! isset( $recur[Util::$FREQ] )) { // "MUST be specified.. ."
$recur[Util::$FREQ] = self::$DAILY;
} // ??
$wkst = ( isset( $recur[Util::$WKST] ) && ( $SU == $recur[Util::$WKST] )) ? 24 * 60 * 60 : 0; // ??
if( ! isset( $recur[Util::$INTERVAL] )) {
$recur[Util::$INTERVAL] = 1;
}
$recurCount = ( ! isset( $recur[Util::$BYSETPOS] )) ? 1 : 0; // DTSTART \counts as the first occurrence
/* find out how to step up dates and set index for interval \count */
$step = [];
if( self::$YEARLY == $recur[Util::$FREQ] ) {
$step[Util::$LCYEAR] = 1;
}
elseif( self::$MONTHLY == $recur[Util::$FREQ] ) {
$step[Util::$LCMONTH] = 1;
}
elseif( self::$WEEKLY == $recur[Util::$FREQ] ) {
$step[Util::$LCDAY] = 7;
}
else {
$step[Util::$LCDAY] = 1;
}
if( isset( $step[Util::$LCYEAR] ) && isset( $recur[Util::$BYMONTH] )) {
$step = [ Util::$LCMONTH => 1 ];
}
if( empty( $step ) && isset( $recur[Util::$BYWEEKNO] )) { // ??
$step = [ Util::$LCDAY => 7 ];
}
if( isset( $recur[Util::$BYYEARDAY] ) ||
isset( $recur[Util::$BYMONTHDAY] ) ||
isset( $recur[Util::$BYDAY] )) {
$step = [ Util::$LCDAY => 1 ];
}
$intervalArr = [];
if( 1 < $recur[Util::$INTERVAL] ) {
$intervalIx = self::recurIntervalIx( $recur[Util::$FREQ], $wDate, $wkst );
$intervalArr = [ $intervalIx => 0 ];
}
if( isset( $recur[Util::$BYSETPOS] )) { // save start date + weekno
$bysetPosymd1 = $bysetPosymd2 = $bysetPosw1 = $bysetPosw2 = [];
if( is_array( $recur[Util::$BYSETPOS] )) {
foreach( $recur[Util::$BYSETPOS] as $bix => $bval ) {
$recur[Util::$BYSETPOS][$bix] = (int) $bval;
}
}
else {
$recur[Util::$BYSETPOS] = [ (int) $recur[Util::$BYSETPOS] ];
}
if( self::$YEARLY == $recur[Util::$FREQ] ) {
$wDate[Util::$LCMONTH] = $wDate[Util::$LCDAY] = 1; // start from beginning of year
$wDateYMD = Util::getYMDString( $wDate );
self::stepDate( $fcnEnd, $fcnEndYMD, [ Util::$LCYEAR => 1 ] ); // make sure to \count last year
}
elseif( self::$MONTHLY == $recur[Util::$FREQ] ) {
$wDate[Util::$LCDAY] = 1; // start from beginning of month
$wDateYMD = Util::getYMDString( $wDate );
self::stepDate( $fcnEnd, $fcnEndYMD, [ Util::$LCMONTH => 1 ] ); // make sure to \count last month
}
else {
self::stepDate( $fcnEnd, $fcnEndYMD, $step );
} // make sure to \count whole last period
$bysetPosWold = self::getWeeNumber(0,0, $wkst, $wDate[Util::$LCMONTH], $wDate[Util::$LCDAY], $wDate[Util::$LCYEAR] );
$bysetPosYold = $wDate[Util::$LCYEAR];
$bysetPosMold = $wDate[Util::$LCMONTH];
$bysetPosDold = $wDate[Util::$LCDAY];
} // end if( isset( $recur[Util::$BYSETPOS] ))
else {
self::stepDate( $wDate, $wDateYMD, $step );
}
$yearOld = null;
$dayCnts = [];
/* MAIN LOOP */
while( true ) {
if( $wDateYMD . $wDateHis > $fcnEndYMD . $untilHis ) {
break;
}
if( isset( $recur[Util::$COUNT] ) &&
( $recurCount >= $recur[Util::$COUNT] )) {
break;
}
if( $yearOld != $wDate[Util::$LCYEAR] ) { // $yearOld=null 1:st time
$yearOld = $wDate[Util::$LCYEAR];
$dayCnts = self::initDayCnts( $wDate, $recur, $wkst );
}
/* check interval */
if( 1 < $recur[Util::$INTERVAL] ) {
/* create interval index */
$intervalIx = self::recurIntervalIx( $recur[Util::$FREQ], $wDate, $wkst );
/* check interval */
$currentKey = array_keys( $intervalArr );
$currentKey = end( $currentKey ); // get last index
if( $currentKey != $intervalIx ) {
$intervalArr = [ $intervalIx => ( $intervalArr[$currentKey] + 1 ) ];
}
if(( $recur[Util::$INTERVAL] != $intervalArr[$intervalIx] ) &&
( 0 != $intervalArr[$intervalIx] )) {
/* step up date */
self::stepDate( $wDate, $wDateYMD, $step );
continue;
}
else // continue within the selected interval
{
$intervalArr[$intervalIx] = 0;
}
} // endif( 1 < $recur['INTERVAL'] )
$updateOK = true;
if( $updateOK && isset( $recur[Util::$BYMONTH] )) {
$updateOK = self::recurBYcntcheck( $recur[Util::$BYMONTH], $wDate[Util::$LCMONTH],
( $wDate[Util::$LCMONTH] - 13 )
);
}
if( $updateOK && isset( $recur[Util::$BYWEEKNO] )) {
$updateOK = self::recurBYcntcheck(
$recur[Util::$BYWEEKNO],
$dayCnts[$wDate[Util::$LCMONTH]][$wDate[Util::$LCDAY]][self::$WEEKNO_UP],
$dayCnts[$wDate[Util::$LCMONTH]][$wDate[Util::$LCDAY]][self::$WEEKNO_DOWN]
);
}
if( $updateOK && isset( $recur[Util::$BYYEARDAY] )) {
$updateOK = self::recurBYcntcheck(
$recur[Util::$BYYEARDAY],
$dayCnts[$wDate[Util::$LCMONTH]][$wDate[Util::$LCDAY]][self::$YEARCNT_UP],
$dayCnts[$wDate[Util::$LCMONTH]][$wDate[Util::$LCDAY]][self::$YEARCNT_DOWN]
);
}
if( $updateOK && isset( $recur[Util::$BYMONTHDAY] )) {
$updateOK = self::recurBYcntcheck(
$recur[Util::$BYMONTHDAY],
$wDate[Util::$LCDAY],
$dayCnts[$wDate[Util::$LCMONTH]][$wDate[Util::$LCDAY]][self::$MONTHCNT_DOWN]
);
}
if( $updateOK && isset( $recur[Util::$BYDAY] )) {
$updateOK = false;
$m = $wDate[Util::$LCMONTH];
$d = $wDate[Util::$LCDAY];
if( isset( $recur[Util::$BYDAY][Util::$DAY] )) { // single day, opt with year/month day order no
$daynoExists = $daynoSw = $dayNameSw = false;
if( $recur[Util::$BYDAY][Util::$DAY] == $dayCnts[$m][$d][Util::$DAY] ) {
$dayNameSw = true;
}
if( isset( $recur[Util::$BYDAY][0] )) {
$daynoExists = true;
if(( isset( $recur[Util::$FREQ] ) && ( $recur[Util::$FREQ] == self::$MONTHLY )) ||
isset( $recur[Util::$BYMONTH] )) {
$daynoSw = self::recurBYcntcheck(
$recur[Util::$BYDAY][0],
$dayCnts[$m][$d][self::$MONTHDAYNO_UP],
$dayCnts[$m][$d][self::$MONTHDAYNO_DOWN]
);
}
elseif( isset( $recur[Util::$FREQ] ) &&
( $recur[Util::$FREQ] == self::$YEARLY )) {
$daynoSw = self::recurBYcntcheck(
$recur[Util::$BYDAY][0],
$dayCnts[$m][$d][self::$YEARDAYNO_UP],
$dayCnts[$m][$d][self::$YEARDAYNO_DOWN]
);
}
}
if(( $daynoExists && $daynoSw && $dayNameSw ) ||
( ! $daynoExists && ! $daynoSw && $dayNameSw )) {
$updateOK = true;
}
} // end if( isset( $recur[Util::$BYDAY][Util::$DAY] ))
else {
foreach( $recur[Util::$BYDAY] as $bydayvalue ) {
$daynoExists = $daynoSw = $dayNameSw = false;
if( isset( $bydayvalue[Util::$DAY] ) &&
( $bydayvalue[Util::$DAY] == $dayCnts[$m][$d][Util::$DAY] )) {
$dayNameSw = true;
}
if( isset( $bydayvalue[0] )) {
$daynoExists = true;
if(( isset( $recur[Util::$FREQ] ) &&
( $recur[Util::$FREQ] == self::$MONTHLY )) ||
isset( $recur[Util::$BYMONTH] )) {
$daynoSw = self::recurBYcntcheck(
$bydayvalue[Util::$ZERO],
$dayCnts[$m][$d][self::$MONTHDAYNO_UP],
$dayCnts[$m][$d][self::$MONTHDAYNO_DOWN]
);
}
elseif( isset( $recur[Util::$FREQ] ) &&
( $recur[Util::$FREQ] == self::$YEARLY )) {
$daynoSw = self::recurBYcntcheck(
$bydayvalue[Util::$ZERO],
$dayCnts[$m][$d][self::$YEARDAYNO_UP],
$dayCnts[$m][$d][self::$YEARDAYNO_DOWN]
);
}
} // end if( isset( $bydayvalue[0] ))
if(( $daynoExists && $daynoSw && $dayNameSw ) ||
( ! $daynoExists && ! $daynoSw && $dayNameSw )) {
$updateOK = true;
break;
}
} // end foreach( $recur[Util::$BYDAY] as $bydayvalue )
} // end else
} // end if( $updateOK && isset( $recur[Util::$BYDAY] ))
/* check BYSETPOS */
if( $updateOK ) {
if( isset( $recur[Util::$BYSETPOS] ) &&
( in_array( $recur[Util::$FREQ], $YEAR2DAYARR )) ) {
if( isset( $recur[self::$WEEKLY] )) {
if( $bysetPosWold == $dayCnts[$wDate[Util::$LCMONTH]][$wDate[Util::$LCDAY]][self::$WEEKNO_UP] ) {
$bysetPosw1[] = $wDateYMD;
}
else {
$bysetPosw2[] = $wDateYMD;
}
}
else {
if(( isset( $recur[Util::$FREQ] ) &&
( self::$YEARLY == $recur[Util::$FREQ] ) &&
( $bysetPosYold == $wDate[Util::$LCYEAR] )) ||
( isset( $recur[Util::$FREQ] ) &&
( self::$MONTHLY == $recur[Util::$FREQ] ) &&
(( $bysetPosYold == $wDate[Util::$LCYEAR] ) &&
( $bysetPosMold == $wDate[Util::$LCMONTH] )) ) ||
( isset( $recur[Util::$FREQ] ) &&
( self::$DAILY == $recur[Util::$FREQ] ) &&
(( $bysetPosYold == $wDate[Util::$LCYEAR] ) &&
( $bysetPosMold == $wDate[Util::$LCMONTH] ) &&
( $bysetPosDold == $wDate[Util::$LCDAY] )) )) {
$bysetPosymd1[] = $wDateYMD;
}
else {
$bysetPosymd2[] = $wDateYMD;
}
} // end else
}
else {
if( checkdate((int) $wDate[Util::$LCMONTH], (int) $wDate[Util::$LCDAY], (int) $wDate[Util::$LCYEAR] )) {
/* update result array if BYSETPOS is not set */
$recurCount++;
if( $fcnStartYMD <= $wDateYMD ) { // only output within period
$result[$wDateYMD] = true;
}
}
$updateOK = false;
}
}
/* step up date */
self::stepDate( $wDate, $wDateYMD, $step );
/* check if BYSETPOS is set for updating result array */
if( $updateOK && isset( $recur[Util::$BYSETPOS] )) {
$bysetPos = false;
if( isset( $recur[Util::$FREQ] ) &&
( self::$YEARLY == $recur[Util::$FREQ] ) &&
( $bysetPosYold != $wDate[Util::$LCYEAR] )) {
$bysetPos = true;
$bysetPosYold = $wDate[Util::$LCYEAR];
}
elseif( isset( $recur[Util::$FREQ] ) &&
( self::$MONTHLY == $recur[Util::$FREQ] &&
(( $bysetPosYold != $wDate[Util::$LCYEAR] ) ||
( $bysetPosMold != $wDate[Util::$LCMONTH] )) )) {
$bysetPos = true;
$bysetPosYold = $wDate[Util::$LCYEAR];
$bysetPosMold = $wDate[Util::$LCMONTH];
}
elseif( isset( $recur[Util::$FREQ] ) &&
( self::$WEEKLY == $recur[Util::$FREQ] )) {
$weekNo = self::getWeeNumber(0,0, $wkst, $wDate[Util::$LCMONTH], $wDate[Util::$LCDAY], $wDate[Util::$LCYEAR] );
if( $bysetPosWold != $weekNo ) {
$bysetPosWold = $weekNo;
$bysetPos = true;
}
}
elseif( isset( $recur[Util::$FREQ] ) &&
( self::$DAILY == $recur[Util::$FREQ] ) &&
(( $bysetPosYold != $wDate[Util::$LCYEAR] ) ||
( $bysetPosMold != $wDate[Util::$LCMONTH] ) ||
( $bysetPosDold != $wDate[Util::$LCDAY] )) ) {
$bysetPos = true;
$bysetPosYold = $wDate[Util::$LCYEAR];
$bysetPosMold = $wDate[Util::$LCMONTH];
$bysetPosDold = $wDate[Util::$LCDAY];
}
if( $bysetPos ) {
if( isset( $recur[Util::$BYWEEKNO] )) {
$bysetPosArr1 = &$bysetPosw1;
$bysetPosArr2 = &$bysetPosw2;
}
else {
$bysetPosArr1 = &$bysetPosymd1;
$bysetPosArr2 = &$bysetPosymd2;
}
foreach( $recur[Util::$BYSETPOS] as $ix ) {
if( 0 > $ix ) { // both positive and negative BYSETPOS allowed
$ix = ( count( $bysetPosArr1 ) + $ix + 1 );
}
$ix--;
if( isset( $bysetPosArr1[$ix] )) {
if( $fcnStartYMD <= $bysetPosArr1[$ix] ) { // only output within period
$result[$bysetPosArr1[$ix]] = true;
}
$recurCount++;
}
if( isset( $recur[Util::$COUNT] ) && ( $recurCount >= $recur[Util::$COUNT] )) {
break;
}
}
$bysetPosArr1 = $bysetPosArr2;
$bysetPosArr2 = [];
} // end if( $bysetPos )
} // end if( $updateOK && isset( $recur['BYSETPOS'] ))
} // end while( true )
}
/**
* Checking BYDAY (etc) hits, recur2date help function
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.6.12 - 2011-01-03
* @param array $BYvalue
* @param int $upValue
* @param int $downValue
* @return bool
* @access private
* @static
*/
private static function recurBYcntcheck( $BYvalue, $upValue, $downValue ) {
if( is_array( $BYvalue ) && ( in_array( $upValue, $BYvalue ) || in_array( $downValue, $BYvalue )) ) {
return true;
}
elseif(( $BYvalue == $upValue ) || ( $BYvalue == $downValue )) {
return true;
}
else {
return false;
}
}
/**
* (re-)Calculate internal index, recur2date help function
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.26 - 2018-11-10
* @param string $freq
* @param array $date
* @param int $wkst
* @return bool
* @access private
* @static
*/
private static function recurIntervalIx( $freq, $date, $wkst ) {
/* create interval index */
switch( $freq ) {
case self::$YEARLY :
$intervalIx = $date[Util::$LCYEAR];
break;
case self::$MONTHLY :
$intervalIx = $date[Util::$LCYEAR] . Util::$MINUS . $date[Util::$LCMONTH];
break;
case self::$WEEKLY :
$intervalIx = self::getWeeNumber(0,0, $wkst, $date[Util::$LCMONTH], $date[Util::$LCDAY], $date[Util::$LCYEAR] );
break;
case self::$DAILY :
default:
$intervalIx = $date[Util::$LCYEAR] . Util::$MINUS . $date[Util::$LCMONTH] . Util::$MINUS . $date[Util::$LCDAY];
break;
}
return $intervalIx;
}
/**
* Return updated date, array and timpstamp
*
* @param array $date date to step
* @param string $dateYMD date YMD
* @param array $step default array( Util::$LCDAY => 1 )
* @return void
* @access private
* @static
*/
private static function stepDate( & $date, & $dateYMD, $step = null ) {
if( is_null( $step )) {
$step = [ Util::$LCDAY => 1 ];
}
if( ! isset( $date[Util::$LCHOUR] )) {
$date[Util::$LCHOUR] = 0;
}
if( ! isset( $date[Util::$LCMIN] )) {
$date[Util::$LCMIN] = 0;
}
if( ! isset( $date[Util::$LCSEC] )) {
$date[Util::$LCSEC] = 0;
}
if( isset( $step[Util::$LCDAY] )) {
$daysInMonth = self::getDaysInMonth(
$date[Util::$LCHOUR],
$date[Util::$LCMIN],
$date[Util::$LCSEC],
$date[Util::$LCMONTH],
$date[Util::$LCDAY],
$date[Util::$LCYEAR]
);
}
foreach( $step as $stepix => $stepvalue ) {
$date[$stepix] += $stepvalue;
}
if( isset( $step[Util::$LCMONTH] )) {
if( 12 < $date[Util::$LCMONTH] ) {
$date[Util::$LCYEAR] += 1;
$date[Util::$LCMONTH] -= 12;
}
}
elseif( isset( $step[Util::$LCDAY] )) {
if( $daysInMonth < $date[Util::$LCDAY] ) {
$date[Util::$LCDAY] -= $daysInMonth;
$date[Util::$LCMONTH] += 1;
if( 12 < $date[Util::$LCMONTH] ) {
$date[Util::$LCYEAR] += 1;
$date[Util::$LCMONTH] -= 12;
}
}
}
$dateYMD = Util::getYMDString( $date );
}
/**
* Return initiated $dayCnts
*
* @param array $wDate
* @param array $recur
* @param int $wkst
* @return array
* @access private
* @static
*/
private static function initDayCnts( array $wDate, array $recur, $wkst ) {
$dayCnts = [];
$yearDayCnt = [];
$yearDays = 0;
foreach( self::$DAYNAMES as $dn ) {
$yearDayCnt[$dn] = 0;
}
for( $m = 1; $m <= 12; $m++ ) { // \count up and update up-counters
$dayCnts[$m] = [];
$weekDayCnt = [];
foreach( self::$DAYNAMES as $dn ) {
$weekDayCnt[$dn] = 0;
}
$daysInMonth = self::getDaysInMonth( 0, 0, 0, $m, 1, $wDate[Util::$LCYEAR] );
for( $d = 1; $d <= $daysInMonth; $d++ ) {
$dayCnts[$m][$d] = [];
if( isset( $recur[Util::$BYYEARDAY] )) {
$yearDays++;
$dayCnts[$m][$d][self::$YEARCNT_UP] = $yearDays;
}
if( isset( $recur[Util::$BYDAY] )) {
$day = self::getDayInWeek( 0, 0, 0, $m, $d, $wDate[Util::$LCYEAR] );
$dayCnts[$m][$d][Util::$DAY] = $day;
$weekDayCnt[$day]++;
$dayCnts[$m][$d][self::$MONTHDAYNO_UP] = $weekDayCnt[$day];
$yearDayCnt[$day]++;
$dayCnts[$m][$d][self::$YEARDAYNO_UP] = $yearDayCnt[$day];
}
if( isset( $recur[Util::$BYWEEKNO] ) || ( $recur[Util::$FREQ] == self::$WEEKLY )) {
$dayCnts[$m][$d][self::$WEEKNO_UP] = self::getWeeNumber(0,0, $wkst, $m, $d, $wDate[Util::$LCYEAR] );
}
} // end for( $d = 1; $d <= $daysInMonth; $d++ )
} // end for( $m = 1; $m <= 12; $m++ )
$daycnt = 0;
$yearDayCnt = [];
if( isset( $recur[Util::$BYWEEKNO] ) ||
( $recur[Util::$FREQ] == self::$WEEKLY )) {
$weekNo = null;
for( $d = 31; $d > 25; $d-- ) { // get last weekno for year
if( ! $weekNo ) {
$weekNo = $dayCnts[12][$d][self::$WEEKNO_UP];
}
elseif( $weekNo < $dayCnts[12][$d][self::$WEEKNO_UP] ) {
$weekNo = $dayCnts[12][$d][self::$WEEKNO_UP];
break;
}
}
}
for( $m = 12; $m > 0; $m-- ) { // count down and update down-counters
$weekDayCnt = [];
foreach( self::$DAYNAMES as $dn ) {
$yearDayCnt[$dn] = $weekDayCnt[$dn] = 0;
}
$monthCnt = 0;
$daysInMonth = self::getDaysInMonth( 0, 0, 0, $m, 1, $wDate[Util::$LCYEAR] );
for( $d = $daysInMonth; $d > 0; $d-- ) {
if( isset( $recur[Util::$BYYEARDAY] )) {
$daycnt -= 1;
$dayCnts[$m][$d][self::$YEARCNT_DOWN] = $daycnt;
}
if( isset( $recur[Util::$BYMONTHDAY] )) {
$monthCnt -= 1;
$dayCnts[$m][$d][self::$MONTHCNT_DOWN] = $monthCnt;
}
if( isset( $recur[Util::$BYDAY] )) {
$day = $dayCnts[$m][$d][Util::$DAY];
$weekDayCnt[$day] -= 1;
$dayCnts[$m][$d][self::$MONTHDAYNO_DOWN] = $weekDayCnt[$day];
$yearDayCnt[$day] -= 1;
$dayCnts[$m][$d][self::$YEARDAYNO_DOWN] = $yearDayCnt[$day];
}
if( isset( $recur[Util::$BYWEEKNO] ) || ( $recur[Util::$FREQ] == self::$WEEKLY )) {
$dayCnts[$m][$d][self::$WEEKNO_DOWN] = ( $dayCnts[$m][$d][self::$WEEKNO_UP] - $weekNo - 1 );
}
}
} // end for( $m = 12; $m > 0; $m-- )
return $dayCnts;
}
/**
* Return a reformatted input date
*
* @param mixed $aDate
* @access private
* @static
*/
private static function reFormatDate( & $aDate ) {
static $YMDHIS2 = 'Y-m-d H:i:s';
switch( true ) {
case ( is_string( $aDate )) :
Util::strDate2arr( $aDate );
break;
case ( $aDate instanceof DateTime ) :
$aDate = $aDate->format( $YMDHIS2 );
Util::strDate2arr( $aDate );
break;
default :
break;
}
foreach( $aDate as $k => $v ) {
if( ctype_digit( $v )) {
$aDate[$k] = (int) $v;
}
}
}
/**
* Return week number
*
* @param int $hour
* @param int $min
* @param int $sec
* @param int $month
* @param int $day
* @param int $year
* @return int
* @access private
* @static
*/
private static function getWeeNumber( $hour, $min, $sec, $month, $day, $year ) {
static $W = 'W';
return (int) date( $W, mktime( $hour, $min, $sec, $month, $day, $year ));
}
/**
* Return number of days in month
*
* @param int $hour
* @param int $min
* @param int $sec
* @param int $month
* @param int $day
* @param int $year
* @return int
* @access private
* @static
*/
private static function getDaysInMonth( $hour, $min, $sec, $month, $day, $year ) {
static $T = 't';
return (int) date( $T, mktime( $hour, $min, $sec, $month, $day, $year ));
}
/**
* Return day in week
*
* @param int $hour
* @param int $min
* @param int $sec
* @param int $month
* @param int $day
* @param int $year
* @return string
* @access private
* @static
*/
private static function getDayInWeek( $hour, $min, $sec, $month, $day, $year ) {
static $W = 'w';
$dayNo = (int) date( $W, mktime( $hour, $min, $sec, $month, $day, $year ));
return self::$DAYNAMES[$dayNo];
}
}

View File

@@ -0,0 +1,168 @@
<?php
/**
* iCalcreator, the PHP class package managing iCal (rfc2445/rfc5445) calendar information.
*
* copyright (c) 2007-2019 Kjell-Inge Gustafsson, kigkonsult, All rights reserved
* Link https://kigkonsult.se
* Package iCalcreator
* Version 2.26.8
* License Subject matter of licence is the software iCalcreator.
* The above copyright, link, package and version notices,
* this licence notice and the invariant [rfc5545] PRODID result use
* as implemented and invoked in iCalcreator shall be included in
* all copies or substantial portions of the iCalcreator.
*
* iCalcreator 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 3 of the License,
* or (at your option) any later version.
*
* iCalcreator 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 iCalcreator. If not, see <https://www.gnu.org/licenses/>.
*
* This file is a part of iCalcreator.
*/
namespace Kigkonsult\Icalcreator\Util;
use Kigkonsult\Icalcreator\Vcalendar;
use function clearstatcache;
use function file_put_contents;
use function fclose;
use function filesize;
use function filemtime;
use function fopen;
use function fpassthru;
use function gzencode;
use function header;
use function is_file;
use function is_readable;
use function sprintf;
use function strlen;
use function sys_get_temp_dir;
use function tempnam;
use function time;
use function unlink;
use function utf8_encode;
/**
* iCalcreator redirect support class
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.26 - 2018-11-10
*/
class UtilRedirect
{
/**
* HTTP headers
*
* @var array $headers
* @access private
* @static
*/
private static $headers = [
'Content-Encoding: gzip',
'Vary: *',
'Content-Length: %s',
'Content-Type: text/calendar; charset=utf-8',
'Content-Disposition: attachment; filename="%s"',
'Content-Disposition: inline; filename="%s"',
'Cache-Control: max-age=10',
];
/**
* Return created, updated and/or parsed calendar, sending a HTTP redirect header.
*
* @param Vcalendar $calendar
* @param bool $utf8Encode
* @param bool $gzip
* @param bool $cdType true : Content-Disposition: attachment... (default), false : ...inline...
* @return bool true on success, false on error
* @static
*/
public static function returnCalendar(
Vcalendar $calendar,
$utf8Encode = false,
$gzip = false,
$cdType = true
) {
static $ICR = 'iCr';
$filename = $calendar->getConfig( Util::$FILENAME );
$output = $calendar->createCalendar();
if( $utf8Encode ) {
$output = utf8_encode( $output );
}
$fsize = null;
if( $gzip ) {
$output = gzencode( $output, 9 );
$fsize = strlen( $output );
header( self::$headers[0] );
header( self::$headers[1] );
}
else {
if( false !== ( $temp = tempnam( sys_get_temp_dir(), $ICR ))) {
if( false !== file_put_contents( $temp, $output )) {
$fsize = @filesize( $temp );
}
unlink( $temp );
}
}
if( ! empty( $fsize )) {
header( sprintf( self::$headers[2], $fsize ));
}
header( self::$headers[3] );
$cdType = ( $cdType ) ? 4 : 5;
header( sprintf( self::$headers[$cdType], $filename ));
header( self::$headers[6] );
echo $output;
return true;
}
/**
* If recent version of calendar file exists (default one hour), an HTTP redirect header is sent
*
* @param Vcalendar $calendar
* @param int $timeout default 3600 sec
* @param bool $cdType true : Content-Disposition: attachment... (default), false : ...inline...
* @return bool true on success, false on error
* @static
*/
public static function useCachedCalendar(
Vcalendar $calendar,
$timeout = 3600,
$cdType = true
) {
static $R = 'r';
if( false === ( $dirfile = $calendar->getConfig( Util::$URL ))) {
$dirfile = $calendar->getConfig( Util::$DIRFILE );
}
if( ! is_file( $dirfile ) || ! is_readable( $dirfile )) {
return false;
}
if( time() - filemtime( $dirfile ) > $timeout ) {
return false;
}
clearstatcache();
$fsize = @filesize( $dirfile );
$filename = $calendar->getConfig( Util::$FILENAME );
header( self::$headers[3] );
if( ! empty( $fsize )) {
header( sprintf( self::$headers[2], $fsize ));
}
$cdType = ( $cdType ) ? 4 : 5;
header( sprintf( self::$headers[$cdType], $filename ));
header( self::$headers[6] );
if( false === ( $fp = @fopen( $dirfile, $R ))) {
return false;
}
fpassthru( $fp );
fclose( $fp );
return true;
}
}

View File

@@ -0,0 +1,698 @@
<?php
/**
* iCalcreator, the PHP class package managing iCal (rfc2445/rfc5445) calendar information.
*
* copyright (c) 2007-2019 Kjell-Inge Gustafsson, kigkonsult, All rights reserved
* Link https://kigkonsult.se
* Package iCalcreator
* Version 2.26.8
* License Subject matter of licence is the software iCalcreator.
* The above copyright, link, package and version notices,
* this licence notice and the invariant [rfc5545] PRODID result use
* as implemented and invoked in iCalcreator shall be included in
* all copies or substantial portions of the iCalcreator.
*
* iCalcreator 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 3 of the License,
* or (at your option) any later version.
*
* iCalcreator 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 iCalcreator. If not, see <https://www.gnu.org/licenses/>.
*
* This file is a part of iCalcreator.
*/
namespace Kigkonsult\Icalcreator\Util;
use DateTime;
use DateInterval;
use Exception;
use function array_key_exists;
use function array_keys;
use function count;
use function ctype_digit;
use function end;
use function explode;
use function in_array;
use function is_array;
use function is_string;
use function reset;
use function str_replace;
use function strlen;
use function strtoupper;
use function substr;
use function substr_count;
use function trim;
use function usort;
/**
* iCalcreator EXDATE/RDATE support class
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.26.8 - 2018-12-12
*/
class UtilRexdate
{
/**
* @var array
* @access private
* @static
*/
private static $GMTUTCZARR = [ 'GMT', 'UTC', 'Z' ];
/**
* Check (EXDATE/RDATE) date(-time) and params arrays for an opt. timezone
*
* If it is a DATE-TIME or DATE, updates $parno and (opt) $params)
*
* @param array $theDate date to check
* @param int $parno no of date parts (i.e. year, month.. .)
* @param array $params property parameters
* @access private
* @static
* @since 2.26.7 - 2018-11-25
*/
private static function chkDateCfg( $theDate, & $parno, & $params ) {
$paramsValueIsDATE = Util::isParamsValueSet( [ Util::$LCparams => $params ], Util::$DATE );
switch( true ) {
case ( isset( $params[Util::$TZID] )) :
$parno = 6;
break;
case ( $paramsValueIsDATE ) :
$params[Util::$VALUE] = Util::$DATE;
$parno = 3;
break;
default:
if( Util::isParamsValueSet( [ Util::$LCparams => $params ], Util::$PERIOD )) {
$params[Util::$VALUE] = Util::$PERIOD;
$parno = 7;
}
switch( true ) {
case ( $theDate instanceof DateTime ) :
$tz = $theDate->getTimezone();
if( ! empty( $tz )) {
$params[Util::$TZID] = $tz->getName();
}
$parno = 7;
break;
case ( is_array( $theDate )) :
$tzid = null;
if( isset( $theDate[Util::$LCTIMESTAMP] )) {
$tzid = ( isset( $theDate[Util::$LCtz] )) ? $theDate[Util::$LCtz] : null;
}
elseif( isset( $theDate[Util::$LCtz] )) {
$tzid = $theDate[Util::$LCtz];
}
elseif( 7 == count( $theDate )) {
$tzid = end( $theDate );
}
if( ! empty( $tzid )) {
$parno = 7;
if( ! Util::isOffset( $tzid )) {
$params[Util::$TZID] = $tzid;
} // save only timezone
}
elseif( ! $parno && ( 3 == count( $theDate )) && $paramsValueIsDATE ) {
$parno = 3;
}
else {
$parno = 6;
}
break;
default : // i.e. string
$date = trim((string) $theDate );
if(( Util::$Z == substr( $date, -1 )) || // UTC DATE-TIME
( Util::$GMT == substr( $date, -3 )) ||
( Util::$UTC == substr( $date, -3 ))) {
$params[Util::$TZID] = Util::$Z;
$parno = 7;
}
elseif(( 2 == substr_count( $date, Util::$SP1 )) && // 'Y-m-d H:i:s e'
( 2 == substr_count( $date, Util::$MINUS )) &&
( 2 == substr_count( $date, Util::$COLON ))) {
$params[Util::$TZID] = explode( Util::$SP1, $date, 3 )[2];
$parno = 7;
}
elseif((( 8 == strlen( $date ) && ctype_digit( $date )) || ( 11 >= strlen( $date )))
&& $paramsValueIsDATE ) {
$parno = 3;
}
$date = Util::strDate2ArrayDate( $date, $parno );
unset( $date[Util::$UNPARSEDTEXT] );
if( ! empty( $date[Util::$LCtz] )) {
$parno = 7;
if( ! Util::isOffset( $date[Util::$LCtz] )) {
$params[Util::$TZID] = $date[Util::$LCtz];
} // save only timezone
}
elseif( empty( $parno )) {
$parno = 6;
}
break;
} // end switch( true )
if( isset( $params[Util::$TZID] )) {
$parno = 6;
}
} // end switch( true )
}
/**
* Return formatted output for calendar component property data value type recur
*
* @param array $exdateData
* @param bool $allowEmpty
* @return string
* @static
*/
public static function formatExdate( $exdateData, $allowEmpty ) {
static $SORTER1 = [
'Kigkonsult\Icalcreator\Util\VcalendarSortHandler',
'sortExdate1',
];
static $SORTER2 = [
'Kigkonsult\Icalcreator\Util\VcalendarSortHandler',
'sortExdate2',
];
$output = null;
$exdates = [];
foreach(( array_keys( $exdateData )) as $ex ) {
$theExdate = $exdateData[$ex];
if( empty( $theExdate[Util::$LCvalue] )) {
if( $allowEmpty ) {
$output .= Util::createElement( Util::$EXDATE );
}
continue;
}
if( 1 < count( $theExdate[Util::$LCvalue] )) {
usort( $theExdate[Util::$LCvalue], $SORTER1 );
}
$exdates[] = $theExdate;
}
if( 1 < count( $exdates )) {
usort( $exdates, $SORTER2 );
}
foreach(( array_keys( $exdates )) as $ex ) {
$theExdate = $exdates[$ex];
$content = $attributes = null;
foreach(( array_keys( $theExdate[Util::$LCvalue] )) as $eix ) {
$exdatePart = $theExdate[Util::$LCvalue][$eix];
$parno = count( $exdatePart );
$formatted = Util::date2strdate( $exdatePart, $parno );
if( isset( $theExdate[Util::$LCparams][Util::$TZID] )) {
$formatted = str_replace( Util::$Z, null, $formatted );
}
if( 0 < $eix ) {
if( isset( $theExdate[Util::$LCvalue][0][Util::$LCtz] )) {
if(( Util::isOffset( $theExdate[Util::$LCvalue][0][Util::$LCtz] )) ||
( Util::$Z == $theExdate[Util::$LCvalue][0][Util::$LCtz] )) {
if( Util::$Z != substr( $formatted, -1 )) {
$formatted .= Util::$Z;
}
}
else {
$formatted = str_replace( Util::$Z, null, $formatted );
}
}
else {
$formatted = str_replace( Util::$Z, null, $formatted );
}
} // end if( 0 < $eix )
$content .= ( 0 < $eix ) ? Util::$COMMA . $formatted : $formatted;
} // end foreach(( array_keys( $theExdate[Util::$LCvalue]...
$output .= Util::createElement(
Util::$EXDATE,
Util::createParams( $theExdate[Util::$LCparams] ),
$content
);
} // end foreach(( array_keys( $exdates...
return $output;
}
/**
* Return prepared calendar component property exdate input
*
* @param array $exdates
* @param array $params
* @return mixed array|bool
* @static
* @since 2.26.7 - 2018-11-25
*/
public static function prepInputExdate( $exdates, $params = null ) {
$output = [
Util::$LCparams => Util::setParams( $params, Util::$DEFAULTVALUEDATETIME ),
Util::$LCvalue => [],
];
foreach(( array_keys( $exdates )) as $eix ) {
if( $exdates[$eix] instanceof DateTime ) {
$exdates[$eix] = Util::dateTime2Str( $exdates[$eix] );
}
}
/* ev. check 1:st date and save ev. timezone **/
self::chkDateCfg( reset( $exdates ), $parno, $output[Util::$LCparams] );
Util::existRem( $output[Util::$LCparams], Util::$VALUE, Util::$DATE_TIME ); // remove default parameter
$toZ = ( isset( $output[Util::$LCparams][Util::$TZID] ) &&
in_array( strtoupper( $output[Util::$LCparams][Util::$TZID] ), self::$GMTUTCZARR )) ? true : false;
foreach(( array_keys( $exdates )) as $eix ) {
$theExdate = $exdates[$eix];
$wDate = [];
Util::strDate2arr( $theExdate );
if( Util::isArrayTimestampDate( $theExdate )) {
if( isset( $theExdate[Util::$LCtz] ) &&
! Util::isOffset( $theExdate[Util::$LCtz] )) {
if( isset( $output[Util::$LCparams][Util::$TZID] )) {
$theExdate[Util::$LCtz] = $output[Util::$LCparams][Util::$TZID];
}
else {
$output[Util::$LCparams][Util::$TZID] = $theExdate[Util::$LCtz];
}
}
$wDate = Util::timestamp2date( $theExdate, $parno );
}
elseif( is_array( $theExdate )) {
$d = Util::chkDateArr( $theExdate, $parno );
if( isset( $d[Util::$LCtz] ) && ( Util::$Z != $d[Util::$LCtz] ) && Util::isOffset( $d[Util::$LCtz] )) {
$wDate = Util::ensureArrDatetime( [Util::$LCvalue => $d], $d[Util::$LCtz], 7 );
unset( $wDate[Util::$UNPARSEDTEXT] );
}
else {
$wDate = $d;
}
}
elseif( 8 <= strlen( trim( $theExdate ))) { // ex. 2006-08-03 10:12:18
$wDate = Util::strDate2ArrayDate( $theExdate, $parno );
unset( $wDate[Util::$UNPARSEDTEXT] );
}
if( 3 == $parno ) {
unset( $wDate[Util::$LCHOUR], $wDate[Util::$LCMIN], $wDate[Util::$LCSEC], $wDate[Util::$LCtz] );
}
elseif( isset( $wDate[Util::$LCtz] )) {
$wDate[Util::$LCtz] = (string) $wDate[Util::$LCtz];
}
if( isset( $output[Util::$LCparams][Util::$TZID] ) ||
( isset( $wDate[Util::$LCtz] ) && ! Util::isOffset( $wDate[Util::$LCtz] )) ||
( isset( $output[Util::$LCvalue][0] ) && ( ! isset( $output[Util::$LCvalue][0][Util::$LCtz] ))) ||
( isset( $output[Util::$LCvalue][0][Util::$LCtz] ) &&
! Util::isOffset( $output[Util::$LCvalue][0][Util::$LCtz] ))) {
unset( $wDate[Util::$LCtz] );
}
if( $toZ ) { // time zone Z
$wDate[Util::$LCtz] = Util::$Z;
}
$output[Util::$LCvalue][] = $wDate;
} // end foreach(( array_keys( $exdates...
if( 0 >= count( $output[Util::$LCvalue] )) {
return false;
}
if( 3 == $parno ) {
$output[Util::$LCparams][Util::$VALUE] = Util::$DATE;
unset( $output[Util::$LCparams][Util::$TZID] );
}
if( $toZ ) { // time zone Z
unset( $output[Util::$LCparams][Util::$TZID] );
}
return $output;
}
/**
* Return formatted output for calendar component property rdate
*
* @param array $rdateData
* @param bool $allowEmpty
* @param string $compType
* @return string
* @static
* @since 2.26.7 - 2018-11-29
*/
public static function formatRdate( $rdateData, $allowEmpty, $compType ) {
static $SORTER1 = [
'Kigkonsult\Icalcreator\Util\VcalendarSortHandler',
'sortRdate1',
];
static $SORTER2 = [
'Kigkonsult\Icalcreator\Util\VcalendarSortHandler',
'sortRdate2',
];
$utcTime = ( Util::isCompInList( $compType, Util::$TZCOMPS )) ? true : false;
$output = null;
$rDates = [];
foreach(( array_keys( $rdateData )) as $rpix ) {
$theRdate = $rdateData[$rpix];
if( empty( $theRdate[Util::$LCvalue] )) {
if( $allowEmpty ) {
$output .= Util::createElement( Util::$RDATE );
}
continue;
}
if( $utcTime ) {
unset( $theRdate[Util::$LCparams][Util::$TZID] );
}
if( 1 < count( $theRdate[Util::$LCvalue] )) {
usort( $theRdate[Util::$LCvalue], $SORTER1 );
}
$rDates[] = $theRdate;
}
if( 1 < count( $rDates )) {
usort( $rDates, $SORTER2 );
}
$paramsTZIDisSet = ! empty( $theRdate[Util::$LCparams][Util::$TZID] );
foreach(( array_keys( $rDates )) as $rpix ) {
$theRdate = $rDates[$rpix];
$attributes = Util::createParams( $theRdate[Util::$LCparams] );
$cnt = count( $theRdate[Util::$LCvalue] );
$content = null;
$rno = 1;
foreach(( array_keys( $theRdate[Util::$LCvalue] )) as $rix ) {
$rdatePart = $theRdate[Util::$LCvalue][$rix];
$contentPart = null;
if( is_array( $rdatePart ) && Util::isParamsValueSet( $theRdate, Util::$PERIOD )) { // PERIOD
if( $utcTime ||
( $paramsTZIDisSet && isset( $rdatePart[0][Util::$LCtz] ) &&
! Util::isOffset( $rdatePart[0][Util::$LCtz] ))) {
unset( $rdatePart[0][Util::$LCtz] );
}
$formatted = Util::date2strdate( $rdatePart[0] ); // PERIOD part 1
if( $utcTime || $paramsTZIDisSet ) {
$formatted = str_replace( Util::$Z, null, $formatted );
}
$contentPart .= $formatted;
$contentPart .= '/';
if( isset( $rdatePart[1]['invert'] )) { // fix pre 7.0.5 bug
$dateInterval = UtilDuration::DateIntervalArr2DateInterval( $rdatePart[1] );
$contentPart .= UtilDuration::dateInterval2String( $dateInterval );
}
elseif( ! array_key_exists( Util::$LCHOUR, $rdatePart[1] )) {
$contentPart .= Util::getYMDString( $rdatePart[1] );
}
else { // date-time
if( $utcTime ||
( $paramsTZIDisSet && isset( $rdatePart[1][Util::$LCtz] ) &&
! Util::isOffset( $rdatePart[1][Util::$LCtz] ))) {
unset( $rdatePart[1][Util::$LCtz] );
}
$formatted = Util::date2strdate( $rdatePart[1] ); // PERIOD part 2
if( $utcTime || $paramsTZIDisSet ) {
$formatted = str_replace( Util::$Z, null, $formatted );
}
$contentPart .= $formatted;
}
} // PERIOD end
else { // SINGLE date start
if( $utcTime ||
( $paramsTZIDisSet && isset( $rdatePart[Util::$LCtz] ) &&
! Util::isOffset( $rdatePart[Util::$LCtz] ))) {
unset( $rdatePart[Util::$LCtz] );
}
$parno = ( Util::isParamsValueSet( $theRdate, Util::$DATE )) ? 3 : null;
$formatted = Util::date2strdate( $rdatePart, $parno );
if( $utcTime || $paramsTZIDisSet ) {
$formatted = str_replace( Util::$Z, null, $formatted );
}
$contentPart .= $formatted;
}
$content .= $contentPart;
if( $rno < $cnt ) {
$content .= Util::$COMMA;
}
$rno++;
} // end foreach(( array_keys( $theRdate[Util::$LCvalue]...
$output .= Util::createElement( Util::$RDATE, $attributes, $content );
} // foreach(( array_keys( $rDates...
return $output;
}
/**
* Return prepared calendar component property rdate input
*
* @param array $rDates
* @param array $params
* @param string $compType
* @return array
* @static
* @since 2.26.7 - 2018-11-29
* @todo fix exception
*/
public static function prepInputRdate( array $rDates, $params=null, $compType=null ) {
$output = [ Util::$LCparams => Util::setParams( $params, Util::$DEFAULTVALUEDATETIME ) ];
if( Util::isCompInList( $compType, Util::$TZCOMPS )) {
unset( $output[Util::$LCparams][Util::$TZID] );
$output[Util::$LCparams][Util::$VALUE] = Util::$DATE_TIME;
}
/* check if PERIOD, if not set */
if( self::isUnAttributedPeriod( $rDates, $output )) {
$output[Util::$LCparams][Util::$VALUE] = Util::$PERIOD;
}
/* check 1:st date, upd. $parno (opt) and save opt. timezone */
$date = reset( $rDates );
if( isset( $output[Util::$LCparams][Util::$VALUE] ) &&
( Util::$PERIOD == $output[Util::$LCparams][Util::$VALUE] )) { // PERIOD
$date = reset( $date );
}
self::chkDateCfg( $date, $parno, $output[Util::$LCparams] );
if( isset( $output[Util::$LCvalue ][Util::$LCtz] ) &&
( in_array( strtoupper( $output[Util::$LCvalue ][Util::$LCtz] ), self::$GMTUTCZARR ) ||
Util::isOffset( $output[Util::$LCvalue ][Util::$LCtz] ))) {
$toZ = true;
}
else {
$toZ = ( isset( $params[Util::$TZID] ) &&
in_array( strtoupper( $params[Util::$TZID] ), self::$GMTUTCZARR )) ? true : false;
}
Util::existRem( $output[Util::$LCparams], Util::$VALUE, Util::$DATE_TIME ); // remove default
foreach( $rDates as $rpix => $theRdate ) {
$wDate = null;
if( $theRdate instanceof DateTime ) {
$theRdate = Util::dateTime2Str( $theRdate );
}
Util::strDate2arr( $theRdate );
if( is_array( $theRdate )) {
if( isset( $output[Util::$LCparams][Util::$VALUE] ) &&
( Util::$PERIOD == $output[Util::$LCparams][Util::$VALUE] )) { // PERIOD
foreach( $theRdate as $rix => $rPeriod ) {
if( $rPeriod instanceof DateTime ) {
$rPeriod = Util::dateTime2Str( $rPeriod );
}
elseif( $rPeriod instanceof DateInterval ) {
$wDate[] = (array) $rPeriod; // fix pre 7.0.5 bug
continue;
}
$wDate2 = null;
if( is_array( $rPeriod )) {
if( Util::isArrayTimestampDate( $rPeriod )) { // timestamp
if( isset( $rPeriod[Util::$LCtz] ) &&
! Util::isOffset( $rPeriod[Util::$LCtz] )) {
if( isset( $output[Util::$LCparams][Util::$TZID] )) {
$rPeriod[Util::$LCtz] = $output[Util::$LCparams][Util::$TZID];
}
else {
$output[Util::$LCparams][Util::$TZID] = $rPeriod[Util::$LCtz];
}
}
$wDate2 = Util::timestamp2date( $rPeriod, $parno );
} // end if( Util::isArrayTimestampDate( $rPeriod ))
elseif( Util::isArrayDate( $rPeriod )) {
$d = ( 3 < count( $rPeriod ))
? Util::chkDateArr( $rPeriod, $parno )
: Util::chkDateArr( $rPeriod, 6 );
if( isset( $d[Util::$LCtz] ) &&
( Util::$Z != $d[Util::$LCtz] ) &&
Util::isOffset( $d[Util::$LCtz] )) {
$wDate2 = Util::ensureArrDatetime( [Util::$LCvalue => $d], $d[Util::$LCtz], 7 );
unset( $wDate2[Util::$UNPARSEDTEXT] );
}
else {
$wDate2 = $d;
}
} // end elseif( Util::isArrayDate( $rPeriod ))
elseif(( 1 == count( $rPeriod )) &&
( 8 <= strlen( reset( $rPeriod )))) { // text-date
$wDate2 = Util::strDate2ArrayDate( reset( $rPeriod ), $parno );
unset( $wDate2[Util::$UNPARSEDTEXT] );
}
else { // array format duration
try { // fix pre 7.0.5 bug
$wDate[] = (array) UtilDuration::conformDateInterval(
new DateInterval(
UtilDuration::duration2str(
UtilDuration::duration2arr( $rPeriod )
)
)
);
}
catch( Exception $e ) {
// return false; // todo
}
continue;
}
} // end if( is_array( $rPeriod ))
elseif(( 3 <= strlen( trim( $rPeriod ))) && // string format duration
( in_array( $rPeriod[0], UtilDuration::$PREFIXARR ))) {
if( UtilDuration::$P != $rPeriod[0] ) {
$rPeriod = substr( $rPeriod, 1 );
}
try {
$wDate[] = (array) UtilDuration::conformDateInterval( new DateInterval( $rPeriod ));
}
catch( Exception $e ) {
// return false; // todo
}
continue;
}
elseif( 8 <= strlen( trim( $rPeriod ))) { // text date ex. 2006-08-03 10:12:18
$wDate2 = Util::strDate2ArrayDate( $rPeriod, $parno );
unset( $wDate2[Util::$UNPARSEDTEXT] );
}
if(( 0 == $rpix ) && ( 0 == $rix )) {
if( isset( $wDate2[Util::$LCtz] ) &&
in_array( strtoupper( $wDate2[Util::$LCtz] ), self::$GMTUTCZARR )) {
$wDate2[Util::$LCtz] = Util::$Z;
$toZ = true;
}
}
else {
if( isset( $wDate[0][Util::$LCtz] ) &&
( Util::$Z == $wDate[0][Util::$LCtz] ) &&
isset( $wDate2[Util::$LCYEAR] )) {
$wDate2[Util::$LCtz] = Util::$Z;
}
else {
unset( $wDate2[Util::$LCtz] );
}
}
if( $toZ && isset( $wDate2[Util::$LCYEAR] )) {
$wDate2[Util::$LCtz] = Util::$Z;
}
$wDate[] = $wDate2;
} // end foreach( $theRdate as $rix => $rPeriod )
} // PERIOD end
elseif( Util::isArrayTimestampDate( $theRdate )) { // timestamp
if( isset( $theRdate[Util::$LCtz] ) && ! Util::isOffset( $theRdate[Util::$LCtz] )) {
if( isset( $output[Util::$LCparams][Util::$TZID] )) {
$theRdate[Util::$LCtz] = $output[Util::$LCparams][Util::$TZID];
}
else {
$output[Util::$LCparams][Util::$TZID] = $theRdate[Util::$LCtz];
}
}
$wDate = Util::timestamp2date( $theRdate, $parno );
}
else { // date[-time]
$wDate = Util::chkDateArr( $theRdate, $parno );
if( isset( $wDate[Util::$LCtz] ) && ( Util::$Z != $wDate[Util::$LCtz] ) && Util::isOffset( $wDate[Util::$LCtz] )) {
$wDate = Util::ensureArrDatetime( [Util::$LCvalue => $wDate], $wDate[Util::$LCtz], 7 );
unset( $wDate[Util::$UNPARSEDTEXT] );
}
}
} // end if( is_array( $theRdate ))
elseif( 8 <= strlen( trim( $theRdate ))) { // text date ex. 2006-08-03 10:12:18
$wDate = Util::strDate2ArrayDate( $theRdate, $parno );
unset( $wDate[Util::$UNPARSEDTEXT] );
if( $toZ ) {
$wDate[Util::$LCtz] = Util::$Z;
}
}
if( ! isset( $output[Util::$LCparams][Util::$VALUE] ) ||
( Util::$PERIOD != $output[Util::$LCparams][Util::$VALUE] )) { // no PERIOD
if(( 0 == $rpix ) && ! $toZ ) {
$toZ = ( isset( $wDate[Util::$LCtz] ) &&
in_array( strtoupper( $wDate[Util::$LCtz] ), self::$GMTUTCZARR )) ? true : false;
}
if( $toZ ) {
$wDate[Util::$LCtz] = Util::$Z;
}
if( 3 == $parno ) {
unset( $wDate[Util::$LCHOUR], $wDate[Util::$LCMIN], $wDate[Util::$LCSEC], $wDate[Util::$LCtz] );
}
elseif( isset( $wDate[Util::$LCtz] )) {
$wDate[Util::$LCtz] = (string) $wDate[Util::$LCtz];
}
if( isset( $output[Util::$LCparams][Util::$TZID] ) ||
( isset( $output[Util::$LCvalue][0] ) &&
( ! isset( $output[Util::$LCvalue][0][Util::$LCtz] )))) {
if( ! $toZ ) {
unset( $wDate[Util::$LCtz] );
}
}
} // end if - no PERIOD
$output[Util::$LCvalue][] = $wDate;
} // end foreach( $rDates as $rpix => $theRdate )
if( 3 == $parno ) {
$output[Util::$LCparams][Util::$VALUE] = Util::$DATE;
unset( $output[Util::$LCparams][Util::$TZID] );
}
if( $toZ ) {
unset( $output[Util::$LCparams][Util::$TZID] );
}
return $output;
}
/**
* Return true if PERIOD is not set BUT is PERIOD
*
* @param array $rDates
* @param array $output
* @return bool
* @access private
* @static
* @since 2.26.7 - 2018-11-21
*/
private static function isUnAttributedPeriod( array $rDates, array $output ) {
if( Util::isParamsValueSet( $output, Util::$PERIOD )) {
return false;
}
if( isset( $output[Util::$LCparams][Util::$VALUE] ) &&
( Util::isParamsValueSet( $output, Util::$DATE ) ||
Util::isParamsValueSet( $output, Util::$DATE_TIME ))) {
return false;
}
if( isset( $rDates[0] ) && is_string( $rDates[0] )) {
return false;
}
if( isset( $rDates[0] ) && is_array( $rDates[0] ) && ( 2 != count( $rDates[0] ))) {
return false;
}
if( ! isset( $rDates[0][0] )) {
return false;
}
if( isset( $rDates[0][1] ) && isset( $rDates[0][Util::$LCTIMESTAMP] )) {
return false;
}
$firstOK = false;
switch( true ) {
case ( $rDates[0][0] instanceof DateTime ) :
$firstOK = true;
break;
case ( is_array( $rDates[0][0] ) &&
( Util::isArrayDate( $rDates[0][0] ) || isset( $rDates[0][0][Util::$LCTIMESTAMP] ))) :
$firstOK = true;
break;
case ( is_string( $rDates[0][0] ) && ( 8 <= strlen( trim( $rDates[0][0] )))) :
$firstOK = true;
break;
}
if( ! $firstOK ) {
return false;
}
switch( true ) {
case ( $rDates[0][1] instanceof DateTime ) :
return true;
break;
case ( is_array( $rDates[0][1] )) :
return true;
break;
case ( is_string( $rDates[0][1] ) && ( 3 <= strlen( trim( $rDates[0][1] )))) :
return true;
break;
}
return false;
}
}

View File

@@ -0,0 +1,352 @@
<?php
/**
* iCalcreator, the PHP class package managing iCal (rfc2445/rfc5445) calendar information.
*
* copyright (c) 2007-2019 Kjell-Inge Gustafsson, kigkonsult, All rights reserved
* Link https://kigkonsult.se
* Package iCalcreator
* Version 2.26.8
* License Subject matter of licence is the software iCalcreator.
* The above copyright, link, package and version notices,
* this licence notice and the invariant [rfc5545] PRODID result use
* as implemented and invoked in iCalcreator shall be included in
* all copies or substantial portions of the iCalcreator.
*
* iCalcreator 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 3 of the License,
* or (at your option) any later version.
*
* iCalcreator 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 iCalcreator. If not, see <https://www.gnu.org/licenses/>.
*
* This file is a part of iCalcreator.
*/
namespace Kigkonsult\Icalcreator\Util;
use Kigkonsult\Icalcreator\Vcalendar;
use Kigkonsult\Icalcreator\CalendarComponent;
use DateInterval;
use function array_slice;
use function is_null;
use function key;
use function reset;
use function strcmp;
/**
* iCalcreator VcalendarSortHandler class
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.26.7 - 2018-12-02
*/
class VcalendarSortHandler
{
/**
* Vcalendar sort callback function
*
* @since 2.26 - 2018-11-10
* @param CalendarComponent $a
* @param CalendarComponent $b
* @return int
* @static
*/
public static function cmpfcn(
CalendarComponent $a,
CalendarComponent $b
) {
if( empty( $a )) {
return -1;
}
if( empty( $b )) {
return 1;
}
if( Vcalendar::VTIMEZONE == $a->compType ) {
if( Vcalendar::VTIMEZONE != $b->compType ) {
return -1;
}
elseif( $a->srtk[0] <= $b->srtk[0] ) {
return -1;
}
else {
return 1;
}
}
elseif( Vcalendar::VTIMEZONE == $b->compType ) {
return 1;
}
for( $k = 0; $k < 4; $k++ ) {
if( empty( $a->srtk[$k] )) {
return -1;
}
elseif( empty( $b->srtk[$k] )) {
return 1;
}
$sortStat = strcmp( $a->srtk[$k], $b->srtk[$k] );
if( 0 == $sortStat ) {
continue;
}
return ( 0 < $sortStat ) ? 1 : -1;
}
return 0;
}
/**
* Set sort arguments/parameters in component
*
* @since 2.26.3 - 2018-11-15
* @param CalendarComponent $c valendar component
* @param string $sortArg
* @static
*/
public static function setSortArgs(
CalendarComponent $c,
$sortArg = null
) {
static $INITARR = [ '0', '0', '0', '0' ];
$c->srtk = $INITARR;
if( Vcalendar::VTIMEZONE == $c->compType ) {
if( false === ( $c->srtk[0] = $c->getProperty( Util::$TZID ))) {
$c->srtk[0] = 0;
}
return;
}
elseif( ! is_null( $sortArg )) {
if( Util::isPropInList( $sortArg, Util::$MPROPS1 )) { // all string
$propValues = [];
$c->getProperties( $sortArg, $propValues );
if( ! empty( $propValues )) {
$c->srtk[0] = key( array_slice( $propValues, 0, 1, true ));
}
if( Util::$RELATED_TO == $sortArg ) {
$c->srtk[0] = $c->getProperty( Util::$UID );
}
} // end if( Util::isPropInList( $sortArg, Util::$MPROPS1 ))
elseif( false !== ( $d = $c->getProperty( $sortArg ))) {
$c->srtk[0] = ( Util::isArrayDate( $d )) ? self::arrDate2str( $d ) : $d;
if( Util::$UID == $sortArg ) {
if( false !== ( $d = $c->getProperty( Util::$RECURRENCE_ID ))) {
$c->srtk[1] = self::arrDate2str( $d );
if( false === ( $c->srtk[2] = $c->getProperty( Util::$SEQUENCE ))) {
$c->srtk[2] = 0; // missing sequence equals sequence:0 in comb. with recurr.-id
}
}
else {
$c->srtk[1] = $c->srtk[2] = PHP_INT_MAX;
}
} // end if( Util::$UID == $sortArg )
} // end elseif( false !== ( $d = $c->getProperty( $sortArg )))
return;
} // end elseif( $sortArg )
switch( true ) { // sortkey 0 : dtstart
case ( false !== ( $d = $c->getProperty( UtilSelect::X_CURRENT_DTSTART ))) :
$c->srtk[0] = self::arrDate2str( Util::strDate2ArrayDate( $d[1] ));
break;
case ( false !== ( $d = $c->getProperty( Util::$DTSTART ))) :
$c->srtk[0] = self::arrDate2str( $d );
break;
}
switch( true ) { // sortkey 1 : dtend/due(/duration)
case ( false !== ( $d = $c->getProperty( UtilSelect::X_CURRENT_DTEND ))) :
$c->srtk[1] = self::arrDate2str( Util::strDate2ArrayDate( $d[1] ));
break;
case ( false !== ( $d = $c->getProperty( Util::$DTEND ))) :
$c->srtk[1] = self::arrDate2str( $d );
break;
case ( false !== ( $d = $c->getProperty( UtilSelect::X_CURRENT_DUE ))) :
$c->srtk[1] = self::arrDate2str( Util::strDate2ArrayDate( $d[1] ));
break;
case ( false !== ( $d = $c->getProperty( Util::$DUE ))) :
$c->srtk[1] = self::arrDate2str( $d );
break;
case ( false !== ( $d = $c->getProperty( Util::$DURATION, false, false, true ))) :
$c->srtk[1] = self::arrDate2str( $d );
break;
}
switch( true ) { // sortkey 2 : created/dtstamp
case ( false !== ( $d = $c->getProperty( Util::$CREATED ))) :
$c->srtk[2] = self::arrDate2str( $d );
break;
case ( false !== ( $d = $c->getProperty( Util::$DTSTAMP ))) :
$c->srtk[2] = self::arrDate2str( $d );
break;
}
// sortkey 3 : uid
if( false === ( $c->srtk[3] = $c->getProperty( Util::$UID ))) {
$c->srtk[3] = 0;
}
}
/**
* Return formatted string from (array) date/datetime
*
* @param array $aDate
* @return string
* @access private
* @static
*/
private static function arrDate2str( array $aDate ) {
$str = Util::getYMDString( $aDate );
if( isset( $aDate[Util::$LCHOUR] )) {
$str .= Util::getHisString( $aDate );
}
if( isset( $aDate[Util::$LCtz] ) && ! empty( $aDate[Util::$LCtz] )) {
$str .= $aDate[Util::$LCtz];
}
return $str;
}
/**
* Sort callback function for exdate
*
* @param array $a
* @param array $b
* @return int
* @static
*/
public static function sortExdate1( array $a, array $b ) {
$as = Util::getYMDString( $a );
$as .= ( isset( $a[Util::$LCHOUR] )) ? Util::getHisString( $a ) : null;
$bs = Util::getYMDString( $b );
$bs .= ( isset( $b[Util::$LCHOUR] )) ? Util::getHisString( $b ) : null;
return strcmp( $as, $bs );
}
/**
* Sort callback function for exdate
*
* @param array $a
* @param array $b
* @return int
* @static
*/
public static function sortExdate2( array $a, array $b ) {
$val = reset( $a[Util::$LCvalue] );
$as = Util::getYMDString( $val );
$as .= ( isset( $val[Util::$LCHOUR] )) ? Util::getHisString( $val ) : null;
$val = reset( $b[Util::$LCvalue] );
$bs = Util::getYMDString( $val );
$bs .= ( isset( $val[Util::$LCHOUR] )) ? Util::getHisString( $val ) : null;
return strcmp( $as, $bs );
}
/**
* Sort callback function for freebusy and rdate, sort single property (inside values)
*
* @param array|DateInterval $a
* @param array|DateInterval $b
* @return int
* @static
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.26.7 - 2018-12-03
*/
public static function sortRdate1( $a, $b ) {
$as = null;
if( $a instanceof DateInterval ) {
$as = UtilDuration::dateInterval2String( $a, true );
}
elseif( isset( $a[Util::$LCYEAR] )) {
$as = self::formatdatePart( $a );
}
elseif( isset( $a[0][Util::$LCYEAR] )) {
$as = self::formatdatePart( $a[0] );
if( isset( $a[1] )) {
$as .= self::formatdatePart( $a[1] );
}
}
else {
return 1;
}
$bs = null;
if( $b instanceof DateInterval ) {
$bs = UtilDuration::dateInterval2String( $b, true );
}
elseif( isset( $b[Util::$LCYEAR] )) {
$bs = self::formatdatePart( $b );
}
elseif( isset( $b[0][Util::$LCYEAR] )) {
$bs = self::formatdatePart( $b[0] );
if( isset( $b[1] )) {
$bs .= self::formatdatePart( $b[1] );
}
}
else {
return -1;
}
return strcmp( $as, $bs );
}
/**
* Sort callback function for rdate, sort multiple RDATEs in order (after 1st datetime/date/period)
*
* @param array|DateInterval $a
* @param array|DateInterval $b
* @return int
* @static
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.26.7 - 2018-12-03
*/
public static function sortRdate2( $a, $b ) {
$as = null;
if( $a instanceof DateInterval ) {
$as = UtilDuration::dateInterval2String( $a, true );
}
elseif( isset( $a[Util::$LCvalue][0][Util::$LCYEAR] )) {
$as = self::formatdatePart( $a[Util::$LCvalue][0] );
}
elseif( isset( $a[Util::$LCvalue][0][0][Util::$LCYEAR] )) {
$as = self::formatdatePart( $a[Util::$LCvalue][0][0] );
if( isset( $a[Util::$LCvalue][0][1] )) {
$as .= self::formatdatePart( $a[Util::$LCvalue][0][1] );
}
}
else {
return 1;
}
$bs = null;
if( $b instanceof DateInterval ) {
$bs = UtilDuration::dateInterval2String( $b, true );
}
elseif( isset( $b[Util::$LCvalue][0][Util::$LCYEAR] )) {
$bs = self::formatdatePart( $b[Util::$LCvalue][0] );
}
elseif( isset( $a[Util::$LCvalue][0][0][Util::$LCYEAR] )) {
$bs = self::formatdatePart( $b[Util::$LCvalue][0][0] );
if( isset( $b[Util::$LCvalue][0][1] )) {
$bs .= self::formatdatePart( $b[Util::$LCvalue][0][1] );
}
}
else {
return -1;
}
return strcmp( $as, $bs );
}
/**
* Format date
*
* @param array|DateInterval $part
* @return string
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.26.7 - 2018-11-29
*/
private static function formatdatePart( $part ) {
if( $part instanceof DateInterval ) {
$str = UtilDuration::dateInterval2String( $part, true );
}
elseif( isset( $part[Util::$LCYEAR] )) {
$str = Util::getYMDString( $part );
$str .= ( isset( $part[Util::$LCHOUR] )) ? Util::getHisString( $part ) : null;
}
else {
$str = UtilDuration::duration2str( $part );
}
return $str;
}
}

View File

@@ -0,0 +1,179 @@
<?php
/**
* iCalcreator, the PHP class package managing iCal (rfc2445/rfc5445) calendar information.
*
* copyright (c) 2007-2019 Kjell-Inge Gustafsson, kigkonsult, All rights reserved
* Link https://kigkonsult.se
* Package iCalcreator
* Version 2.26.8
* License Subject matter of licence is the software iCalcreator.
* The above copyright, link, package and version notices,
* this licence notice and the invariant [rfc5545] PRODID result use
* as implemented and invoked in iCalcreator shall be included in
* all copies or substantial portions of the iCalcreator.
*
* iCalcreator 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 3 of the License,
* or (at your option) any later version.
*
* iCalcreator 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 iCalcreator. If not, see <https://www.gnu.org/licenses/>.
*
* This file is a part of iCalcreator.
*/
namespace Kigkonsult\Icalcreator;
use Kigkonsult\Icalcreator\Util\Util;
use Kigkonsult\Icalcreator\Util\UtilDuration;
use function sprintf;
use function strtoupper;
/**
* iCalcreator VALARM component class
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.26 - 2018-11-10
*/
class Valarm extends CalendarComponent
{
use Traits\ACTIONtrait,
Traits\ATTACHtrait,
Traits\ATTENDEEtrait,
Traits\DESCRIPTIONtrait,
Traits\DURATIONtrait,
Traits\REPEATtrait,
Traits\SUMMARYtrait,
Traits\TRIGGERtrait;
/**
* Constructor for calendar component VALARM object
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.22.20 - 2017-02-01
* @param array $config
*/
public function __construct( $config = [] ) {
static $A = 'a';
parent::__construct();
$this->setConfig( Util::initConfig( $config ));
$this->cno = $A . parent::getObjectNo();
}
/**
* Destructor
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.26 - 2018-11-10
*/
public function __destruct() {
unset( $this->xprop,
$this->components,
$this->unparsed,
$this->config,
$this->propix,
$this->propdelix
);
unset( $this->compType,
$this->cno,
$this->srtk
);
unset( $this->action,
$this->attach,
$this->attendee,
$this->description,
$this->duration,
$this->repeat,
$this->summary,
$this->trigger
);
}
/**
* Return formatted output for calendar component VALARM object instance
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.26 - 2018-11-10
* @return string
*/
public function createComponent() {
$compType = strtoupper( $this->compType );
$component = sprintf( Util::$FMTBEGIN, $compType );
$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();
return $component . sprintf( Util::$FMTEND, $compType );
}
/**
* Return Valarm component property value/params,
*
* If arg $inclParam, return array with keys VALUE/PARAMS.
*
* @param string $propName
* @param int $propix specific property in case of multiply occurences
* @param bool $inclParam
* @param bool $specform
* @return mixed
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.26.7 - 2018-12-02
*/
public function getProperty(
$propName = null,
$propix = null,
$inclParam = null,
$specform = null
) {
switch( strtoupper( $propName )) {
case Util::$ACTION:
if( isset( $this->action[Util::$LCvalue] )) {
return ( $inclParam ) ? $this->action : $this->action[Util::$LCvalue];
}
break;
case Util::$REPEAT:
if( isset( $this->repeat[Util::$LCvalue] )) {
return ( $inclParam ) ? $this->repeat : $this->repeat[Util::$LCvalue];
}
break;
case Util::$TRIGGER:
if( ! isset( $this->trigger[Util::$LCvalue] )) {
break;
}
if( isset( $this->trigger[Util::$LCvalue]['invert'] )) { // fix pre 7.0.5 bug
$dateInterval = UtilDuration::DateIntervalArr2DateInterval( $this->trigger[Util::$LCvalue] );
$value = UtilDuration::dateInterval2arr( $dateInterval );
$value[UtilDuration::$BEFORE] =
( 0 < $this->trigger[Util::$LCvalue]['invert'] ) ? true : false;
$value[UtilDuration::$RELATEDSTART] =
( isset( $this->trigger[Util::$LCparams ][UtilDuration::$RELATED] ) &&
( UtilDuration::$END == $this->trigger[Util::$LCparams ][UtilDuration::$RELATED] ))
? false
: true;
}
else {
$value = $this->trigger[Util::$LCvalue];
}
return ( $inclParam )
? [ Util::$LCvalue => $value, Util::$LCparams => $this->trigger[Util::$LCparams ] ]
: $value;
break;
default:
return parent::getProperty( $propName, $propix, $inclParam, $specform );
break;
}
return false;
}
}

View File

@@ -0,0 +1,205 @@
<?php
/**
* iCalcreator, the PHP class package managing iCal (rfc2445/rfc5445) calendar information.
*
* copyright (c) 2007-2019 Kjell-Inge Gustafsson, kigkonsult, All rights reserved
* Link https://kigkonsult.se
* Package iCalcreator
* Version 2.26.8
* License Subject matter of licence is the software iCalcreator.
* The above copyright, link, package and version notices,
* this licence notice and the invariant [rfc5545] PRODID result use
* as implemented and invoked in iCalcreator shall be included in
* all copies or substantial portions of the iCalcreator.
*
* iCalcreator 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 3 of the License,
* or (at your option) any later version.
*
* iCalcreator 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 iCalcreator. If not, see <https://www.gnu.org/licenses/>.
*
* This file is a part of iCalcreator.
*/
namespace Kigkonsult\Icalcreator;
use Kigkonsult\Icalcreator\Util\Util;
use function sprintf;
use function strtoupper;
/**
* iCalcreator VEVENT component class
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.26 - 2018-11-10
*/
class Vevent extends CalendarComponent
{
use Traits\ATTACHtrait,
Traits\ATTENDEEtrait,
Traits\CATEGORIEStrait,
Traits\CLASStrait,
Traits\COMMENTtrait,
Traits\CONTACTtrait,
Traits\CREATEDtrait,
Traits\DESCRIPTIONtrait,
Traits\DTENDtrait,
Traits\DTSTAMPtrait,
Traits\DTSTARTtrait,
Traits\DURATIONtrait,
Traits\EXDATEtrait,
Traits\EXRULEtrait,
Traits\GEOtrait,
Traits\LAST_MODIFIEDtrait,
Traits\LOCATIONtrait,
Traits\ORGANIZERtrait,
Traits\PRIORITYtrait,
Traits\RDATEtrait,
Traits\RECURRENCE_IDtrait,
Traits\RELATED_TOtrait,
Traits\REQUEST_STATUStrait,
Traits\RESOURCEStrait,
Traits\RRULEtrait,
Traits\SEQUENCEtrait,
Traits\STATUStrait,
Traits\SUMMARYtrait,
Traits\TRANSPtrait,
Traits\UIDtrait,
Traits\URLtrait;
/**
* Constructor for calendar component VEVENT object
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.22.20 - 2017-02-01
* @param array $config
*/
public function __construct( $config = [] ) {
static $E = 'e';
parent::__construct();
$this->setConfig( Util::initConfig( $config ));
$this->cno = $E . parent::getObjectNo();
}
/**
* Destructor
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.26 - 2018-11-10
*/
public function __destruct() {
if( ! empty( $this->components )) {
foreach( $this->components as $cix => $component ) {
$this->components[$cix]->__destruct();
}
}
unset( $this->xprop,
$this->components,
$this->unparsed,
$this->config,
$this->compix,
$this->propix,
$this->propdelix
);
unset( $this->compType,
$this->cno,
$this->srtk
);
unset( $this->attach,
$this->attendee,
$this->categories,
$this->class,
$this->comment,
$this->contact,
$this->created,
$this->description,
$this->dtend,
$this->dtstamp,
$this->dtstart,
$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->uid,
$this->url
);
}
/**
* Return formatted output for calendar component VEVENT object instance
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.26 - 2018-11-10
* @return string
*/
public function createComponent() {
$compType = strtoupper( $this->compType );
$component = sprintf( Util::$FMTBEGIN, $compType );
$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();
return $component . sprintf( Util::$FMTEND, $compType );
}
/**
* Return Valarm object instance, CalendarComponent::newComponent() wrapper
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.26 - 2018-11-10
* @return object
*/
public function newValarm() {
return $this->newComponent( self::VALARM );
}
}

View File

@@ -0,0 +1,132 @@
<?php
/**
* iCalcreator, the PHP class package managing iCal (rfc2445/rfc5445) calendar information.
*
* copyright (c) 2007-2019 Kjell-Inge Gustafsson, kigkonsult, All rights reserved
* Link https://kigkonsult.se
* Package iCalcreator
* Version 2.26.8
* License Subject matter of licence is the software iCalcreator.
* The above copyright, link, package and version notices,
* this licence notice and the invariant [rfc5545] PRODID result use
* as implemented and invoked in iCalcreator shall be included in
* all copies or substantial portions of the iCalcreator.
*
* iCalcreator 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 3 of the License,
* or (at your option) any later version.
*
* iCalcreator 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 iCalcreator. If not, see <https://www.gnu.org/licenses/>.
*
* This file is a part of iCalcreator.
*/
namespace Kigkonsult\Icalcreator;
use Kigkonsult\Icalcreator\Util\Util;
use function sprintf;
use function strtoupper;
/**
* iCalcreator VFREEBUSY component class
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.26 - 2018-11-10
*/
class Vfreebusy extends CalendarComponent
{
use Traits\ATTENDEEtrait,
Traits\COMMENTtrait,
Traits\CONTACTtrait,
Traits\DTENDtrait,
Traits\DTSTAMPtrait,
Traits\DTSTARTtrait,
Traits\DURATIONtrait,
Traits\FREEBUSYtrait,
Traits\ORGANIZERtrait,
Traits\REQUEST_STATUStrait,
Traits\UIDtrait,
Traits\URLtrait;
/**
* Constructor for calendar component VFREEBUSY object
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.22.20 - 2017-02-01
* @param array $config
*/
public function __construct( $config = [] ) {
static $F = 'f';
parent::__construct();
$this->setConfig( Util::initConfig( $config ));
$this->cno = $F . parent::getObjectNo();
}
/**
* Destructor
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.26 - 2018-11-10
*/
public function __destruct() {
unset( $this->xprop,
$this->components,
$this->unparsed,
$this->config,
$this->propix,
$this->compix,
$this->propdelix
);
unset( $this->compType,
$this->cno,
$this->srtk
);
unset( $this->attendee,
$this->comment,
$this->contact,
$this->dtend,
$this->dtstamp,
$this->dtstart,
$this->duration,
$this->freebusy,
$this->organizer,
$this->requeststatus,
$this->uid,
$this->url
);
}
/**
* Return formatted output for calendar component VFREEBUSY object instance
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.26 - 2018-11-10
* @return string
*/
public function createComponent() {
$compType = strtoupper( $this->compType );
$component = sprintf( Util::$FMTBEGIN, $compType );
$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();
return $component . sprintf( Util::$FMTEND, $compType );
}
}

View File

@@ -0,0 +1,168 @@
<?php
/**
* iCalcreator, the PHP class package managing iCal (rfc2445/rfc5445) calendar information.
*
* copyright (c) 2007-2019 Kjell-Inge Gustafsson, kigkonsult, All rights reserved
* Link https://kigkonsult.se
* Package iCalcreator
* Version 2.26.8
* License Subject matter of licence is the software iCalcreator.
* The above copyright, link, package and version notices,
* this licence notice and the invariant [rfc5545] PRODID result use
* as implemented and invoked in iCalcreator shall be included in
* all copies or substantial portions of the iCalcreator.
*
* iCalcreator 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 3 of the License,
* or (at your option) any later version.
*
* iCalcreator 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 iCalcreator. If not, see <https://www.gnu.org/licenses/>.
*
* This file is a part of iCalcreator.
*/
namespace Kigkonsult\Icalcreator;
use Kigkonsult\Icalcreator\Util\Util;
use function sprintf;
use function strtoupper;
/**
* iCalcreator VJOURNAL component class
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.26 - 2018-11-10
*/
class Vjournal extends CalendarComponent
{
use Traits\ATTACHtrait,
Traits\ATTENDEEtrait,
Traits\CATEGORIEStrait,
Traits\CLASStrait,
Traits\COMMENTtrait,
Traits\CONTACTtrait,
Traits\CREATEDtrait,
Traits\DESCRIPTIONtrait,
Traits\DTSTAMPtrait,
Traits\DTSTARTtrait,
Traits\EXDATEtrait,
Traits\EXRULEtrait,
Traits\LAST_MODIFIEDtrait,
Traits\ORGANIZERtrait,
Traits\RDATEtrait,
Traits\RECURRENCE_IDtrait,
Traits\RELATED_TOtrait,
Traits\REQUEST_STATUStrait,
Traits\RRULEtrait,
Traits\SEQUENCEtrait,
Traits\STATUStrait,
Traits\SUMMARYtrait,
Traits\UIDtrait,
Traits\URLtrait;
/**
* Constructor for calendar component VJOURNAL object
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.22.20 - 2017-02-01
* @param array $config
*/
public function __construct( $config = [] ) {
static $J = 'j';
parent::__construct();
$this->setConfig( Util::initConfig( $config ));
$this->cno = $J . parent::getObjectNo();
}
/**
* Destructor
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.26 - 2018-11-10
*/
public function __destruct() {
unset( $this->xprop,
$this->components,
$this->unparsed,
$this->config,
$this->compix,
$this->propix,
$this->propdelix
);
unset( $this->compType,
$this->cno,
$this->srtk
);
unset( $this->attach,
$this->attendee,
$this->categories,
$this->class,
$this->comment,
$this->contact,
$this->created,
$this->description,
$this->dtstamp,
$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->uid,
$this->url
);
}
/**
* Return formatted output for calendar component VJOURNAL object instance
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.26 - 2018-11-10
* @return string
*/
public function createComponent() {
$compType = strtoupper( $this->compType );
$component = sprintf( Util::$FMTBEGIN, $compType );
$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();
return $component . sprintf( Util::$FMTEND, $compType );
}
}

View File

@@ -0,0 +1,215 @@
<?php
/**
* iCalcreator, the PHP class package managing iCal (rfc2445/rfc5445) calendar information.
*
* copyright (c) 2007-2019 Kjell-Inge Gustafsson, kigkonsult, All rights reserved
* Link https://kigkonsult.se
* Package iCalcreator
* Version 2.26.8
* License Subject matter of licence is the software iCalcreator.
* The above copyright, link, package and version notices,
* this licence notice and the invariant [rfc5545] PRODID result use
* as implemented and invoked in iCalcreator shall be included in
* all copies or substantial portions of the iCalcreator.
*
* iCalcreator 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 3 of the License,
* or (at your option) any later version.
*
* iCalcreator 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 iCalcreator. If not, see <https://www.gnu.org/licenses/>.
*
* This file is a part of iCalcreator.
*/
namespace Kigkonsult\Icalcreator;
use Kigkonsult\Icalcreator\Util\Util;
use function is_array;
use function sprintf;
use function strtolower;
use function strtoupper;
use function ucfirst;
/**
* iCalcreator VTIMEZONE component class
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.26 - 2018-11-10
*/
class Vtimezone extends CalendarComponent
{
use Traits\COMMENTtrait,
Traits\DTSTARTtrait,
Traits\LAST_MODIFIEDtrait,
Traits\RDATEtrait,
Traits\RRULEtrait,
Traits\TZIDtrait,
Traits\TZNAMEtrait,
Traits\TZOFFSETFROMtrait,
Traits\TZOFFSETTOtrait,
Traits\TZURLtrait;
/**
* @var string $timezonetype Vtimezone type value
* @access protected
*/
protected $timezonetype;
/**
* Constructor for calendar component VTIMEZONE object
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.26 - 2018-11-10
* @param mixed $timezonetype default false ( STANDARD / DAYLIGHT )
* @param array $config
*/
public function __construct( $timezonetype = null, $config = [] ) {
static $TZ = 'tz';
if( is_array( $timezonetype )) {
$config = $timezonetype;
$timezonetype = null;
}
$this->timezonetype = ( empty( $timezonetype )) ? self::VTIMEZONE : ucfirst( strtolower( $timezonetype ));
parent::__construct();
$this->setConfig( Util::initConfig( $config ));
$prf = ( empty( $timezonetype )) ? $TZ : \substr( $timezonetype, 0, 1 );
$this->cno = $prf . parent::getObjectNo();
}
/**
* Destructor
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.26 - 2018-11-10
*/
public function __destruct() {
if( ! empty( $this->components )) {
foreach( $this->components as $cix => $component ) {
$this->components[$cix]->__destruct();
}
}
unset( $this->xprop,
$this->components,
$this->unparsed,
$this->config,
$this->propix,
$this->compix,
$this->propdelix
);
unset( $this->compType,
$this->cno,
$this->srtk
);
unset( $this->comment,
$this->dtstart,
$this->lastmodified,
$this->rdate,
$this->rrule,
$this->tzid,
$this->tzname,
$this->tzoffsetfrom,
$this->tzoffsetto,
$this->tzurl,
$this->timezonetype
);
}
/**
* Return formatted output for calendar component VTIMEZONE object instance
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.26 - 2018-11-10
* @return string
*/
public function createComponent() {
$compType = strtoupper(( isset( $this->timezonetype )) ? $this->timezonetype : $this->compType );
$component = sprintf( Util::$FMTBEGIN, $compType );
$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();
return $component . sprintf( Util::$FMTEND, $compType );
}
/**
* Return Vtimezone component property value/params
*
* If arg $inclParam, return array with keys VALUE/PARAMS
*
* @param string $propName
* @param int $propix specific property in case of multiply occurences
* @param bool $inclParam
* @param bool $specform
* @return mixed
*/
public function getProperty(
$propName = null,
$propix = null,
$inclParam = false,
$specform = false
) {
switch( strtoupper( $propName )) {
case Util::$TZID:
if( isset( $this->tzid[Util::$LCvalue] )) {
return ( $inclParam ) ? $this->tzid : $this->tzid[Util::$LCvalue];
}
break;
case Util::$TZOFFSETFROM:
if( isset( $this->tzoffsetfrom[Util::$LCvalue] )) {
return ( $inclParam ) ? $this->tzoffsetfrom : $this->tzoffsetfrom[Util::$LCvalue];
}
break;
case Util::$TZOFFSETTO:
if( isset( $this->tzoffsetto[Util::$LCvalue] )) {
return ( $inclParam ) ? $this->tzoffsetto : $this->tzoffsetto[Util::$LCvalue];
}
break;
case Util::$TZURL:
if( isset( $this->tzurl[Util::$LCvalue] )) {
return ( $inclParam ) ? $this->tzurl : $this->tzurl[Util::$LCvalue];
}
break;
default:
return parent::getProperty( $propName, $propix, $inclParam, $specform );
break;
}
return false;
}
/**
* Return timezone standard object instance, Vtimezone::newComponent() wrapper
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.26 - 2018-11-10
* @return object
*/
public function newStandard() {
return $this->newComponent( self::STANDARD );
}
/**
* Return timezone daylight object instance, Vtimezone::newComponent() wrapper
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.26 - 2018-11-10
* @return object
*/
public function newDaylight() {
return $this->newComponent( self::DAYLIGHT );
}
}

View File

@@ -0,0 +1,209 @@
<?php
/**
* iCalcreator, the PHP class package managing iCal (rfc2445/rfc5445) calendar information.
*
* copyright (c) 2007-2019 Kjell-Inge Gustafsson, kigkonsult, All rights reserved
* Link https://kigkonsult.se
* Package iCalcreator
* Version 2.26.8
* License Subject matter of licence is the software iCalcreator.
* The above copyright, link, package and version notices,
* this licence notice and the invariant [rfc5545] PRODID result use
* as implemented and invoked in iCalcreator shall be included in
* all copies or substantial portions of the iCalcreator.
*
* iCalcreator 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 3 of the License,
* or (at your option) any later version.
*
* iCalcreator 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 iCalcreator. If not, see <https://www.gnu.org/licenses/>.
*
* This file is a part of iCalcreator.
*/
namespace Kigkonsult\Icalcreator;
use Kigkonsult\Icalcreator\Util\Util;
use function sprintf;
use function strtoupper;
/**
* iCalcreator VTODO component class
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.26 - 2018-11-10
*/
class Vtodo extends CalendarComponent
{
use Traits\ATTACHtrait,
Traits\ATTENDEEtrait,
Traits\CATEGORIEStrait,
Traits\CLASStrait,
Traits\COMMENTtrait,
Traits\COMPLETEDtrait,
Traits\CONTACTtrait,
Traits\CREATEDtrait,
Traits\DESCRIPTIONtrait,
Traits\DTSTAMPtrait,
Traits\DTSTARTtrait,
Traits\DUEtrait,
Traits\DURATIONtrait,
Traits\EXDATEtrait,
Traits\EXRULEtrait,
Traits\GEOtrait,
Traits\LAST_MODIFIEDtrait,
Traits\LOCATIONtrait,
Traits\ORGANIZERtrait,
Traits\PERCENT_COMPLETEtrait,
Traits\PRIORITYtrait,
Traits\RDATEtrait,
Traits\RECURRENCE_IDtrait,
Traits\RELATED_TOtrait,
Traits\REQUEST_STATUStrait,
Traits\RESOURCEStrait,
Traits\RRULEtrait,
Traits\SEQUENCEtrait,
Traits\STATUStrait,
Traits\SUMMARYtrait,
Traits\UIDtrait,
Traits\URLtrait;
/**
* Constructor for calendar component VTODO object
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.26 - 2018-11-10
* @param array $config
*/
public function __construct( $config = [] ) {
static $T = 't';
parent::__construct();
$this->setConfig( Util::initConfig( $config ));
$this->cno = $T . parent::getObjectNo();
}
/**
* Destructor
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.26 - 2018-11-10
*/
public function __destruct() {
if( ! empty( $this->components )) {
foreach( $this->components as $cix => $component ) {
$this->components[$cix]->__destruct();
}
}
unset( $this->xprop,
$this->components,
$this->unparsed,
$this->config,
$this->propix,
$this->compix,
$this->propdelix
);
unset( $this->compType,
$this->cno,
$this->srtk
);
unset( $this->attach,
$this->attendee,
$this->categories,
$this->class,
$this->comment,
$this->completed,
$this->contact,
$this->created,
$this->description,
$this->dtstamp,
$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->uid,
$this->url
);
}
/**
* Return formatted output for calendar component VTODO object instance
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.26 - 2018-11-10
* @return string
*/
public function createComponent() {
$compType = strtoupper( $this->compType );
$component = sprintf( Util::$FMTBEGIN, $compType );
$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();
return $component . sprintf( Util::$FMTEND, $compType );
}
/**
* Return Valarm object instance, CalendarComponent::newComponent() wrapper
*
* @author Kjell-Inge Gustafsson, kigkonsult <ical@kigkonsult.se>
* @since 2.26 - 2018-11-10
* @return object
*/
public function newValarm() {
return $this->newComponent( self::VALARM );
}
}

View File

@@ -0,0 +1,369 @@
<?php
/**
* iCalcreator, the PHP class package managing iCal (rfc2445/rfc5445) calendar information.
*
* copyright (c) 2007-2019 Kjell-Inge Gustafsson, kigkonsult, All rights reserved
* Link https://kigkonsult.se
* Package iCalcreator
* Version 2.26.8
* License Subject matter of licence is the software iCalcreator.
* The above copyright, link, package and version notices,
* this licence notice and the invariant [rfc5545] PRODID result use
* as implemented and invoked in iCalcreator shall be included in
* all copies or substantial portions of the iCalcreator.
*
* iCalcreator 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 3 of the License,
* or (at your option) any later version.
*
* iCalcreator 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 iCalcreator. If not, see <https://www.gnu.org/licenses/>.
*
* This file is a part of iCalcreator.
*/
/**
* 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
*/
namespace Kigkonsult\Icalcreator;
use Kigkonsult\Icalcreator\Util\Util;
use function array_merge;
use function count;
use function explode;
use function getdate;
use function is_array;
use function mktime;
use function sort;
use function sprintf;
use function strtotime;
use function substr;
use function time;
/**
* 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 ) {
static $OFFSETHIS = 'offsetHis';
static $OFFSETSEC = 'offsetSec';
static $TZBEFORE = 'tzbefore';
static $TZAFTER = 'tzafter';
static $TZNAME = 'tzname';
if( is_array( $timestamp )) {
$timestamp = \gmmktime(
$timestamp[Util::$LCHOUR],
$timestamp[Util::$LCMIN],
$timestamp[Util::$LCSEC],
$timestamp[Util::$LCMONTH],
$timestamp[Util::$LCDAY],
$timestamp[Util::$LCYEAR]
);
}
$tzoffset = [];
// 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][Util::$LCTIMESTAMP] ) {
// 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][Util::$LCTIMESTAMP] ) {
// 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][Util::$LCTIMESTAMP] ) &&
( $timestamp < $tzdatearray[$i + 1][Util::$LCTIMESTAMP] )) {
$tzoffset[$OFFSETHIS] = $tzdatearray[$i][$TZAFTER][$OFFSETHIS];
$tzoffset[$OFFSETSEC] = $tzdatearray[$i][$TZAFTER][$OFFSETSEC];
$tzoffset[$TZNAME] = $tzdatearray[$i][$TZAFTER][$TZNAME];
break;
}
}
}
}
return $tzoffset;
}
/**
* Return an array containing all the timezone data in the Vcalendar object
*
* @param Vcalendar $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 ) {
static $TZID = 'tzid';
$timezonedata = [];
while( $vtz = $Vcalendar->getComponent( Vcalendar::VTIMEZONE )) {
$tzid = $vtz->getProperty( $TZID );
$alltzdates = [];
while( $vtzc = $vtz->getComponent( Vcalendar::STANDARD )) {
$newtzdates = expandTimezoneDates( $vtzc );
$alltzdates = array_merge( $alltzdates, $newtzdates );
}
while( $vtzc = $vtz->getComponent( Vcalendar::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)
* @todo fix quickfix...
*/
function expandTimezoneDates( $vtzc ) {
static $OFFSETHIS = 'offsetHis';
static $OFFSETSEC = 'offsetSec';
static $TZBEFORE = 'tzbefore';
static $TZAFTER = 'tzafter';
static $TZNAME = 'tzname';
static $YEARLY = 'YEARLY';
static $FMTDATE = '%04d%02d%02dT%02d%02d%02d';
static $DAYNAMES = [
'SU' => 'Sunday',
'MO' => 'Monday',
'TU' => 'Tuesday',
'WE' => 'Wednesday',
'TH' => 'Thursday',
'FR' => 'Friday',
'SA' => 'Saturday',
];
static $MON = 'mon';
static $MDAY = 'mday';
static $HOURS = 'hours';
static $MINUTES = 'minutes';
static $SECONDS = 'seconds';
static $MINUS1WEEK = '-1 week';
static $PLUS1MONTH = '+1 month';
static $SP1WEEK = ' week';
static $SP1YEAR = ' year';
static $PLUS10YEAR = '+10 year';
$tzdates = [];
// prepare time zone "description" to attach to each change
$tzbefore = [];
$tzbefore[$OFFSETHIS] = $vtzc->getProperty( Util::$TZOFFSETFROM );
$tzbefore[$OFFSETSEC] = Util::tz2offset( $tzbefore[$OFFSETHIS] );
if(( Util::$MINUS != substr((string) $tzbefore[$OFFSETSEC], 0, 1 )) &&
( Util::$PLUS != substr((string) $tzbefore[$OFFSETSEC], 0, 1 ))) {
$tzbefore[$OFFSETSEC] = Util::$PLUS . $tzbefore[$OFFSETSEC];
}
$tzafter = [];
$tzafter[$OFFSETHIS] = $vtzc->getProperty( Util::$TZOFFSETTO );
$tzafter[$OFFSETSEC] = Util::tz2offset( $tzafter[$OFFSETHIS] );
if(( Util::$MINUS != substr((string) $tzafter[$OFFSETSEC], 0, 1 )) &&
( Util::$PLUS != substr((string) $tzafter[$OFFSETSEC], 0, 1 ))) {
$tzafter[$OFFSETSEC] = Util::$PLUS . $tzafter[$OFFSETSEC];
}
if( false === ( $tzafter[$TZNAME] = $vtzc->getProperty( Util::$TZNAME ))) {
$tzafter[$TZNAME] = $tzafter[$OFFSETHIS];
}
// find out where to start from
$dtstart = $vtzc->getProperty( Util::$DTSTART );
$dtstarttimestamp = mktime( $dtstart[Util::$LCHOUR],
$dtstart[Util::$LCMIN],
$dtstart[Util::$LCSEC],
$dtstart[Util::$LCMONTH],
$dtstart[Util::$LCDAY],
$dtstart[Util::$LCYEAR]
);
if( ! isset( $dtstart[Util::$UNPARSEDTEXT] )) // ??
{
$dtstart[Util::$UNPARSEDTEXT] = sprintf( $FMTDATE, $dtstart[Util::$LCYEAR],
$dtstart[Util::$LCMONTH],
$dtstart[Util::$LCDAY],
$dtstart[Util::$LCHOUR],
$dtstart[Util::$LCMIN],
$dtstart[Util::$LCSEC]
);
}
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[Util::$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[] = [
Util::$LCTIMESTAMP => $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( Util::$RRULE );
if( is_array( $rrule )) {
if( $rrule[Util::$FREQ] == $YEARLY ) {
// calculate transition dates starting from DTSTART
$offsetchangetimestamp = $dtstarttimestamp;
// calculate transition dates until 10 years in the future
$stoptimestamp = strtotime( $PLUS10YEAR, time());
// if UNTIL is set, calculate until then (however far ahead)
if( isset( $rrule[Util::$UNTIL] ) && ( $rrule[Util::$UNTIL] != Util::$SP0 )) {
$stoptimestamp = mktime(
$rrule[Util::$UNTIL][Util::$LCHOUR],
$rrule[Util::$UNTIL][Util::$LCMIN],
$rrule[Util::$UNTIL][Util::$LCSEC],
$rrule[Util::$UNTIL][Util::$LCMONTH],
$rrule[Util::$UNTIL][Util::$LCDAY],
$rrule[Util::$UNTIL][Util::$LCYEAR]
);
}
$count = 0;
$stopcount = isset( $rrule[Util::$COUNT] ) ? $rrule[Util::$COUNT] : 0;
// 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[Util::$BYMONTH] ) && ( $rrule[Util::$BYMONTH] != 0 )) {
// set the month
$datearray[$MON] = $rrule[Util::$BYMONTH];
}
if( isset( $rrule[Util::$BYMONTHDAY] )) { // start quickfix...
// set first found/specific day of month
$datearray[$MDAY] = ( is_array( $rrule[Util::$BYMONTHDAY] ))
? reset( $rrule[Util::$BYMONTHDAY] )
: $rrule[Util::$BYMONTHDAY]; // end quickfix
}
elseif( isset( $rrule[Util::$BYDAY] ) && is_array( $rrule[Util::$BYDAY] )) { // update: 'isset...'
// 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[Util::$LCYEAR]
);
if( $rrule[Util::$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[Util::$BYDAY][Util::$DAY]],
$offsetchangetimestamp
);
$offsetchangetimestamp = strtotime( $MINUS1WEEK, $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( $PLUS1MONTH, $offsetchangetimestamp );
$offsetchangetimestamp = strtotime( $DAYNAMES[$rrule[Util::$BYDAY][Util::$DAY]],
$offsetchangetimestamp
);
}
// now move forward or back the appropriate number of weeks, into the month we want
$offsetchangetimestamp = strtotime( $rrule[Util::$BYDAY][0] . $SP1WEEK, $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[Util::$LCYEAR]
);
// add this change to the array of changes
$tzdates[] = [
Util::$LCTIMESTAMP => $offsetchangetimestamp,
$TZBEFORE => $tzbefore,
$TZAFTER => $tzafter,
];
// update \counters (timestamp and \count)
$offsetchangetimestamp = strtotime( Util::$PLUS
. (( isset( $rrule[Util::$INTERVAL] ) && ( $rrule[Util::$INTERVAL] != 0 ))
? $rrule[Util::$INTERVAL] : 1 )
. $SP1YEAR, $offsetchangetimestamp
);
$count += 1;
}
}
}
// generate dates according to RDATE lines
while( $rdates = $vtzc->getProperty( Util::$RDATE )) {
if( is_array( $rdates )) {
foreach( $rdates as $rdate ) {
// convert the explicit change date to a timestamp
$offsetchangetimestamp = \mktime(
$rdate[Util::$LCHOUR],
$rdate[Util::$LCMIN],
$rdate[Util::$LCSEC] + $diff,
$rdate[Util::$LCMONTH],
$rdate[Util::$LCDAY],
$rdate[Util::$LCYEAR]
);
// add this change to the array of changes
$tzdates[] = [
Util::$LCTIMESTAMP => $offsetchangetimestamp,
$TZBEFORE => $tzbefore,
$TZAFTER => $tzafter,
];
}
}
}
return $tzdates;
}