#9598: imip invitation mails show js error (in Felamimail)
authorPhilipp Schüle <p.schuele@metaways.de>
Wed, 29 Jan 2014 09:48:47 +0000 (10:48 +0100)
committerPhilipp Schüle <p.schuele@metaways.de>
Wed, 29 Jan 2014 10:25:28 +0000 (11:25 +0100)
- convert VCALENDAR even if it contains only a recur exception
- adds fallbacks if certain values are empty

https://forge.tine20.org/mantisbt/view.php?id=9598

Change-Id: I7f864fb6de20bc2ff097ee1ef87e50926fbd3a12
Reviewed-on: https://gerrit.tine20.org/tine20/2763
Tested-by: jenkins user
Reviewed-by: Philipp Schüle <p.schuele@metaways.de>
Tested-by: Philipp Schüle <p.schuele@metaways.de>
tests/tine20/Calendar/Convert/Event/VCalendar/GenericTest.php
tests/tine20/Calendar/Import/files/request_exdate.ics [new file with mode: 0644]
tine20/Calendar/Convert/Event/VCalendar/Abstract.php
tine20/Calendar/Model/Attender.php
tine20/Calendar/js/EventDetailsPanel.js

index f23961f..e78f206 100644 (file)
@@ -4,7 +4,7 @@
  * 
  * @package     Calendar
  * @license     http://www.gnu.org/licenses/agpl.html
- * @copyright   Copyright (c) 2011-2013 Metaways Infosystems GmbH (http://www.metaways.de)
+ * @copyright   Copyright (c) 2011-2014 Metaways Infosystems GmbH (http://www.metaways.de)
  * @author      Lars Kneschke <l.kneschke@metaways.de>
  */
 
@@ -359,10 +359,6 @@ class Calendar_Convert_Event_VCalendar_GenericTest extends PHPUnit_Framework_Tes
         
         $updatedEvent = $this->_converter->toTine20Model($vcalendarStream, clone $event);
     
-        //var_dump($event->exdate->toArray());
-        #var_dump($updatedEvent->exdate[3]->attendee->toArray());
-        #var_dump($event->dtstart->format('hm'));
-    
         $this->assertTrue(! empty($updatedEvent->exdate[3]->attendee[0]->status_authkey));
         $this->assertEquals($event->exdate[3]->attendee[0]->status_authkey, $updatedEvent->exdate[3]->attendee[0]->status_authkey);
     
@@ -617,4 +613,20 @@ class Calendar_Convert_Event_VCalendar_GenericTest extends PHPUnit_Framework_Tes
         $this->assertEquals('Test-Termin aus Google an Tine20', $event->summary);
         $this->assertEquals('REQUEST', $this->_converter->getMethod());
     }
+
+    /**
+     * testConvertExdateRequest
+     * 
+     * @see 0009598: imip invitation mails show js error (in Felamimail)
+     */
+    public function testConvertExdateRequest()
+    {
+        $vcalendarStream = Calendar_Frontend_WebDAV_EventTest::getVCalendar(dirname(__FILE__) . '/../../../Import/files/request_exdate.ics', 'r');
+        
+        $this->_converter = Calendar_Convert_Event_VCalendar_Factory::factory(Calendar_Convert_Event_VCalendar_Factory::CLIENT_GENERIC);
+        
+        $event = $this->_converter->toTine20Model($vcalendarStream);
+        
+        $this->assertEquals('meeting Philipp / Lars', $event->summary, print_r($event->toArray(), true));
+    }
 }
diff --git a/tests/tine20/Calendar/Import/files/request_exdate.ics b/tests/tine20/Calendar/Import/files/request_exdate.ics
new file mode 100644 (file)
index 0000000..05e9cae
--- /dev/null
@@ -0,0 +1,51 @@
+BEGIN:VCALENDAR
+VERSION:2.0
+PRODID:-//tine20.com//Tine 2.0 Calendar V8.1//EN
+CALSCALE:GREGORIAN
+METHOD:REQUEST
+BEGIN:VTIMEZONE
+TZID:Europe/Berlin
+BEGIN:DAYLIGHT
+TZOFFSETFROM:+0100
+RRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU
+DTSTART:19810329T020000
+TZNAME:CEST
+TZOFFSETTO:+0200
+END:DAYLIGHT
+BEGIN:STANDARD
+TZOFFSETFROM:+0200
+RRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU
+DTSTART:19961027T030000
+TZNAME:CET
+TZOFFSETTO:+0100
+END:STANDARD
+END:VTIMEZONE
+BEGIN:VEVENT
+CREATED:20140128T110153Z
+LAST-MODIFIED:20140128T110153Z
+DTSTAMP:20140128T110157Z
+UID:012b00cf72f8f3606d736411a592c804d3c9d481
+SEQUENCE:1
+RECURRENCE-ID;TZID=Europe/Berlin:20140129T140000
+DTSTART;TZID=Europe/Berlin:20140129T140000
+DTEND;TZID=Europe/Berlin:20140129T150000
+ORGANIZER;CN="Schüle, Philipp";EMAIL=p.schuele@metaways.de;SENT-BY="mailto
+ :p.schuele@metaways.de":mailto:p.schuele@metaways.de
+ATTENDEE;CN="Schüle, Philipp";CUTYPE=INDIVIDUAL;PARTSTAT=ACCEPTED;ROLE=REQ
+ -PARTICIPANT;RSVP=FALSE;EMAIL=p.schuele@metaways.de:mailto:p.schuele@metaw
+ ays.de
+ATTENDEE;CN="Kneschke, Lars";CUTYPE=INDIVIDUAL;PARTSTAT=NEEDS-ACTION;ROLE=R
+ EQ-PARTICIPANT;RSVP=FALSE;EMAIL=l.kneschke@metaways.de:mailto:l.kneschke@m
+ etaways.de
+CLASS:PUBLIC
+STATUS:CONFIRMED
+DESCRIPTION:verschoben von Dienstag
+SUMMARY:meeting Philipp / Lars
+TRANSP:OPAQUE
+BEGIN:VALARM
+ACTION:DISPLAY
+DESCRIPTION:meeting Philipp / Lars
+TRIGGER;VALUE=DURATION:-PT15M
+END:VALARM
+END:VEVENT
+END:VCALENDAR
index 7ecb666..ecd5dd1 100644 (file)
@@ -377,30 +377,51 @@ class Calendar_Convert_Event_VCalendar_Abstract implements Tinebase_Convert_Inte
             $this->setMethod($vcalendar->METHOD);
         }
         
