Set the appointment time/duration.
public setDatetime ( array $datetime = [] ) | ||
$datetime | array | An array containing: - start: (Horde_Date) The start time. - end: (Horde_Date) The end time. If omitted, must include duration or allday. - duration: (integer) The event duration in seconds. - allday: (boolean) If true, this is an allday event. |
public function testEncodingSimpleExceptions() { $this->markTestSkipped('Needs updated fixture.'); $l = new Horde_Test_Log(); $logger = $l->getLogger(); //$logger = new Horde_Log_Logger(new Horde_Log_Handler_Stream(fopen('/tmp/test.log', 'a'))); // Every other week recurrence, on thursday, no end. $r = new Horde_Date_Recurrence('2011-12-01T15:00:00'); $r->setRecurType(Horde_Date_Recurrence::RECUR_WEEKLY); $r->setRecurInterval(2); $r->setRecurOnDay(Horde_Date::MASK_THURSDAY); $r->addException(2011, 12, 29); $e = new Horde_ActiveSync_Message_Exception(); $d = new Horde_Date('2011-12-29T15:00:00'); $e->setExceptionStartTime($d); $e->deleted = true; $appt = new Horde_ActiveSync_Message_Appointment(array('logger' => $logger)); $appt->setSubject('Event Title'); $appt->setBody('Event Description'); $appt->setLocation('Philadelphia, PA'); $start = new Horde_Date('2011-12-01T15:00:00'); $appt->setDatetime(array('start' => $start, 'end' => new Horde_Date('2011-12-01T16:00:00'), 'allday' => false)); $appt->setTimezone($start); $appt->setSensitivity(Horde_ActiveSync_Message_Appointment::SENSITIVITY_PERSONAL); $appt->setBusyStatus(Horde_ActiveSync_Message_Appointment::BUSYSTATUS_BUSY); $appt->setDTStamp($start->timestamp()); $appt->setRecurrence($r); $appt->addException($e); $stream = fopen('php://memory', 'w+'); $encoder = new Horde_ActiveSync_Wbxml_Encoder($stream); $encoder->setLogger($logger); $encoder->startTag(Horde_ActiveSync::SYNC_DATA); $appt->encodeStream($encoder); $encoder->endTag(); $fixture = file_get_contents(__DIR__ . '/fixtures/simpleexception.wbxml'); rewind($stream); $results = stream_get_contents($stream); fclose($stream); $this->assertEquals($fixture, $results); }
/** * Export this event as a MS ActiveSync Message * * @param array $options Options: * - protocolversion: (float) The EAS version to support * DEFAULT: 2.5 * - bodyprefs: (array) A BODYPREFERENCE array. * DEFAULT: none (No body prefs enforced). * - truncation: (integer) Truncate event body to this length * DEFAULT: none (No truncation). * * @return Horde_ActiveSync_Message_Appointment */ public function toASAppointment(array $options = array()) { global $prefs, $registry; $message = new Horde_ActiveSync_Message_Appointment(array('logger' => $GLOBALS['injector']->getInstance('Horde_Log_Logger'), 'protocolversion' => $options['protocolversion'])); if (!$this->isPrivate()) { // Handle body/truncation if (!empty($options['bodyprefs'])) { if (Horde_String::length($this->description) > 0) { $bp = $options['bodyprefs']; $note = new Horde_ActiveSync_Message_AirSyncBaseBody(); // No HTML supported. Always use plaintext. $note->type = Horde_ActiveSync::BODYPREF_TYPE_PLAIN; if (isset($bp[Horde_ActiveSync::BODYPREF_TYPE_PLAIN]['truncationsize'])) { $truncation = $bp[Horde_ActiveSync::BODYPREF_TYPE_PLAIN]['truncationsize']; } elseif (isset($bp[Horde_ActiveSync::BODYPREF_TYPE_HTML])) { $truncation = $bp[Horde_ActiveSync::BODYPREF_TYPE_HTML]['truncationsize']; $this->description = Horde_Text_Filter::filter($this->description, 'Text2html', array('parselevel' => Horde_Text_Filter_Text2html::MICRO)); } else { $truncation = false; } if ($truncation && Horde_String::length($this->description) > $truncation) { $note->data = Horde_String::substr($this->desciption, 0, $truncation); $note->truncated = 1; } else { $note->data = $this->description; } $note->estimateddatasize = Horde_String::length($this->description); $message->airsyncbasebody = $note; } } else { $message->setBody($this->description); } $message->setLocation($this->location); } $message->setSubject($this->getTitle()); $message->setDatetime(array('start' => $this->start, 'end' => $this->end, 'allday' => $this->isAllDay())); $message->setTimezone($this->start); // Organizer if (count($this->attendees)) { if ($this->creator == $registry->getAuth()) { $as_ident = $prefs->getValue('activesync_identity') == 'horde' ? $prefs->getValue('default_identity') : $prefs->getValue('activesync_identity'); $name = $GLOBALS['injector']->getInstance('Horde_Core_Factory_Identity')->create($this->creator)->getValue('fullname', $as_ident); $email = $GLOBALS['injector']->getInstance('Horde_Core_Factory_Identity')->create($this->creator)->getValue('from_addr', $as_ident); } else { $name = Kronolith::getUserName($this->creator); $email = Kronolith::getUserEmail($this->creator); } $message->setOrganizer(array('name' => $name, 'email' => $email)); } // Privacy $message->setSensitivity($this->private ? Horde_ActiveSync_Message_Appointment::SENSITIVITY_PRIVATE : Horde_ActiveSync_Message_Appointment::SENSITIVITY_NORMAL); // Busy Status switch ($this->status) { case Kronolith::STATUS_CANCELLED: $status = Horde_ActiveSync_Message_Appointment::BUSYSTATUS_FREE; break; case Kronolith::STATUS_CONFIRMED: $status = Horde_ActiveSync_Message_Appointment::BUSYSTATUS_BUSY; break; case Kronolith::STATUS_TENTATIVE: $status = Horde_ActiveSync_Message_Appointment::BUSYSTATUS_TENTATIVE; case Kronolith::STATUS_FREE: case Kronolith::STATUS_NONE: $status = Horde_ActiveSync_Message_Appointment::BUSYSTATUS_FREE; } $message->setBusyStatus($status); // DTStamp $message->setDTStamp($_SERVER['REQUEST_TIME']); // Recurrence if ($this->recurs()) { $message->setRecurrence($this->recurrence, $GLOBALS['prefs']->getValue('week_start_monday')); /* Exceptions are tricky. Exceptions, even those that represent * deleted instances of a recurring event, must be added. To do this * we query the storage for all the events that represent exceptions * (those with the baseid == $this->uid) and then remove the * exceptionoriginaldate from the list of exceptions we know about. * Any dates left in this list when we are done, must represent * deleted instances of this recurring event.*/ if (!empty($this->recurrence) && ($exceptions = $this->recurrence->getExceptions())) { $results = $this->boundExceptions(); foreach ($results as $exception) { $e = new Horde_ActiveSync_Message_Exception(array('protocolversion' => $options['protocolversion'])); $e->setDateTime(array('start' => $exception->start, 'end' => $exception->end, 'allday' => $exception->isAllDay())); // The start time of the *original* recurring event $e->setExceptionStartTime($exception->exceptionoriginaldate); $originaldate = $exception->exceptionoriginaldate->format('Ymd'); $key = array_search($originaldate, $exceptions); if ($key !== false) { unset($exceptions[$key]); } // Remaining properties that could be different $e->setSubject($exception->getTitle()); if (!$exception->isPrivate()) { $e->setLocation($exception->location); $e->setBody($exception->description); } $e->setSensitivity($exception->private ? Horde_ActiveSync_Message_Appointment::SENSITIVITY_PRIVATE : Horde_ActiveSync_Message_Appointment::SENSITIVITY_NORMAL); $e->setReminder($exception->alarm); $e->setDTStamp($_SERVER['REQUEST_TIME']); if ($options['protocolversion'] > Horde_ActiveSync::VERSION_TWELVEONE) { switch ($exception->status) { case Kronolith::STATUS_TENTATIVE: $e->responsetype = Horde_ActiveSync_Message_Appointment::RESPONSE_TENTATIVE; break; case Kronolith::STATUS_NONE: $e->responsetype = Horde_ActiveSync_Message_Appointment::RESPONSE_NORESPONSE; break; case Kronolith::STATUS_CONFIRMED: $e->responsetype = Horde_ActiveSync_Message_Appointment::RESPONSE_ACCEPTED; break; default: $e->responsetype = Horde_ActiveSync_Message_Appointment::RESPONSE_NONE; } } // Tags/Categories if (!$exception->isPrivate()) { foreach ($exception->tags as $tag) { $e->addCategory($tag); } } $message->addexception($e); } // Any dates left in $exceptions must be deleted exceptions foreach ($exceptions as $deleted) { $e = new Horde_ActiveSync_Message_Exception(array('protocolversion' => $options['protocolversion'])); // Kronolith stores the date only, but some AS clients need // the datetime. list($year, $month, $mday) = sscanf($deleted, '%04d%02d%02d'); $st = clone $this->start; $st->year = $year; $st->month = $month; $st->mday = $mday; $e->setExceptionStartTime($st); $e->deleted = true; $message->addException($e); } } } // Attendees if (!$this->isPrivate() && count($this->attendees)) { $message->setMeetingStatus(Horde_ActiveSync_Message_Appointment::MEETING_IS_MEETING); foreach ($this->attendees as $email => $properties) { $attendee = new Horde_ActiveSync_Message_Attendee(array('protocolversion' => $options['protocolversion'])); $adr_obj = new Horde_Mail_Rfc822_Address($email); $attendee->name = $adr_obj->label; $attendee->email = $adr_obj->bare_address; // AS only has required or optional, and only EAS Version > 2.5 if ($options['protocolversion'] > Horde_ActiveSync::VERSION_TWOFIVE) { $attendee->type = $properties['attendance'] !== Kronolith::PART_REQUIRED ? Horde_ActiveSync_Message_Attendee::TYPE_OPTIONAL : Horde_ActiveSync_Message_Attendee::TYPE_REQUIRED; switch ($properties['response']) { case Kronolith::RESPONSE_NONE: $attendee->status = Horde_ActiveSync_Message_Attendee::STATUS_NORESPONSE; break; case Kronolith::RESPONSE_ACCEPTED: $attendee->status = Horde_ActiveSync_Message_Attendee::STATUS_ACCEPT; break; case Kronolith::RESPONSE_DECLINED: $attendee->status = Horde_ActiveSync_Message_Attendee::STATUS_DECLINE; break; case Kronolith::RESPONSE_TENTATIVE: $attendee->status = Horde_ActiveSync_Message_Attendee::STATUS_TENTATIVE; break; default: $attendee->status = Horde_ActiveSync_Message_Attendee::STATUS_UNKNOWN; } } $message->addAttendee($attendee); } } else { $message->setMeetingStatus(Horde_ActiveSync_Message_Appointment::MEETING_NOT_MEETING); } // Resources if ($options['protocolversion'] > Horde_ActiveSync::VERSION_TWOFIVE) { $r = $this->getResources(); foreach ($r as $id => $data) { $resource = Kronolith::getDriver('Resource')->getResource($id); // EAS *REQUIRES* an email field for Resources. If it is missing // a number of clients will fail, losing push. if ($resource->get('email')) { $attendee = new Horde_ActiveSync_Message_Attendee(array('protocolversion' => $options['protocolversion'])); $attendee->email = $resource->get('email'); $attendee->type = Horde_ActiveSync_Message_Attendee::TYPE_RESOURCE; $attendee->name = $data['name']; $attendee->status = $data['response']; $message->addAttendee($attendee); } } } // Reminder if ($this->alarm) { $message->setReminder($this->alarm); } // Categories (tags) if (!$this->isPrivate()) { foreach ($this->tags as $tag) { $message->addCategory($tag); } } // EAS 14 if ($options['protocolversion'] > Horde_ActiveSync::VERSION_TWELVEONE) { // We don't track the actual responses we sent to other's invitations. // Set this based on the status flag. switch ($this->status) { case Kronolith::STATUS_TENTATIVE: $message->responsetype = Horde_ActiveSync_Message_Appointment::RESPONSE_TENTATIVE; break; case Kronolith::STATUS_NONE: $message->responsetype = Horde_ActiveSync_Message_Appointment::RESPONSE_NORESPONSE; break; case Kronolith::STATUS_CONFIRMED: $message->responsetype = Horde_ActiveSync_Message_Appointment::RESPONSE_ACCEPTED; break; default: $message->responsetype = Horde_ActiveSync_Message_Appointment::RESPONSE_NONE; } } // 14.1 if ($options['protocolversion'] >= Horde_ActiveSync::VERSION_FOURTEENONE) { $message->onlinemeetingexternallink = $this->url; } return $message; }
/** * Test deprecated setDatetime method since it's still used in FW_52. */ public function testSetDatetimeAlldayHandling() { $l = new Horde_Test_Log(); $logger = $l->getLogger(); // Test the deprecated setDatetime method's ability to properly detect // and set properties. // Single day 00:00 to 00:00 $message = new Horde_ActiveSync_Message_Appointment(array('logger' => $logger, 'protocolversion' => Horde_ActiveSync::VERSION_FOURTEEN)); $start = new Horde_Date('1970-03-20T00:00:00', 'America/New_York'); $end = new Horde_Date('1970-03-21T00:00:00', 'America/New_York'); $message->setDatetime(array('start' => $start, 'end' => $end)); $this->assertEquals(true, $message->alldayevent); // Multiday 00:00 to 23:59 $message = new Horde_ActiveSync_Message_Appointment(array('logger' => $logger, 'protocolversion' => Horde_ActiveSync::VERSION_FOURTEEN)); $start = new Horde_Date('1970-03-20T00:00:00', 'America/New_York'); $end = new Horde_Date('1970-03-21T23:59:00', 'America/New_York'); $message->setDatetime(array('start' => $start, 'end' => $end)); $this->assertEquals(true, $message->alldayevent); $end = $message->endtime; $end->setTimezone('America/New_York'); $this->assertEquals('1970-03-22 00:00:00', (string) $end); // Single day with incorrect time part, no endtime given. $message = new Horde_ActiveSync_Message_Appointment(array('logger' => $logger, 'protocolversion' => Horde_ActiveSync::VERSION_FOURTEEN)); $start = new Horde_Date('1970-03-20T04:00:00', 'America/New_York'); $message->setDatetime(array('start' => $start, 'allday' => true)); $this->assertEquals(true, $message->alldayevent); $start = $message->starttime; $start->setTimezone('America/New_York'); $this->assertEquals('1970-03-20 00:00:00', (string) $start); $end = $message->endtime; $end->setTimezone('America/New_York'); $this->assertEquals('1970-03-21 00:00:00', (string) $end); // Single day, no endtime given. $message = new Horde_ActiveSync_Message_Appointment(array('logger' => $logger, 'protocolversion' => Horde_ActiveSync::VERSION_FOURTEEN)); $start = new Horde_Date('1970-03-20T00:00:00', 'America/New_York'); $message->setDatetime(array('start' => $start, 'allday' => true)); $this->assertEquals(true, $message->alldayevent); $end = $message->endtime; $end->setTimezone('America/New_York'); $this->assertEquals('1970-03-21 00:00:00', (string) $end); // Make sure non-all day events don't inadvertently get converted to one $message = new Horde_ActiveSync_Message_Appointment(array('logger' => $logger, 'protocolversion' => Horde_ActiveSync::VERSION_FOURTEEN)); $start = new Horde_Date('1970-03-20T05:00:00', 'America/New_York'); $end = new Horde_Date('1970-03-21T00:00:00', 'America/New_York'); $message->setDatetime(array('start' => $start, 'end' => $end)); $this->assertEquals(false, $message->alldayevent); $start = $message->starttime; $start->setTimezone('America/New_York'); $this->assertEquals('1970-03-20 05:00:00', (string) $start); // Incorrect timeparts given, but allday flag is set. $message = new Horde_ActiveSync_Message_Appointment(array('logger' => $logger, 'protocolversion' => Horde_ActiveSync::VERSION_FOURTEEN)); $start = new Horde_Date('1970-03-20T00:00:00', 'America/New_York'); $end = new Horde_Date('1970-03-21T05:00:00', 'America/New_York'); $message->setDatetime(array('start' => $start, 'end' => $end, 'allday' => true)); $this->assertEquals(true, $message->alldayevent); $start = $message->starttime; $start->setTimezone('America/New_York'); $end = $message->endtime; $end->setTimezone('America/New_York'); $this->assertEquals('1970-03-20 00:00:00', (string) $start); $this->assertEquals('1970-03-22 00:00:00', (string) $end); $message = new Horde_ActiveSync_Message_Appointment(array('logger' => $logger, 'protocolversion' => Horde_ActiveSync::VERSION_FOURTEEN)); $start = new Horde_Date('1970-03-20T08:00:00', 'America/New_York'); $end = new Horde_Date('1970-03-21T05:00:00', 'America/New_York'); $message->setDatetime(array('start' => $start, 'end' => $end, 'allday' => true)); $this->assertEquals(true, $message->alldayevent); $start = $message->starttime; $start->setTimezone('America/New_York'); $end = $message->endtime; $end->setTimezone('America/New_York'); $this->assertEquals('1970-03-20 00:00:00', (string) $start); $this->assertEquals('1970-03-22 00:00:00', (string) $end); }