/**
  * update one record
  * 
  * NOTE: clients might send their original (creation) data w.o. our adoptions for update
  *       therefore we need reapply them
  *       
  * @param   Calendar_Model_Event $_event
  * @param   bool                 $_checkBusyConflicts
  * @return  Calendar_Model_Event
  * @throws  Tinebase_Exception_AccessDenied
  * @throws  Tinebase_Exception_Record_Validation
  */
 public function update(Tinebase_Record_Interface $_event, $_checkBusyConflicts = FALSE)
 {
     if ($_event->recurid) {
         throw new Tinebase_Exception_UnexpectedValue('recur event instances must be saved as part of the base event');
     }
     $currentOriginEvent = $this->_eventController->get($_event->getId());
     $this->_fromiTIP($_event, $currentOriginEvent);
     // NOTE:  create an update must be handled equally as apple devices do not fetch events after creation.
     //        an update from the creating device would change defaults otherwise
     // NOTE2: Being organizer without attending is not possible when sync is in use as every update
     //        from a sync device of the organizer adds the organizer as attendee :-(
     //        -> in the sync world this is scenario is called delegation and handled differently
     //        -> it might be consequent to have the same behavior (organizer is always attendee with role chair)
     //           in tine20 in general. This is how Thunderbird handles it as well
     $_event->assertAttendee($this->getCalendarUser());
     $exceptions = $_event->exdate instanceof Tinebase_Record_RecordSet ? $_event->exdate : new Tinebase_Record_RecordSet('Calendar_Model_Event');
     $exceptions->addIndices(array('is_deleted'));
     $currentPersistentExceptions = $_event->rrule ? $this->_eventController->getRecurExceptions($_event, FALSE) : new Tinebase_Record_RecordSet('Calendar_Model_Event');
     $newPersistentExceptions = $exceptions->filter('is_deleted', 0);
     $migration = $this->_getExceptionsMigration($currentPersistentExceptions, $newPersistentExceptions);
     $this->_eventController->delete($migration['toDelete']->getId());
     // NOTE: we need to exclude the toCreate exdates here to not confuse computations in createRecurException!
     $_event->exdate = array_diff($exceptions->getOriginalDtStart(), $migration['toCreate']->getOriginalDtStart());
     $updatedBaseEvent = $this->_eventController->update($_event, $_checkBusyConflicts);
     if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) {
         Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' Found ' . count($migration['toCreate']) . ' exceptions to create and ' . count($migration['toUpdate']) . ' to update.');
     }
     foreach ($migration['toCreate'] as $exception) {
         $exception->assertAttendee($this->getCalendarUser());
         $this->_prepareException($updatedBaseEvent, $exception);
         $this->_eventController->createRecurException($exception, !!$exception->is_deleted);
     }
     $updatedExceptions = array();
     foreach ($migration['toUpdate'] as $exception) {
         if (in_array($exception->getId(), $updatedExceptions)) {
             if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) {
                 Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' ' . ' Exdate ' . $exception->getId() . ' already updated');
             }
             continue;
         }
         if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) {
             Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' ' . ' Update exdate ' . $exception->getId() . ' at ' . $exception->dtstart->toString());
         }
         $exception->assertAttendee($this->getCalendarUser());
         $this->_prepareException($updatedBaseEvent, $exception);
         $this->_addStatusAuthkeyForOwnAttender($exception);
         // skip concurrency check here by setting the seq of the current record
         $currentException = $currentPersistentExceptions->getById($exception->getId());
         $exception->seq = $currentException->seq;
         if (Tinebase_Core::isLogLevel(Zend_Log::TRACE)) {
             Tinebase_Core::getLogger()->trace(__METHOD__ . '::' . __LINE__ . ' Updating exception: ' . print_r($exception->toArray(), TRUE));
         }
         $this->_eventController->update($exception, $_checkBusyConflicts);
         $updatedExceptions[] = $exception->getId();
     }
     // NOTE: we need to refetch here, otherwise eTag fail's as exception updates change baseEvents seq
     return $this->get($updatedBaseEvent->getId());
 }
예제 #2
0
 /**
  * update one record
  *
  * @param   Calendar_Model_Event $_record
  * @param   bool                 $_checkBusyConflicts
  * @return  Calendar_Model_Event
  * @throws  Tinebase_Exception_AccessDenied
  * @throws  Tinebase_Exception_Record_Validation
  */
 public function update(Tinebase_Record_Interface $_event, $_checkBusyConflicts = FALSE)
 {
     if ($_event->recurid) {
         throw new Tinebase_Exception_UnexpectedValue('recur event instances must be saved as part of the base event');
     }
     $exceptions = $_event->exdate instanceof Tinebase_Record_RecordSet ? $_event->exdate : new Tinebase_Record_RecordSet('Calendar_Model_Event');
     $_event->exdate = $exceptions->getOriginalDtStart();
     $currentPersistentExceptions = $_event->rrule ? $this->_eventController->getRecurExceptions($_event, FALSE) : new Tinebase_Record_RecordSet('Calendar_Model_Event');
     $newPersistentExceptions = $exceptions->filter('is_deleted', 0);
     $this->_prepareException($_event, $newPersistentExceptions);
     $migration = $this->_getExceptionsMigration($currentPersistentExceptions, $newPersistentExceptions);
     $this->_eventController->delete($migration['toDelete']->getId());
     foreach ($migration['toCreate'] as $exception) {
         $this->_eventController->createRecurException($exception, !!$exception->is_deleted);
     }
     foreach ($migration['toUpdate'] as $exception) {
         $this->_eventController->update($exception, $_checkBusyConflicts);
     }
     $updatedBaseEvent = $this->_eventController->update($_event, $_checkBusyConflicts);
     return $this->_toiTIP($updatedBaseEvent);
 }