/** * add event attendee to VEVENT object * * @param \Sabre\VObject\Component\VEvent $vevent * @param Calendar_Model_Event $event */ protected function _addEventAttendee(\Sabre\VObject\Component\VEvent $vevent, Calendar_Model_Event $event) { parent::_addEventAttendee($vevent, $event); if (empty($event->attendee)) { return; } // add organizer as CHAIR Attendee if he's no organizer, otherwise yosemite would add an attendee // when editing the event again. // NOTE: when the organizer edits the event he becomes attendee anyway, see comments in MSEventFacade::update if (version_compare($this->_version, '10.10', '>=')) { if (!empty($event->organizer)) { $organizerContact = $event->resolveOrganizer(); if ($organizerContact instanceof Addressbook_Model_Contact) { $organizerAttendee = Calendar_Model_Attender::getAttendee($event->attendee, new Calendar_Model_Attender(array('user_id' => $organizerContact->getId(), 'user_type' => Calendar_Model_Attender::USERTYPE_USER))); if (!$organizerAttendee) { $parameters = array('CN' => $organizerContact->n_fileas, 'CUTYPE' => 'INDIVIDUAL', 'PARTSTAT' => 'ACCEPTED', 'ROLE' => 'CHAIR'); $organizerEmail = $organizerContact->email; if (strpos($organizerEmail, '@') !== false) { $parameters['EMAIL'] = $organizerEmail; } $vevent->add('ATTENDEE', (strpos($organizerEmail, '@') !== false ? 'mailto:' : 'urn:uuid:') . $organizerEmail, $parameters); } } } } }
/** * @return void */ public function testEmailsToAttendeeWithGroups() { if (Tinebase_User::getConfiguredBackend() === Tinebase_User::LDAP || Tinebase_User::getConfiguredBackend() === Tinebase_User::ACTIVEDIRECTORY) { $this->markTestSkipped('FIXME: Does not work with LDAP/AD backend'); } $event = $this->_getEvent(); $persistentEvent = Calendar_Controller_Event::getInstance()->create($event); $primaryGroup = Tinebase_Group::getInstance()->getGroupById(Tinebase_Core::getUser()->accountPrimaryGroup); $newAttendees = array(array('userType' => Calendar_Model_Attender::USERTYPE_USER, 'firstName' => $this->_originalTestUser->accountFirstName, 'lastName' => $this->_originalTestUser->accountLastName, 'partStat' => Calendar_Model_Attender::STATUS_TENTATIVE, 'role' => Calendar_Model_Attender::ROLE_REQUIRED, 'email' => $this->_originalTestUser->accountEmailAddress), array('userType' => Calendar_Model_Attender::USERTYPE_GROUP, 'displayName' => $primaryGroup->name, 'partStat' => Calendar_Model_Attender::STATUS_NEEDSACTION, 'role' => Calendar_Model_Attender::ROLE_REQUIRED, 'email' => '*****@*****.**')); Calendar_Model_Attender::emailsToAttendee($persistentEvent, $newAttendees, TRUE); $persistentEvent = Calendar_Controller_Event::getInstance()->update($persistentEvent); $attendees = clone $persistentEvent->attendee; Calendar_Model_Attender::resolveAttendee($attendees); $newAttendees = array(); foreach ($attendees as $attendee) { $newAttendees[] = array('userType' => $attendee->user_type == 'group' ? Calendar_Model_Attender::USERTYPE_GROUP : Calendar_Model_Attender::USERTYPE_USER, 'partStat' => Calendar_Model_Attender::STATUS_TENTATIVE, 'role' => Calendar_Model_Attender::ROLE_REQUIRED, 'email' => $attendee->user_type == 'group' ? $attendee->user_id->getId() : $attendee->user_id->email, 'displayName' => $attendee->user_type == 'group' ? $attendee->user_id->name : $attendee->user_id->n_fileas); } Calendar_Model_Attender::emailsToAttendee($persistentEvent, $newAttendees, TRUE); $persistentEvent = Calendar_Controller_Event::getInstance()->update($persistentEvent); // print_r($persistentEvent->attendee->toArray()); // there must be more than 2 attendees the user, the group + the groupmembers $this->assertGreaterThan(2, count($persistentEvent->attendee)); // current account must not be a groupmember $this->assertFalse(!!Calendar_Model_Attender::getAttendee($persistentEvent->attendee, new Calendar_Model_Attender(array('user_type' => Calendar_Model_Attender::USERTYPE_GROUPMEMBER, 'user_id' => $this->_originalTestUser->contact_id))), 'found user as groupmember'); $this->assertEquals(Calendar_Model_Attender::STATUS_TENTATIVE, Calendar_Model_Attender::getOwnAttender($persistentEvent->attendee)->status); }
/** * get updates of human interest * * @param Calendar_Model_Event $_event * @param Calendar_Model_Event $_oldEvent * @return array */ protected function _getUpdates($_event, $_oldEvent) { // check event details $diff = $_event->diff($_oldEvent)->diff; $orderedUpdateFieldOfInterest = array('dtstart', 'dtend', 'rrule', 'summary', 'location', 'description', 'transp', 'priority', 'status', 'class', 'url', 'is_all_day_event', 'originator_tz'); $updates = array(); foreach ($orderedUpdateFieldOfInterest as $field) { if (isset($diff[$field]) || array_key_exists($field, $diff)) { $updates[$field] = $diff[$field]; } } // rrule legacy if (isset($updates['rrule']) || array_key_exists('rrule', $updates)) { $updates['rrule'] = $_oldEvent->rrule; } // check for organizer update if (Tinebase_Record_Abstract::convertId($_event['organizer'], 'Addressbook_Model_Contact') != Tinebase_Record_Abstract::convertId($_oldEvent['organizer'], 'Addressbook_Model_Contact')) { $updates['organizer'] = $_event->resolveOrganizer(); } // check attendee updates $attendeeMigration = Calendar_Model_Attender::getMigration($_oldEvent->attendee, $_event->attendee); foreach ($attendeeMigration['toUpdate'] as $attendee) { $oldAttendee = Calendar_Model_Attender::getAttendee($_oldEvent->attendee, $attendee); if ($attendee->status == $oldAttendee->status) { $attendeeMigration['toUpdate']->removeRecord($attendee); } } foreach ($attendeeMigration as $action => $migration) { Calendar_Model_Attender::resolveAttendee($migration, FALSE); if (!count($migration)) { unset($attendeeMigration[$action]); } } if (!empty($attendeeMigration)) { $updates['attendee'] = $attendeeMigration; } return $updates; }
/** * assert current user as attender * * @param Calendar_Model_Event $exdate */ protected function _assertCurrentUserAttender($event) { $this->assertTrue($event->attendee instanceof Tinebase_Record_RecordSet, 'attendee is no recordset: ' . print_r($event->toArray(), true)); $this->assertEquals(2, $event->attendee->count(), 'exdate should have 2 attendee: ' . print_r($event->toArray(), true)); $currentUser = Calendar_Model_Attender::getAttendee($event->attendee, new Calendar_Model_Attender(array('user_id' => Tinebase_Core::getUser()->contact_id, 'user_type' => Calendar_Model_Attender::USERTYPE_USER))); $this->assertNotNull($currentUser, 'currentUser not found in attendee'); $this->assertEquals(Calendar_Model_Attender::STATUS_ACCEPTED, $currentUser->status, print_r($currentUser->toArray(), true)); }
public function testMissingEmailAttendee() { $noMailContact = Addressbook_Controller_Contact::getInstance()->create(new Addressbook_Model_Contact(array('org_name' => 'nomail'))); $noMailAttendee = new Calendar_Model_Attender(array('user_type' => Calendar_Model_Attender::USERTYPE_USER, 'user_id' => $noMailContact->getId(), 'organizer' => Tinebase_Core::getUser()->contact_id)); $event = $this->_getEvent(); $event->attendee->addRecord($noMailAttendee); $persistentEvent = Calendar_Controller_Event::getInstance()->create($event); $loadedEvent = $this->_uit->get($persistentEvent->getId()); $this->assertTrue((bool) Calendar_Model_Attender::getAttendee($persistentEvent->attendee, $noMailAttendee)); $this->assertFalse((bool) Calendar_Model_Attender::getAttendee($loadedEvent->attendee, $noMailAttendee)); $loadedEvent->summary = 'update'; $update = $this->_uit->update($loadedEvent); $loadedEvent = Calendar_Controller_Event::getInstance()->get($persistentEvent->getId()); $this->assertEquals('update', $loadedEvent->summary); $this->assertTrue((bool) Calendar_Model_Attender::getAttendee($loadedEvent->attendee, $noMailAttendee)); }
public function testAlarmSkipDeclined() { $event = $this->_getEvent(); $event->attendee = $this->_getPersonaAttendee('sclever, pwulf'); $event->organizer = $this->_getPersonasContacts('sclever')->getId(); $event->dtstart = Tinebase_DateTime::now()->addMinute(25); $event->dtend = clone $event->dtstart; $event->dtend->addMinute(30); $event->alarms = new Tinebase_Record_RecordSet('Tinebase_Model_Alarm', array(new Tinebase_Model_Alarm(array('minutes_before' => 30), TRUE))); $persistentEvent = $this->_eventController->create($event); $sclever = Calendar_Model_Attender::getAttendee($persistentEvent->attendee, $event->attendee[0]); $sclever->status = Calendar_Model_Attender::STATUS_DECLINED; $this->_eventController->attenderStatusUpdate($persistentEvent, $sclever, $sclever->status_authkey); self::flushMailer(); Tinebase_Alarm::getInstance()->sendPendingAlarms("Tinebase_Event_Async_Minutely"); $this->_assertMail('pwulf', 'Alarm'); $this->assertEquals(1, count(self::getMessages())); }
/** * testInvitationExternalReply */ public function testInvitationExternalReply() { $email = $email = $this->_getEmailAddress(); $ics = file_get_contents(dirname(__FILE__) . '/files/invitation_reply_external_accepted.ics'); $ics = preg_replace('/unittest@tine20\\.org/', $email, $ics); $iMIP = new Calendar_Model_iMIP(array('id' => Tinebase_Record_Abstract::generateUID(), 'ics' => $ics, 'method' => 'REPLY', 'originator' => '*****@*****.**')); $this->assertEquals(1, $iMIP->getEvent()->seq); $this->assertTrue(!empty($iMIP->getEvent()->last_modified_time)); // force creation of external attendee $externalAttendee = new Calendar_Model_Attender(array('user_type' => Calendar_Model_Attender::USERTYPE_USER, 'user_id' => $iMIP->getEvent()->attendee->getFirstRecord()->user_id, 'status' => Calendar_Model_Attender::STATUS_NEEDSACTION)); // create matching event $event = new Calendar_Model_Event(array('summary' => 'TEST7', 'dtstart' => '2011-11-30 14:00:00', 'dtend' => '2011-11-30 15:00:00', 'description' => 'Early to bed and early to rise, makes a men healthy, wealthy and wise ...', 'attendee' => $this->_getAttendee(), 'organizer' => Tinebase_Core::getUser()->contact_id, 'uid' => 'a8d10369e051094ae9322bd65e8afecac010bfc8')); $event->attendee->addRecord($externalAttendee); $event = Calendar_Controller_Event::getInstance()->create($event); $this->_eventIdsToDelete[] = $event->getId(); // TEST NORMAL REPLY try { $this->_iMIPFrontend->autoProcess($iMIP); } catch (Exception $e) { $this->fail('TEST NORMAL REPLY autoProcess throws Exception: ' . $e); } unset($iMIP->existing_event); $updatedEvent = Calendar_Controller_Event::getInstance()->get($event->getId()); $updatedExternalAttendee = Calendar_Model_Attender::getAttendee($updatedEvent->attendee, $externalAttendee); $this->assertEquals(3, count($updatedEvent->attendee)); $this->assertEquals(Calendar_Model_Attender::STATUS_ACCEPTED, $updatedExternalAttendee->status, 'status not updated'); // TEST ACCEPTABLE NON RECENT REPLY $updatedExternalAttendee->status = Calendar_Model_Attender::STATUS_NEEDSACTION; Calendar_Controller_Event::getInstance()->attenderStatusUpdate($updatedEvent, $updatedExternalAttendee, $updatedExternalAttendee->status_authkey); try { $iMIP->preconditionsChecked = false; $this->_iMIPFrontend->autoProcess($iMIP); } catch (Exception $e) { $this->fail('TEST ACCEPTABLE NON RECENT REPLY autoProcess throws Exception: ' . $e); } unset($iMIP->existing_event); $updatedEvent = Calendar_Controller_Event::getInstance()->get($event->getId()); $updatedExternalAttendee = Calendar_Model_Attender::getAttendee($updatedEvent->attendee, $externalAttendee); $this->assertEquals(3, count($updatedEvent->attendee)); $this->assertEquals(Calendar_Model_Attender::STATUS_ACCEPTED, $updatedExternalAttendee->status, 'status not updated'); // check if attendee are resolved $existingEvent = $this->_iMIPFrontend->getExistingEvent($iMIP); $this->assertTrue($iMIP->existing_event->attendee instanceof Tinebase_Record_RecordSet); $this->assertEquals(3, count($iMIP->existing_event->attendee)); // TEST NON ACCEPTABLE NON RECENT REPLY $iMIP->preconditionsChecked = false; try { $this->_iMIPFrontend->autoProcess($iMIP); $this->fail('autoProcess should throw Calendar_Exception_iMIP'); } catch (Calendar_Exception_iMIP $cei) { $this->assertContains('iMIP preconditions failed: RECENT', $cei->getMessage()); } }
/** * test implicit recur (exception) series creation for attendee status only */ public function testAttendeeSetStatusRecurExceptionAllFollowing() { $from = new Tinebase_DateTime('2012-02-01 00:00:00'); $until = new Tinebase_DateTime('2012-02-29 23:59:59'); $event = new Calendar_Model_Event(array('summary' => 'Some Daily Event', 'dtstart' => '2012-02-03 09:00:00', 'dtend' => '2012-02-03 10:00:00', 'rrule' => 'FREQ=DAILY;INTERVAL=1', 'container_id' => $this->_testCalendar->getId(), 'attendee' => $this->_getAttendee())); $persistentEvent = $this->_controller->create($event); $exceptions = new Tinebase_Record_RecordSet('Calendar_Model_Event'); $recurSet = Calendar_Model_Rrule::computeRecurrenceSet($persistentEvent, $exceptions, $from, $until); // accept for sclever thisandfuture $start = $recurSet[10]; $sclever = Calendar_Model_Attender::getAttendee($start->attendee, $event->attendee[1]); $sclever->status = Calendar_Model_Attender::STATUS_ACCEPTED; $this->_controller->attenderStatusCreateRecurException($start, $sclever, $sclever->status_authkey, TRUE); $events = $this->_controller->search(new Calendar_Model_EventFilter(array(array('field' => 'container_id', 'operator' => 'equals', 'value' => $this->_testCalendar->getId()))))->sort('dtstart', 'ASC'); // assert two baseEvents $this->assertTrue($events[0]->rrule_until instanceof Tinebase_DateTime, 'rrule_until of first baseEvent is not set'); $this->assertTrue($events[0]->rrule_until < new Tinebase_DateTime('2012-02-14 09:00:00'), 'rrule_until of first baseEvent is not adopted properly'); $this->assertEquals(Calendar_Model_Attender::STATUS_NEEDSACTION, Calendar_Model_Attender::getAttendee($events[0]->attendee, $event->attendee[1])->status, 'first baseEvent status must not be touched'); $this->assertEquals($events[1]->dtstart, new Tinebase_DateTime('2012-02-14 09:00:00'), 'start of second baseEvent is wrong'); $this->assertTrue(empty($events[1]->recurid), 'second baseEvent is not a baseEvent'); $this->assertEquals($events[1]->rrule, $event->rrule, 'rrule of second baseEvent must be set'); $this->assertFalse($events[1]->rrule_until instanceof Tinebase_DateTime, 'rrule_until of second baseEvent must not be set'); $this->assertEquals(Calendar_Model_Attender::STATUS_ACCEPTED, Calendar_Model_Attender::getAttendee($events[1]->attendee, $event->attendee[1])->status, 'second baseEvent status is not touched'); }
public static function enforceEventParameters(Calendar_Model_Event $_event) { // got there any attendees added? if (!$_event->attendee instanceof Tinebase_Record_RecordSet) { $_event->attendee = new Tinebase_Record_RecordSet('Calendar_Model_Attender'); } // can happen only during create not on update if (empty($_event->organizer)) { $_event->organizer = Tinebase_Core::getUser()->contact_id; } // the organizer must always be an attendee if ($_event->organizer === Tinebase_Core::getUser()->contact_id && ($ownAttendee = Calendar_Model_Attender::getOwnAttender($_event->attendee)) == null) { $_event->attendee->addRecord(new Calendar_Model_Attender(array('user_id' => Tinebase_Core::getUser()->contact_id, 'user_type' => Calendar_Model_Attender::USERTYPE_USER, 'role' => Calendar_Model_Attender::ROLE_REQUIRED, 'status' => Calendar_Model_Attender::STATUS_ACCEPTED))); if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . " added organizer as attendee "); } } if (empty($_event->transp)) { $_event->transp = Calendar_Model_Event::TRANSP_OPAQUE; } // check also attached exdates if ($_event->exdate instanceof Tinebase_Record_RecordSet) { foreach ($_event->exdate as $exdate) { if ($exdate->is_deleted == false) { $exdate->container_id = $_event->container_id; $exdate->organizer = $_event->organizer; self::enforceEventParameters($exdate); } if (!$exdate->getId()) { // new exdates must authenticate for status updates foreach ($_event->attendee as $attendee) { if ($attendee->status_authkey) { $exdateAttedee = Calendar_Model_Attender::getAttendee($exdate->attendee, $attendee); if ($exdateAttedee) { $exdateAttedee->status_authkey = $attendee->status_authkey; } } } } } } }
/** * sclever declines event exception. * => from her iTIP perspective this is an fallout than */ public function testPerspectiveExceptionFallout() { $event = $this->testCreate(); $persistentException = $event->exdate->filter('is_deleted', 0)->getFirstRecord(); $sclever = new Calendar_Model_Attender(array('user_id' => $this->_personasContacts['sclever']->getId(), 'user_type' => Calendar_Model_Attender::USERTYPE_USER)); $persistentSClever = Calendar_Model_Attender::getAttendee($persistentException->attendee, $sclever); $persistentException->attendee->removeRecord($persistentSClever); $event = $this->_uit->update($event); //$persistentSClever->status = Calendar_Model_Attender::STATUS_DECLINED; //$this->_uit->attenderStatusUpdate($event, $persistentSClever); $currUser = $this->_uit->setCalendarUser($sclever); $event = $this->_uit->get($event->getId()); $this->_uit->setCalendarUser($currUser); $persistentException = $event->exdate->filter('is_deleted', 0)->getFirstRecord(); $this->assertNull($persistentException); }
/** * @see {http://forge.tine20.org/mantisbt/view.php?id=5686} */ public function testCreateRecurExceptionAllFollowingAttendeeAdd() { $from = new Tinebase_DateTime('2012-02-01 00:00:00'); $until = new Tinebase_DateTime('2012-02-29 23:59:59'); $persistentEvent = $this->_getDailyEvent(new Tinebase_DateTime('2012-02-03 09:00:00')); $exceptions = new Tinebase_Record_RecordSet('Calendar_Model_Event'); $recurSet = Calendar_Model_Rrule::computeRecurrenceSet($persistentEvent, $exceptions, $from, $until); $pwulf = new Calendar_Model_Attender(array('user_type' => Calendar_Model_Attender::USERTYPE_USER, 'user_id' => $this->_getPersonasContacts('pwulf')->getId())); $recurSet[5]->attendee->addRecord($pwulf); $updatedPersistentEvent = $this->_controller->createRecurException($recurSet[5], FALSE, TRUE); $this->assertEquals(3, count($updatedPersistentEvent->attendee)); $persistentPwulf = Calendar_Model_Attender::getAttendee($updatedPersistentEvent->attendee, $pwulf); $this->assertNotNull($persistentPwulf->displaycontainer_id); }
/** * updates an attender status of a event * * @param Calendar_Model_Event $_event * @param Calendar_Model_Attender $_attender * @param string $_authKey * @return Calendar_Model_Attender updated attender */ public function attenderStatusUpdate(Calendar_Model_Event $_event, Calendar_Model_Attender $_attender, $_authKey) { try { $event = $this->get($_event->getId()); if (!$event->attendee) { throw new Tinebase_Exception_NotFound('Could not find any attendee of event.'); } if (($currentAttender = Calendar_Model_Attender::getAttendee($event->attendee, $_attender)) == null) { throw new Tinebase_Exception_NotFound('Could not find attender in event.'); } $updatedAttender = clone $currentAttender; if ($currentAttender->status_authkey !== $_authKey) { if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . " no permissions to update status for {$currentAttender->user_type} {$currentAttender->user_id}"); } return $updatedAttender; } Calendar_Controller_Alarm::enforceACL($_event, $event); $currentAttenderDisplayContainerId = $currentAttender->displaycontainer_id instanceof Tinebase_Model_Container ? $currentAttender->displaycontainer_id->getId() : $currentAttender->displaycontainer_id; $attenderDisplayContainerId = $_attender->displaycontainer_id instanceof Tinebase_Model_Container ? $_attender->displaycontainer_id->getId() : $_attender->displaycontainer_id; // check if something what can be set as user has changed if ($currentAttender->status == $_attender->status && $currentAttenderDisplayContainerId == $attenderDisplayContainerId && $currentAttender->transp == $_attender->transp && !Calendar_Controller_Alarm::hasUpdates($_event, $event)) { if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->DEBUG(__METHOD__ . '::' . __LINE__ . "no status change -> do nothing"); } return $updatedAttender; } $updatedAttender->status = $_attender->status; $updatedAttender->displaycontainer_id = isset($_attender->displaycontainer_id) ? $_attender->displaycontainer_id : $updatedAttender->displaycontainer_id; $updatedAttender->transp = isset($_attender->transp) ? $_attender->transp : Calendar_Model_Event::TRANSP_OPAQUE; if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . " update attender status to {$_attender->status} for {$currentAttender->user_type} {$currentAttender->user_id}"); Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . ' set alarm_ack_time / alarm_snooze_time: ' . $updatedAttender->alarm_ack_time . ' / ' . $updatedAttender->alarm_snooze_time); } $transactionId = Tinebase_TransactionManager::getInstance()->startTransaction(Tinebase_Core::getDb()); $updatedAttender = $this->_backend->updateAttendee($updatedAttender); if ($_event->alarms instanceof Tinebase_Record_RecordSet) { foreach ($_event->alarms as $alarm) { $this->_inspectAlarmSet($event, $alarm); } Tinebase_Alarm::getInstance()->setAlarmsOfRecord($_event); } $this->_increaseDisplayContainerContentSequence($updatedAttender, $event); if ($currentAttender->status != $updatedAttender->status) { $this->_touch($event, TRUE); } Tinebase_TransactionManager::getInstance()->commitTransaction($transactionId); } catch (Exception $e) { Tinebase_TransactionManager::getInstance()->rollBack(); throw $e; } // send notifications if ($currentAttender->status != $updatedAttender->status && $this->_sendNotifications && $_event->mute != 1) { $updatedEvent = $this->get($event->getId()); $this->doSendNotifications($updatedEvent, Tinebase_Core::getUser(), 'changed', $event); } return $updatedAttender; }
/** * converts a tine20 event to an iTIP event * * @param Calendar_Model_Event $_event * @return Calendar_Model_Event */ protected function _toiTIP($_event) { if ($_event instanceof Tinebase_Record_RecordSet) { foreach ($_event as $idx => $event) { try { $_event[$idx] = $this->_toiTIP($event); } catch (Tinebase_Exception_AccessDenied $ade) { // if we don't have permissions for the exdates, this is likely a freebusy info only -> remove from set $_event->removeRecord($event); } catch (Exception $e) { $event->exdate = new Tinebase_Record_RecordSet('Calendar_Model_Event'); } } return $_event; } // get exdates if ($_event->rrule) { $_event->exdate = $this->_eventController->getRecurExceptions($_event, TRUE); } // mark any exdates as deleted if the CU does not attend and is not organizer if ($_event->exdate instanceof Tinebase_Record_RecordSet && $_event->organizer != $this->_calendarUser->user_id) { foreach ($_event->exdate as $exdate) { $CUAttendee = Calendar_Model_Attender::getAttendee($exdate->attendee, $this->_calendarUser); if ($exdate->is_deleted == false && !$CUAttendee) { $exdate->is_deleted = true; } } } return $_event; }
public function testDeleteImplicitDecline() { $_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 = $this->_getVCalendar(dirname(__FILE__) . '/../../Import/files/event_with_custom_alarm.ics'); $id = Tinebase_Record_Abstract::generateUID(); $event = Calendar_Frontend_WebDAV_Event::create($this->objects['sharedContainer'], "{$id}.ics", $vcalendar); $pwulf = new Calendar_Model_Attender(array('user_type' => Calendar_Model_Attender::USERTYPE_USER, 'user_id' => array_value('pwulf', Zend_Registry::get('personas'))->contact_id)); $pwulfAttendee = Calendar_Model_Attender::getAttendee($event->getRecord()->attendee, $pwulf); $pwulfPersonalCal = Tinebase_Container::getInstance()->getContainerById($pwulfAttendee->displaycontainer_id); $pwulfPersonalEvent = new Calendar_Frontend_WebDAV_Event($pwulfPersonalCal, "{$id}.ics"); $pwulfPersonalEvent->delete(); $pwulfPersonalEvent = new Calendar_Frontend_WebDAV_Event($pwulfPersonalCal, "{$id}.ics"); $pwulfAttendee = Calendar_Model_Attender::getAttendee($pwulfPersonalEvent->getRecord()->attendee, $pwulf); $this->assertEquals(Calendar_Model_Attender::STATUS_DECLINED, $pwulfAttendee->status, 'event must be declined for pwulf'); $this->assertEquals(0, $pwulfPersonalEvent->getRecord()->is_deleted, 'event must not be deleted'); }
/** * updates an attender status of a event * * @param Calendar_Model_Event $_event * @param Calendar_Model_Attender $_attender * @param string $_authKey * @return Calendar_Model_Attender updated attender */ public function attenderStatusUpdate(Calendar_Model_Event $_event, Calendar_Model_Attender $_attender, $_authKey) { try { $event = $this->get($_event->getId()); if (!$event->attendee) { throw new Tinebase_Exception_NotFound('Could not find any attendee of event.'); } if (($currentAttender = Calendar_Model_Attender::getAttendee($event->attendee, $_attender)) == null) { throw new Tinebase_Exception_NotFound('Could not find attender in event.'); } $updatedAttender = clone $currentAttender; if ($currentAttender->status_authkey !== $_authKey) { if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . " no permissions to update status for {$currentAttender->user_type} {$currentAttender->user_id}"); } return $updatedAttender; } // check if something what can be set as user has changed if ($currentAttender->status == $_attender->status && $currentAttender->displaycontainer_id == $_attender->displaycontainer_id && $currentAttender->alarm_ack_time == $_attender->alarm_ack_time && $currentAttender->alarm_snooze_time == $_attender->alarm_snooze_time) { if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->DEBUG(__METHOD__ . '::' . __LINE__ . "no status change -> do nothing"); } return $updatedAttender; } $updatedAttender->status = $_attender->status; $updatedAttender->displaycontainer_id = $_attender->displaycontainer_id; $updatedAttender->alarm_ack_time = isset($_attender->alarm_ack_time) ? $_attender->alarm_ack_time : $updatedAttender->alarm_ack_time; $updatedAttender->alarm_snooze_time = isset($_attender->alarm_snooze_time) ? $_attender->alarm_snooze_time : $updatedAttender->alarm_snooze_time; if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . " update attender status to {$_attender->status} for {$currentAttender->user_type} {$currentAttender->user_id}"); } $transactionId = Tinebase_TransactionManager::getInstance()->startTransaction(Tinebase_Core::getDb()); $updatedAttender = $this->_backend->updateAttendee($updatedAttender); $this->_increaseDisplayContainerContentSequence($updatedAttender, $event); if ($currentAttender->status != $updatedAttender->status) { $this->_touch($event, TRUE); } Tinebase_TransactionManager::getInstance()->commitTransaction($transactionId); } catch (Exception $e) { Tinebase_TransactionManager::getInstance()->rollBack(); throw $e; } // send notifications if ($currentAttender->status != $updatedAttender->status && $this->_sendNotifications) { $updatedEvent = $this->get($event->getId()); $this->doSendNotifications($updatedEvent, $this->_currentAccount, 'changed', $event); } return $updatedAttender; }
/** * converts an iTIP event to a tine20 event * * @param Calendar_Model_Event $_event * @param Calendar_Model_Event $_currentEvent (not iTIP!) */ protected function _fromiTIP($_event, $_currentEvent) { if (!$_event->rrule) { $_event->exdate = NULL; } if ($_event->exdate instanceof Tinebase_Record_RecordSet) { try { $currExdates = $this->_eventController->getRecurExceptions($_event, TRUE); $this->getAlarms($currExdates); $currClientExdates = $this->_eventController->getRecurExceptions($_event, TRUE, $this->getEventFilter()); $this->getAlarms($currClientExdates); } catch (Tinebase_Exception_NotFound $e) { $currExdates = NULL; $currClientExdates = NULL; } foreach ($_event->exdate as $idx => $exdate) { try { $this->_prepareException($_event, $exdate); } catch (Exception $e) { } $currExdate = $currExdates instanceof Tinebase_Record_RecordSet ? $currExdates->filter('recurid', $exdate->recurid)->getFirstRecord() : NULL; if ($exdate->is_deleted) { // reset implicit filter fallouts and mark as don't touch (seq = -1) $currClientExdate = $currClientExdates instanceof Tinebase_Record_RecordSet ? $currClientExdates->filter('recurid', $exdate->recurid)->getFirstRecord() : NULL; if ($currClientExdate && $currClientExdate->is_deleted) { $_event->exdate[$idx] = $currExdate; $currExdate->seq = -1; continue; } } $this->_fromiTIP($exdate, $currExdate ? $currExdate : clone $_currentEvent); } } // assert organizer $_event->organizer = $_event->organizer ?: ($_currentEvent->organizer ?: $this->_calendarUser->user_id); $this->_addAttendeeWithoutEmail($_event, $_currentEvent); $CUAttendee = Calendar_Model_Attender::getAttendee($_event->attendee, $this->_calendarUser); $currentCUAttendee = Calendar_Model_Attender::getAttendee($_currentEvent->attendee, $this->_calendarUser); $isOrganizer = $_event->isOrganizer($this->_calendarUser); // remove perspective if ($CUAttendee && !$isOrganizer) { $CUAttendee->transp = $_event->transp; $_event->transp = $_currentEvent->transp ? $_currentEvent->transp : $_event->transp; } // apply changes to original alarms $_currentEvent->alarms = $_currentEvent->alarms instanceof Tinebase_Record_RecordSet ? $_currentEvent->alarms : new Tinebase_Record_RecordSet('Tinebase_Model_Alarm'); $_event->alarms = $_event->alarms instanceof Tinebase_Record_RecordSet ? $_event->alarms : new Tinebase_Record_RecordSet('Tinebase_Model_Alarm'); foreach ($_currentEvent->alarms as $currentAlarm) { if (Calendar_Model_Attender::isAlarmForAttendee($this->_calendarUser, $currentAlarm)) { $alarmUpdate = Calendar_Controller_Alarm::getMatchingAlarm($_event->alarms, $currentAlarm); if ($alarmUpdate) { // we could map the alarm => save ack & snooze options if ($dtAck = Calendar_Controller_Alarm::getAcknowledgeTime($alarmUpdate)) { Calendar_Controller_Alarm::setAcknowledgeTime($currentAlarm, $dtAck, $this->getCalendarUser()->user_id); } if ($dtSnooze = Calendar_Controller_Alarm::getSnoozeTime($alarmUpdate)) { Calendar_Controller_Alarm::setSnoozeTime($currentAlarm, $dtSnooze, $this->getCalendarUser()->user_id); } $_event->alarms->removeRecord($alarmUpdate); } else { // alarm is to be skiped/deleted if (!$currentAlarm->getOption('attendee')) { Calendar_Controller_Alarm::skipAlarm($currentAlarm, $this->_calendarUser); } else { $_currentEvent->alarms->removeRecord($currentAlarm); } } } } if (!$isOrganizer) { $_event->alarms->setOption('attendee', Calendar_Controller_Alarm::attendeeToOption($this->_calendarUser)); } $_event->alarms->merge($_currentEvent->alarms); // assert organizer for personal calendars to be calendar owner if ($this->_currentEventFacadeContainer && $this->_currentEventFacadeContainer->getId() == $_event->container_id && $this->_currentEventFacadeContainer->type == Tinebase_Model_Container::TYPE_PERSONAL && !$_event->hasExternalOrganizer()) { $_event->organizer = $this->_calendarUser->user_id; } // in MS world only cal_user can do status updates if ($CUAttendee) { $CUAttendee->status_authkey = $currentCUAttendee ? $currentCUAttendee->status_authkey : NULL; } }
/** * add given attendee if not present under given conditions * * @param Calendar_Model_Attender $attendee * @param bool $ifOrganizer only add attendee if he's organizer * @param bool $ifNoOtherAttendee only add attendee if no other attendee are present * @param bool $personalOnly only for personal containers * @return Calendar_Model_Attender asserted attendee */ public function assertAttendee($attendee, $ifOrganizer = true, $ifNoOtherAttendee = false, $personalOnly = false) { if ($personalOnly) { try { $container = Tinebase_Container::getInstance()->getContainerById($this->container_id); if ($container->type != Tinebase_Model_Container::TYPE_PERSONAL) { if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . " not adding attendee as container is not personal."); } return; } } catch (Exception $e) { Tinebase_Core::getLogger()->info(__METHOD__ . '::' . __LINE__ . " cannot get container: {$e}"); } } if ($ifNoOtherAttendee && $this->attendee instanceof Tinebase_Record_RecordSet && $this->attendee->count() > 0) { if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . " not adding attendee as other attendee are present."); } return; } $assertionAttendee = Calendar_Model_Attender::getAttendee($this->attendee, $attendee); if (!$assertionAttendee) { if ($ifOrganizer && !$this->isOrganizer($attendee)) { if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . " not adding attendee as he is not organizer."); } } else { if (Tinebase_Core::isLogLevel(Zend_Log::DEBUG)) { Tinebase_Core::getLogger()->debug(__METHOD__ . '::' . __LINE__ . " adding attendee."); } $assertionAttendee = new Calendar_Model_Attender(array('user_id' => $attendee->user_id, 'user_type' => $attendee->user_type, 'status' => Calendar_Model_Attender::STATUS_ACCEPTED, 'role' => Calendar_Model_Attender::ROLE_REQUIRED)); if (!$this->attendee instanceof Tinebase_Record_RecordSet) { $this->attendee = new Tinebase_Record_RecordSet('Calendar_Model_Attender'); } $this->attendee->addRecord($assertionAttendee); } } return $assertionAttendee; }
/** * helper function for getting attender (current user or persona) from attendee set * * @param Tinebase_Record_RecordSet $attendee * @param string $persona * @return Calendar_Model_Attender */ protected function _getAttenderFromAttendeeSet($attendee, $persona = null) { $contactId = $persona ? $this->_getPersonasContacts($persona)->getId() : Tinebase_Core::getUser()->contact_id; $attender = new Calendar_Model_Attender(array('user_id' => $contactId, 'user_type' => Calendar_Model_Attender::USERTYPE_USER)); return Calendar_Model_Attender::getAttendee($attendee, $attender); }