Merge branch 'master' of ssh://git.kolabsys.com/git/roundcube
This commit is contained in:
commit
f5eea012d1
10 changed files with 3033 additions and 15 deletions
|
@ -360,7 +360,7 @@ class kolab_calendar
|
||||||
raise_error(array(
|
raise_error(array(
|
||||||
'code' => 600, 'type' => 'php',
|
'code' => 600, 'type' => 'php',
|
||||||
'file' => __FILE__, 'line' => __LINE__,
|
'file' => __FILE__, 'line' => __LINE__,
|
||||||
'message' => "Error undeleting a contact object $uid from the Kolab server"),
|
'message' => "Error undeleting the event object $uid from the Kolab server"),
|
||||||
true, false);
|
true, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -373,10 +373,7 @@ class kolab_calendar
|
||||||
*/
|
*/
|
||||||
public function _get_recurring_events($event, $start, $end, $event_id = null)
|
public function _get_recurring_events($event, $start, $end, $event_id = null)
|
||||||
{
|
{
|
||||||
// include library class
|
$recurrence = new kolab_date_recurrence($event);
|
||||||
require_once($this->cal->home . '/lib/calendar_recurrence.php');
|
|
||||||
|
|
||||||
$recurrence = new calendar_recurrence($this->cal, $event);
|
|
||||||
|
|
||||||
$events = array();
|
$events = array();
|
||||||
$duration = $event['end'] - $event['start'];
|
$duration = $event['end'] - $event['start'];
|
||||||
|
|
|
@ -5,7 +5,8 @@
|
||||||
* PEAR/Date/Calc.php, Horde/Date/Recurrence.php
|
* PEAR/Date/Calc.php, Horde/Date/Recurrence.php
|
||||||
*/
|
*/
|
||||||
|
|
||||||
require_once(dirname(__FILE__) . '/Horde_Date.php');
|
if (!class_exists('Horde_Date'))
|
||||||
|
require_once(dirname(__FILE__) . '/Horde_Date.php');
|
||||||
|
|
||||||
// {{{ Header
|
// {{{ Header
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,8 @@
|
||||||
* Horde/String.php, Horde/iCalendar.php, Horde/iCalendar/*.php
|
* Horde/String.php, Horde/iCalendar.php, Horde/iCalendar/*.php
|
||||||
*/
|
*/
|
||||||
|
|
||||||
require_once(dirname(__FILE__) . '/Horde_Date.php');
|
if (!class_exists('Horde_Date'))
|
||||||
|
require_once(dirname(__FILE__) . '/Horde_Date.php');
|
||||||
|
|
||||||
|
|
||||||
$GLOBALS['_HORDE_STRING_CHARSET'] = 'iso-8859-1';
|
$GLOBALS['_HORDE_STRING_CHARSET'] = 'iso-8859-1';
|
||||||
|
|
38
plugins/libkolab/bin/get_horde_date.sh
Executable file
38
plugins/libkolab/bin/get_horde_date.sh
Executable file
|
@ -0,0 +1,38 @@
|
||||||
|
#!/bin/sh
|
||||||
|
|
||||||
|
# Copy Horde_Date_Recurrence classes and dependencies to stdout.
|
||||||
|
# This will create a standalone copy of the classes requried for date recurrence computation.
|
||||||
|
|
||||||
|
SRCDIR=$1
|
||||||
|
|
||||||
|
if [ ! -d "$SRCDIR" ]; then
|
||||||
|
echo "Usage: get_horde_date.sh SRCDIR"
|
||||||
|
echo "Please enter a valid source directory of the Horde libs"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This is a concatenated copy of the following files:
|
||||||
|
* Horde/Date/Utils.php, Horde/Date/Recurrence.php
|
||||||
|
* Pull the latest version of these files from the PEAR channel of the Horde
|
||||||
|
* project at http://pear.horde.org by installing the Horde_Date package.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (!class_exists('Horde_Date'))
|
||||||
|
require_once(dirname(__FILE__) . '/Horde_Date.php');
|
||||||
|
|
||||||
|
// minimal required implementation of Horde_Date_Translation to avoid a huge dependency nightmare
|
||||||
|
class Horde_Date_Translation
|
||||||
|
{
|
||||||
|
function t(\$arg) { return \$arg; }
|
||||||
|
function ngettext(\$sing, \$plur, \$num) { return (\$num > 1 ? \$plur : \$sing); }
|
||||||
|
}
|
||||||
|
"
|
||||||
|
|
||||||
|
sed 's/<?php//; s/?>//' $SRCDIR/Date/Utils.php
|
||||||
|
echo "\n"
|
||||||
|
sed 's/<?php//; s/?>//' $SRCDIR/Date/Recurrence.php | sed -E "s/Horde_String::/strto/"
|
||||||
|
echo "\n"
|
||||||
|
|
1112
plugins/libkolab/lib/Horde_Date.php
Normal file
1112
plugins/libkolab/lib/Horde_Date.php
Normal file
File diff suppressed because it is too large
Load diff
1768
plugins/libkolab/lib/Horde_Date_Recurrence.php
Normal file
1768
plugins/libkolab/lib/Horde_Date_Recurrence.php
Normal file
File diff suppressed because it is too large
Load diff
105
plugins/libkolab/lib/kolab_date_recurrence.php
Normal file
105
plugins/libkolab/lib/kolab_date_recurrence.php
Normal file
|
@ -0,0 +1,105 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Recurrence computation class for xcal-based Kolab format objects
|
||||||
|
*
|
||||||
|
* Uitility class to compute instances of recurring events.
|
||||||
|
*
|
||||||
|
* @version @package_version@
|
||||||
|
* @author Thomas Bruederli <bruederli@kolabsys.com>
|
||||||
|
*
|
||||||
|
* Copyright (C) 2012, Kolab Systems AG <contact@kolabsys.com>
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Affero General Public License as
|
||||||
|
* published by the Free Software Foundation, either version 3 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program 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 Affero General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
class kolab_date_recurrence
|
||||||
|
{
|
||||||
|
private $engine;
|
||||||
|
private $tz_offset = 0;
|
||||||
|
private $allday = false;
|
||||||
|
private $hour = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default constructor
|
||||||
|
*
|
||||||
|
* @param array The Kolab object to operate on
|
||||||
|
*/
|
||||||
|
function __construct($object)
|
||||||
|
{
|
||||||
|
// use (copied) Horde classes to compute recurring instances
|
||||||
|
// TODO: replace with something that has less than 6'000 lines of code
|
||||||
|
$this->engine = new Horde_Date_Recurrence($object['start']);
|
||||||
|
$this->engine->fromRRule20($this->to_rrule($object['recurrence'])); // TODO: get that string directly from libkolabxml
|
||||||
|
|
||||||
|
foreach ((array)$object['recurrence']['EXDATE'] as $exdate)
|
||||||
|
$this->engine->addException(date('Y', $exdate), date('n', $exdate), date('j', $exdate));
|
||||||
|
|
||||||
|
$now = new DateTime('now', kolab_format::$timezone);
|
||||||
|
$this->tz_offset = $object['allday'] ? $now->getOffset() - date('Z') : 0;
|
||||||
|
$this->next = new Horde_Date($object['start'] + $this->tz_offset); # shift all-day times to server timezone because computation operates in local TZ
|
||||||
|
$this->dst_start = $this->next->format('I');
|
||||||
|
$this->allday = $object['allday'];
|
||||||
|
$this->hour = $this->next->hour;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get timestamp of the next occurence of this event
|
||||||
|
*
|
||||||
|
* @return mixed Unix timestamp or False if recurrence ended
|
||||||
|
*/
|
||||||
|
public function next_start()
|
||||||
|
{
|
||||||
|
$time = false;
|
||||||
|
if ($this->next && ($next = $this->engine->nextActiveRecurrence(array('year' => $this->next->year, 'month' => $this->next->month, 'mday' => $this->next->mday + 1, 'hour' => $this->next->hour, 'min' => $this->next->min, 'sec' => $this->next->sec)))) {
|
||||||
|
if ($this->allday) {
|
||||||
|
$next->hour = $this->hour; # fix time for all-day events
|
||||||
|
$next->min = 0;
|
||||||
|
}
|
||||||
|
# consider difference in daylight saving between base event and recurring instance
|
||||||
|
$dst_diff = ($this->dst_start - $next->format('I')) * 3600;
|
||||||
|
$time = $next->timestamp() - $this->tz_offset - $dst_diff;
|
||||||
|
$this->next = $next;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $time;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert the internal structured data into a vcalendar RRULE 2.0 string
|
||||||
|
*/
|
||||||
|
private function to_rrule($recurrence)
|
||||||
|
{
|
||||||
|
if (is_string($recurrence))
|
||||||
|
return $recurrence;
|
||||||
|
|
||||||
|
$rrule = '';
|
||||||
|
foreach ((array)$recurrence as $k => $val) {
|
||||||
|
$k = strtoupper($k);
|
||||||
|
switch ($k) {
|
||||||
|
case 'UNTIL':
|
||||||
|
$val = gmdate('Ymd\THis', $val);
|
||||||
|
break;
|
||||||
|
case 'EXDATE':
|
||||||
|
foreach ((array)$val as $i => $ex)
|
||||||
|
$val[$i] = gmdate('Ymd\THis', $ex);
|
||||||
|
$val = join(',', (array)$val);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
$rrule .= $k . '=' . $val . ';';
|
||||||
|
}
|
||||||
|
|
||||||
|
return $rrule;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -118,9 +118,8 @@ class kolab_format_event extends kolab_format_xcal
|
||||||
|
|
||||||
// read object properties
|
// read object properties
|
||||||
$object += array(
|
$object += array(
|
||||||
'allday' => $this->obj->start()->isDateOnly(),
|
|
||||||
'start' => self::php_datetime($this->obj->start()),
|
|
||||||
'end' => self::php_datetime($this->obj->end()),
|
'end' => self::php_datetime($this->obj->end()),
|
||||||
|
'allday' => $this->obj->start()->isDateOnly(),
|
||||||
'free_busy' => $this->obj->transparency() ? 'free' : 'busy', // TODO: transparency is only boolean
|
'free_busy' => $this->obj->transparency() ? 'free' : 'busy', // TODO: transparency is only boolean
|
||||||
'attendees' => array(),
|
'attendees' => array(),
|
||||||
);
|
);
|
||||||
|
@ -283,8 +282,8 @@ class kolab_format_event extends kolab_format_xcal
|
||||||
'title' => $rec['summary'],
|
'title' => $rec['summary'],
|
||||||
'location' => $rec['location'],
|
'location' => $rec['location'],
|
||||||
'description' => $rec['body'],
|
'description' => $rec['body'],
|
||||||
'start' => $rec['start-date'],
|
'start' => new DateTime('@'.$rec['start-date'], self::$timezone),
|
||||||
'end' => $rec['end-date'],
|
'end' => new DateTime('@'.$rec['end-date'], self::$timezone),
|
||||||
'allday' => $allday,
|
'allday' => $allday,
|
||||||
'recurrence' => $rrule,
|
'recurrence' => $rrule,
|
||||||
'alarms' => $alarm_value . $alarm_unit,
|
'alarms' => $alarm_value . $alarm_unit,
|
||||||
|
|
|
@ -89,10 +89,6 @@ class kolab_format_task extends kolab_format_xcal
|
||||||
|
|
||||||
$object['complete'] = intval($this->obj->percentComplete());
|
$object['complete'] = intval($this->obj->percentComplete());
|
||||||
|
|
||||||
// if start/end date is set
|
|
||||||
if ($dtstart = $this->obj->start())
|
|
||||||
$object['start'] = self::php_datetime($dtstart);
|
|
||||||
|
|
||||||
// if due date is set
|
// if due date is set
|
||||||
if ($due = $this->obj->due())
|
if ($due = $this->obj->due())
|
||||||
$object['due'] = self::php_datetime($due);
|
$object['due'] = self::php_datetime($due);
|
||||||
|
|
|
@ -105,6 +105,7 @@ abstract class kolab_format_xcal extends kolab_format
|
||||||
'sensitivity' => $sensitivity_map[$this->obj->classification()],
|
'sensitivity' => $sensitivity_map[$this->obj->classification()],
|
||||||
'priority' => $this->obj->priority(),
|
'priority' => $this->obj->priority(),
|
||||||
'categories' => self::vector2array($this->obj->categories()),
|
'categories' => self::vector2array($this->obj->categories()),
|
||||||
|
'start' => self::php_datetime($this->obj->start()),
|
||||||
);
|
);
|
||||||
|
|
||||||
// read organizer and attendees
|
// read organizer and attendees
|
||||||
|
|
Loading…
Add table
Reference in a new issue