plugins/calendar plugins/libkolab

Thomas Brüderli bruederli at kolabsys.com
Wed Jul 4 15:20:30 CEST 2012


 plugins/calendar/drivers/kolab/kolab_calendar.php |    2 
 plugins/libkolab/lib/kolab_date_recurrence.php    |  188 +++++++++++++---------
 2 files changed, 115 insertions(+), 75 deletions(-)

New commits:
commit 79c8183c0d9df8da51c853fe36155dca3d9f748f
Author: Thomas Bruederli <thomas at roundcube.net>
Date:   Wed Jul 4 15:10:36 2012 +0200

    Add method kolab_date_recurrence::next_instance() for simple iterations

diff --git a/plugins/calendar/drivers/kolab/kolab_calendar.php b/plugins/calendar/drivers/kolab/kolab_calendar.php
index 669b28e..21c94fd 100644
--- a/plugins/calendar/drivers/kolab/kolab_calendar.php
+++ b/plugins/calendar/drivers/kolab/kolab_calendar.php
@@ -378,7 +378,7 @@ class kolab_calendar
     $events = array();
     $duration = $event['end'] - $event['start'];
     $i = 0;
-    while ($rec_start = $recurrence->next_start()) {
+    while ($rec_start = $recurrence->next_start(true)) {
       $rec_end = $rec_start + $duration;
       $rec_id = $event['id'] . '-' . ++$i;
       
diff --git a/plugins/libkolab/lib/kolab_date_recurrence.php b/plugins/libkolab/lib/kolab_date_recurrence.php
index c840864..95dfedc 100644
--- a/plugins/libkolab/lib/kolab_date_recurrence.php
+++ b/plugins/libkolab/lib/kolab_date_recurrence.php
@@ -25,81 +25,121 @@
  */
 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;
+    private $engine;
+    private $object;
+    private $next;
+    private $duration;
+    private $tz_offset = 0;
+    private $dst_start = 0;
+    private $allday = false;
+    private $hour = 0;
+
+    /**
+     * Default constructor
+     *
+     * @param array The Kolab object to operate on
+     */
+    function __construct($object)
+    {
+        $this->object = $object;
+        $this->next = new Horde_Date($object['start'], kolab_format::$timezone->getName());
+
+        if (is_object($object['start']) && is_object($object['end']))
+            $this->duration = $object['end']->diff($object['start']);
+        else
+            $this->duration = new DateInterval('PT' . ($object['end'] - $object['start']) . 'S');
+
+        // 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($this->next);
+        $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->dst_start = $this->next->format('I');
+        $this->allday = $object['allday'];
+        $this->hour = $this->next->hour;
+    }
+
+    /**
+     * Get date/time of the next occurence of this event
+     *
+     * @param boolean Return a Unix timestamp instead of a DateTime object
+     * @return mixed  DateTime object/unix timestamp or False if recurrence ended
+     */
+    public function next_start($timestamp = false)
+    {
+        $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;
+            }
+            if ($timestamp) {
+                # 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;
+            }
+            else {
+                $time = $next->toDateTime();
+            }
+            $this->next = $next;
+        }
+
+        return $time;
     }
 
-    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;
-  }
+    /**
+     * Get the next recurring instance of this event
+     *
+     * @return mixed Array with event properties or False if recurrence ended
+     */
+    public function next_instance()
+    {
+        if ($next_start = $this->next_start()) {
+            $next_end = clone $next_start;
+            $next_end->add($this->duration);
+
+            $next = $this->object;
+            $next['recurrence_id'] = $next_start->format('Y-m-d');
+            $next['start'] = $next_start;
+            $next['end'] = $next_end;
+            unset($next['_formatobj']);
+
+            return $next;
+        }
+
+        return false;
+    }
+
+    /**
+     * 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;
+    }
 
 }





More information about the commits mailing list