/** * 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; }