/**
  * NOTE: As noted in {@see testMoveOriginPersonalToShared} we can't delete/decline for organizer in his
  *       personal cal because a move personal->shared would delete/decline the event.
  *       
  *       To support intensional delete/declines we allow the delte/decline only if ther is some
  *       time between this and the last update
  */
 public function testDeleteImplicitDeclineOrganizer()
 {
     $_SERVER['HTTP_USER_AGENT'] = 'Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.21) Gecko/20110831 Lightning/1.0b2 Thunderbird/3.1.13';
     $vcalendar = self::getVCalendar(dirname(__FILE__) . '/../../Import/files/lightning.ics');
     $vcalendar = preg_replace('#DTSTART;TZID=Europe/Berlin:20111004T100000#', 'DTSTART;TZID=Europe/Berlin:' . Tinebase_DateTime::now()->format('Ymd\\THis'), $vcalendar);
     $vcalendar = preg_replace('#DTEND;TZID=Europe/Berlin:20111004T120000#', 'DTEND;TZID=Europe/Berlin:' . Tinebase_DateTime::now()->addHour(1)->format('Ymd\\THis'), $vcalendar);
     $id = Tinebase_Record_Abstract::generateUID();
     $event = Calendar_Frontend_WebDAV_Event::create($this->objects['initialContainer'], "{$id}.ics", $vcalendar);
     // move event origin to shared (origin and display where the same)
     Calendar_Frontend_WebDAV_Event::create($this->objects['sharedContainer'], "{$id}.ics", stream_get_contents($event->get()));
     //         $oldEvent = new Calendar_Frontend_WebDAV_Event($this->objects['initialContainer'], "$id.ics");
     //         $oldEvent->delete();
     // wait some time
     $cbs = new Calendar_Backend_Sql();
     $cbs->updateMultiple(array($id), array('creation_time' => Tinebase_DateTime::now()->subMinute(5), 'last_modified_time' => Tinebase_DateTime::now()->subMinute(3)));
     $personalEvent = new Calendar_Frontend_WebDAV_Event($this->objects['initialContainer'], "{$id}.ics");
     $personalEvent->delete();
     $loadedEvent = new Calendar_Frontend_WebDAV_Event($this->objects['sharedContainer'], "{$id}.ics");
     $ownAttendee = Calendar_Model_Attender::getOwnAttender($loadedEvent->getRecord()->attendee);
     $this->assertEquals(Calendar_Model_Attender::STATUS_DECLINED, $ownAttendee->status, 'event must be declined');
 }
 public function testStatusUpdate($syncrotonFolder = null)
 {
     if ($syncrotonFolder === null) {
         $syncrotonFolder = $this->testCreateFolder();
     }
     $controller = Syncroton_Data_Factory::factory($this->_class, $this->_getDevice(Syncroton_Model_Device::TYPE_IPHONE), Tinebase_DateTime::now());
     list($serverId, $syncrotonEvent) = $this->testCreateEntry($syncrotonFolder);
     // transfer event to other user
     $rwright = Tinebase_Helper::array_value('rwright', $this->_personas = Zend_Registry::get('personas'));
     $eventBackend = new Calendar_Backend_Sql();
     $eventBackend->updateMultiple($eventBackend->getMultipleByProperty($syncrotonEvent->uID, 'uid')->id, array('container_id' => Tinebase_Core::getPreference('Calendar')->getValueForUser(Calendar_Preference::DEFAULTCALENDAR, $rwright->getId()), 'organizer' => $rwright->contact_id));
     $syncrotonEvent->exceptions[0]->busyStatus = 1;
     $syncrotonEvent->exceptions[0]->subject = 'do not update';
     $serverId = $controller->updateEntry($syncrotonFolder->serverId, $serverId, $syncrotonEvent);
     $syncrotonEvent = $controller->getEntry(new Syncroton_Model_SyncCollection(array('collectionId' => $syncrotonFolder->serverId)), $serverId);
     $event = Calendar_Controller_MSEventFacade::getInstance()->get($serverId);
     $attendee = $event->exdate->getFirstRecord()->attendee->getFirstRecord();
     $this->assertEquals(Calendar_Model_Attender::STATUS_TENTATIVE, $attendee->status);
     $this->assertNotEquals('do not update', $event->summary);
 }
 /**
  * this function creates a Calendar_Model_Event and stores it in the database
  * 
  * @todo the header handling does not belong here. It should be moved to the DAV_Server class when supported
  * 
  * @param  Tinebase_Model_Container  $container
  * @param  stream|string             $vobjectData
  * @return Calendar_Frontend_WebDAV_Event
  */
 public static function create(Tinebase_Model_Container $container, $name, $vobjectData, $onlyCurrentUserOrganizer = false)
 {
     if (is_resource($vobjectData)) {
         $vobjectData = stream_get_contents($vobjectData);
     }
     // Converting to UTF-8, if needed
     $vobjectData = Sabre\DAV\StringUtil::ensureUTF8($vobjectData);
     #Sabre\CalDAV\ICalendarUtil::validateICalendarObject($vobjectData, array('VEVENT', 'VFREEBUSY'));
     list($backend, $version) = Calendar_Convert_Event_VCalendar_Factory::parseUserAgent($_SERVER['HTTP_USER_AGENT']);
     $converter = Calendar_Convert_Event_VCalendar_Factory::factory($backend, $version);
     try {
         $event = $converter->toTine20Model($vobjectData);
     } catch (Exception $e) {
         Tinebase_Core::getLogger()->err(__METHOD__ . '::' . __LINE__ . ' ' . $e);
         Tinebase_Core::getLogger()->err(__METHOD__ . '::' . __LINE__ . " " . $vobjectData);
         throw new Sabre\DAV\Exception\PreconditionFailed($e->getMessage());
     }
     if (true === $onlyCurrentUserOrganizer) {
         if ($event->organizer && $event->organizer != Tinebase_Core::getUser()->contact_id) {
             return null;
         }
     }
     $event->container_id = $container->getId();
     $id = ($pos = strpos($name, '.')) === false ? $name : substr($name, 0, $pos);
     if (strlen($id) > 40) {
         $id = sha1($id);
     }
     $event->setId($id);
     if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) {
         Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . " Event to create: " . print_r($event->toArray(), TRUE));
     }
     Calendar_Controller_MSEventFacade::getInstance()->assertEventFacadeParams($container);
     // check if there is already an existing event with this ID
     // this can happen when the invitation email is faster then the caldav update or
     // or when an event gets moved to another container
     $filter = new Calendar_Model_EventFilter(array(array('field' => 'is_deleted', 'operator' => 'equals', 'value' => Tinebase_Model_Filter_Bool::VALUE_NOTSET), array('condition' => 'OR', 'filters' => array(array('field' => 'id', 'operator' => 'equals', 'value' => $id), array('field' => 'uid', 'operator' => 'equals', 'value' => $id)))));
     $existingEvent = Calendar_Controller_MSEventFacade::getInstance()->search($filter, null, false, false, 'sync')->getFirstRecord();
     if ($existingEvent === null) {
         if (get_class($converter) == 'Calendar_Convert_Event_VCalendar_Generic') {
             if (Tinebase_Core::isLogLevel(Zend_Log::WARN)) {
                 Tinebase_Core::getLogger()->warn(__METHOD__ . '::' . __LINE__ . " update by generic client not allowed. See Calendar_Convert_Event_VCalendar_Factory for supported clients.");
             }
             throw new Sabre\DAV\Exception\Forbidden('write access denied for unknown client');
         }
         try {
             $event = Calendar_Controller_MSEventFacade::getInstance()->create($event);
         } catch (Zend_Db_Statement_Exception $zdse) {
             Tinebase_Exception::log($zdse, true);
             if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) {
                 Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' Might be a duplicate exception, try with new id');
             }
             unset($event->id);
             try {
                 $event = Calendar_Controller_MSEventFacade::getInstance()->create($event);
             } catch (Exception $e) {
                 Tinebase_Core::getLogger()->err(__METHOD__ . '::' . __LINE__ . ' ' . $e);
                 Tinebase_Core::getLogger()->err(__METHOD__ . '::' . __LINE__ . " " . $vobjectData);
                 Tinebase_Core::getLogger()->err(__METHOD__ . '::' . __LINE__ . " " . print_r($event->toArray(), true));
                 throw new Sabre\DAV\Exception\PreconditionFailed($e->getMessage());
             }
         } catch (Exception $e) {
             Tinebase_Core::getLogger()->err(__METHOD__ . '::' . __LINE__ . ' ' . $e);
             Tinebase_Core::getLogger()->err(__METHOD__ . '::' . __LINE__ . " " . $vobjectData);
             Tinebase_Core::getLogger()->err(__METHOD__ . '::' . __LINE__ . " " . print_r($event->toArray(), true));
             throw new Sabre\DAV\Exception\PreconditionFailed($e->getMessage());
         }
         $vevent = new self($container, $event);
     } else {
         if ($existingEvent->is_deleted) {
             if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) {
                 Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' recovering already deleted event');
             }
             // @TODO have a undelete/recover workflow beginning in controller
             $existingEvent->is_deleted = 0;
             $existingEvent->deleted_by = NULL;
             $existingEvent->deleted_time = NULL;
             $be = new Calendar_Backend_Sql();
             $be->updateMultiple($existingEvent->getId(), array('is_deleted' => 0, 'deleted_by' => NULL, 'deleted_time' => NULL));
         }
         if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) {
             Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' update existing event');
         }
         $vevent = new self($container, $existingEvent);
         $vevent->put($vobjectData);
     }
     return $vevent;
 }