-        // find the main event - the main event has no RECURRENCE-ID
-        $baseVevent = null;
-        foreach ($vcalendar->VEVENT as $vevent) {
-            if (! isset($vevent->{'RECURRENCE-ID'})) {
-                
-                $this->_convertVevent($vevent, $event, $options);
-                $baseVevent = $vevent;
-                break;
+        $baseVevent = $this->_findMainEvent($vcalendar);
+        
+        if (! $baseVevent) {
+            if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ 
+                . ' No main VEVENT found');
+            
+            if (! $_record && count($vcalendar->VEVENT) > 0) {
+                if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ 
+                    . ' Convert recur exception without existing event using first VEVENT');
+                $this->_convertVevent($vcalendar->VEVENT[0], $event, $options);
             }
+        } else {
+            $this->_convertVevent($baseVevent, $event, $options);
         }
         
         // TODO only do this for events with rrule?
         // if (! empty($event->rrule)) {
         $this->_parseEventExceptions($event, $vcalendar, $baseVevent, $options);
-
+        
         $event->isValid(true);
         
-        if (Tinebase_Core::isLogLevel(Zend_Log::TRACE)) 
-            Tinebase_Core::getLogger()->trace(__METHOD__ . '::' . __LINE__ . ' data ' . print_r($event->toArray(), true));
+        if (Tinebase_Core::isLogLevel(Zend_Log::TRACE)) Tinebase_Core::getLogger()->trace(__METHOD__ . '::' . __LINE__ 
+            . ' Event: ' . print_r($event->toArray(), true));
         
         return $event;
     }
     
     /**
+     * find the main event - the main event has no RECURRENCE-ID
+     * 
+     * @param \Sabre\VObject\Component\VCalendar $vcalendar
+     * @return \Sabre\VObject\Component\VCalendar | null
+     */
+    protected function _findMainEvent(\Sabre\VObject\Component\VCalendar $vcalendar)
+    {
+        foreach ($vcalendar->VEVENT as $vevent) {
+            if (! isset($vevent->{'RECURRENCE-ID'})) {
+                return $vevent;
+            }
+        }
+        
+        return null;
+    }
+    
+    /**
      * parse event exceptions and add them to Tine 2.0 event record
      * 
      * @param  Calendar_Model_Event                $event
index b99da8d..14eaf48 100644 (file)
@@ -655,7 +655,12 @@ class Calendar_Model_Attender extends Tinebase_Record_Abstract
      * @param bool                              $_resolveDisplayContainers
      * @param Calendar_Model_Event|array        $_events
      */
-    public static function resolveAttendee($_eventAttendee, $_resolveDisplayContainers = TRUE, $_events = NULL) {
+    public static function resolveAttendee($_eventAttendee, $_resolveDisplayContainers = TRUE, $_events = NULL)
+    {
+        if (empty($_eventAttendee)) {
+            return;
+        }
+        
         $eventAttendee = $_eventAttendee instanceof Tinebase_Record_RecordSet ? array($_eventAttendee) : $_eventAttendee;
         $events = $_events instanceof Tinebase_Record_Abstract ? array($_events) : $_events;
         
index bbb9b44..44cdc26 100644 (file)
@@ -62,6 +62,10 @@ Tine.Calendar.EventDetailsPanel = Ext.extend(Tine.widgets.grid.DetailsPanel, {
      * @return {String}
      */
     datetimeRenderer: function(dt) {
+        if (! dt) {
+            return this.app.i18n._('Unknown date');
+        }
+        
         return String.format(this.app.i18n._("{0} {1} o'clock"), dt.format('l') + ', ' + Tine.Tinebase.common.dateRenderer(dt), dt.format('H:i'));
     },