Skip to content

Commit

Permalink
Replaced deprecated gmstrftime() with IntlDateFormatter.
Browse files Browse the repository at this point in the history
Move converter from Streamer to Utils for logging.
Make public methods start with an uppercase letter.
Print cutoffdate in human readable format (YYYY-MM-DD).

References: Issue #103
  • Loading branch information
grammmichi authored and gromandreas committed Nov 3, 2023
1 parent 0ec6aa0 commit 2a3ca65
Show file tree
Hide file tree
Showing 6 changed files with 52 additions and 43 deletions.
31 changes: 2 additions & 29 deletions lib/core/streamer.php
Expand Up @@ -165,7 +165,7 @@ public function Decode(&$decoder) {
if (isset($map[self::STREAMER_TYPE])) {
// Complex type, decode recursively
if ($map[self::STREAMER_TYPE] == self::STREAMER_TYPE_DATE || $map[self::STREAMER_TYPE] == self::STREAMER_TYPE_DATE_DASHES) {
$decoded = Utils::parseDate($decoder->getElementContent());
$decoded = Utils::ParseDate($decoder->getElementContent());
if (!$decoder->getElementEndTag()) {
return false;
}
Expand Down Expand Up @@ -333,7 +333,7 @@ public function Encode(&$encoder) {

if (isset($map[self::STREAMER_TYPE]) && ($map[self::STREAMER_TYPE] == self::STREAMER_TYPE_DATE || $map[self::STREAMER_TYPE] == self::STREAMER_TYPE_DATE_DASHES)) {
if ($this->{$map[self::STREAMER_VAR]} != 0) { // don't output 1-1-1970
$encoder->content($this->formatDate($this->{$map[self::STREAMER_VAR]}, $map[self::STREAMER_TYPE]));
$encoder->content(Utils::FormatDate($this->{$map[self::STREAMER_VAR]}, $map[self::STREAMER_TYPE]));
}
}
elseif (isset($map[self::STREAMER_TYPE]) && $map[self::STREAMER_TYPE] == self::STREAMER_TYPE_HEX) {
Expand Down Expand Up @@ -463,31 +463,4 @@ public function jsonDeserialize($stdObj) {
}
}
}

/*----------------------------------------------------------------------------------------------------------
* Private methods for conversion
*/

/**
* Formats a timestamp
* Oh yeah, this is beautiful. Exchange outputs date fields differently in calendar items
* and emails. We could just always send one or the other, but unfortunately nokia's 'Mail for
* exchange' depends on this quirk. So we have to send a different date type depending on where
* it's used. Sigh.
*
* @param int $ts
* @param int $type
*
* @return string
*/
private function formatDate($ts, $type) {
if ($type == self::STREAMER_TYPE_DATE) {
return gmstrftime("%Y%m%dT%H%M%SZ", $ts);
}
if ($type == self::STREAMER_TYPE_DATE_DASHES) {
return gmstrftime("%Y-%m-%dT%H:%M:%S.000Z", $ts);
}
// fallback to dashes (should never be reached)
return gmstrftime("%Y-%m-%dT%H:%M:%S.000Z", $ts);
}
}
4 changes: 2 additions & 2 deletions lib/grommunio/grommunio.php
Expand Up @@ -872,13 +872,13 @@ public function MeetingResponse($folderid, $request) {

// AS-16.1: did the attendee propose a new time ?
if (!empty($request['proposedstarttime'])) {
$request['proposedstarttime'] = Utils::parseDate($request['proposedstarttime']);
$request['proposedstarttime'] = Utils::ParseDate($request['proposedstarttime']);
}
else {
$request['proposedstarttime'] = false;
}
if (!empty($request['proposedendtime'])) {
$request['proposedendtime'] = Utils::parseDate($request['proposedendtime']);
$request['proposedendtime'] = Utils::ParseDate($request['proposedendtime']);
}
else {
$request['proposedendtime'] = false;
Expand Down
2 changes: 1 addition & 1 deletion lib/grommunio/importer.php
Expand Up @@ -248,7 +248,7 @@ private function isModificationAllowed($messageid) {

// check the sync interval
if ($this->cutoffdate !== false) {
SLog::Write(LOGLEVEL_DEBUG, sprintf("ImportChangesICS->isModificationAllowed('%s'): cut off date is: %s", $messageid, $this->cutoffdate));
SLog::Write(LOGLEVEL_DEBUG, sprintf("ImportChangesICS->isModificationAllowed('%s'): cut off date is: %s (%s)", $messageid, Utils::FormatDate($this->cutoffdate), $this->cutoffdate));
if (($this->contentClass == "Email" && !MAPIUtils::IsInEmailSyncInterval($this->store, $mapimessage, $this->cutoffdate)) ||
($this->contentClass == "Calendar" && !MAPIUtils::IsInCalendarSyncInterval($this->store, $mapimessage, $this->cutoffdate))) {
SLog::Write(LOGLEVEL_WARN, sprintf("ImportChangesICS->isModificationAllowed('%s'): Message in %s is outside the sync interval. Data not saved.", $messageid, $this->contentClass));
Expand Down
17 changes: 9 additions & 8 deletions lib/grommunio/mapiprovider.php
Expand Up @@ -459,6 +459,7 @@ private function getRecurrence($mapimessage, $recurprops, &$syncMessage, &$syncR
break;
}
}

// Termination
switch ($recurrence->recur["term"]) {
case 0x21:
Expand Down Expand Up @@ -1438,8 +1439,8 @@ private function setAppointment($mapimessage, $appointment) {

// AS 16: incoming instanceid means we need to create/update an appointment exception
if (Request::GetProtocolVersion() >= 16.0 && isset($appointment->instanceid) && $appointment->instanceid) {
// this property wasn't decoded so use Streamer->parseDate to convert it into a timestamp and get basedate from it
$instanceid = Utils::parseDate($appointment->instanceid);
// this property wasn't decoded so use Utils->ParseDate to convert it into a timestamp and get basedate from it
$instanceid = Utils::ParseDate($appointment->instanceid);
$basedate = $this->getDayStartOfTimestamp($instanceid);

// get compatible TZ data
Expand Down Expand Up @@ -1526,11 +1527,11 @@ private function setAppointment($mapimessage, $appointment) {

if (isset($existingstartendprops[$amapping["starttime"]]) && !isset($appointment->starttime)) {
$appointment->starttime = $existingstartendprops[$amapping["starttime"]];
SLog::Write(LOGLEVEL_WBXML, sprintf("MAPIProvider->setAppointment(): Parameter 'starttime' was not set, using value from MAPI %d (%s).", $appointment->starttime, gmstrftime("%Y%m%dT%H%M%SZ", $appointment->starttime)));
SLog::Write(LOGLEVEL_WBXML, sprintf("MAPIProvider->setAppointment(): Parameter 'starttime' was not set, using value from MAPI %d (%s).", $appointment->starttime, Utils::FormatDate($appointment->starttime)));
}
if (isset($existingstartendprops[$amapping["endtime"]]) && !isset($appointment->endtime)) {
$appointment->endtime = $existingstartendprops[$amapping["endtime"]];
SLog::Write(LOGLEVEL_WBXML, sprintf("MAPIProvider->setAppointment(): Parameter 'endtime' was not set, using value from MAPI %d (%s).", $appointment->endtime, gmstrftime("%Y%m%dT%H%M%SZ", $appointment->endtime)));
SLog::Write(LOGLEVEL_WBXML, sprintf("MAPIProvider->setAppointment(): Parameter 'endtime' was not set, using value from MAPI %d (%s).", $appointment->endtime, Utils::FormatDate($appointment->endtime)));
}
}
if (!isset($appointment->starttime) || !isset($appointment->endtime)) {
Expand Down Expand Up @@ -2187,7 +2188,7 @@ private function GetTZOffset($ts) {
$Offset = date("O", $ts);

$Parity = $Offset < 0 ? -1 : 1;
$Offset = $Parity * $Offset;
$Offset *= $Parity;
$Offset = ($Offset - ($Offset % 100)) / 100 * 60 + $Offset % 100;

return $Parity * $Offset;
Expand Down Expand Up @@ -2546,7 +2547,7 @@ private function getTimestampOfWeek($year, $month, $week, $wday, $hour, $minute,
while (1) {
$monthnow = gmdate("n", $date); // gmdate returns 1-12
if ($monthnow > $month) {
$date = $date - (24 * 7 * 60 * 60);
$date -= (24 * 7 * 60 * 60);
}
else {
break;
Expand Down Expand Up @@ -2853,9 +2854,9 @@ private function setRecurrence($message, &$recur) {
*
* @see http://developer.berlios.de/mantis/view.php?id=486
*
* @param string $email
* @param string $email
*
* @return string or false on error
* @return string or false on error
*/
private function extractEmailAddress($email) {
if (!isset($this->zRFC822)) {
Expand Down
4 changes: 2 additions & 2 deletions lib/syncobjects/syncappointment.php
Expand Up @@ -337,12 +337,12 @@ public function Check($logAsDebug = false) {
// Case 1, 3a (endtime won't be changed as it's set)
if (!isset($this->starttime)) {
$this->starttime = $calcstart;
SLog::Write(LOGLEVEL_WBXML, sprintf("SyncAppointment->Check(): Parameter 'starttime' was not set, setting it to %d (%s).", $this->starttime, gmstrftime("%Y%m%dT%H%M%SZ", $this->starttime)));
SLog::Write(LOGLEVEL_WBXML, sprintf("SyncAppointment->Check(): Parameter 'starttime' was not set, setting it to %d (%s).", $this->starttime, Utils::FormatDate($this->starttime)));
}
// Case 1, 4
if (!isset($this->endtime)) {
$this->endtime = $calcstart + 1800; // 30 min after calcstart
SLog::Write(LOGLEVEL_WBXML, sprintf("SyncAppointment->Check(): Parameter 'endtime' was not set, setting it to %d (%s).", $this->endtime, gmstrftime("%Y%m%dT%H%M%SZ", $this->endtime)));
SLog::Write(LOGLEVEL_WBXML, sprintf("SyncAppointment->Check(): Parameter 'endtime' was not set, setting it to %d (%s).", $this->endtime, Utils::FormatDate($this->endtime)));
}
}

Expand Down
37 changes: 36 additions & 1 deletion lib/utils/utils.php
Expand Up @@ -869,7 +869,7 @@ public static function SplitMessageId($id) {
*
* @return long
*/
public static function parseDate($ts) {
public static function ParseDate($ts) {
if (preg_match("/(\\d{4})[^0-9]*(\\d{2})[^0-9]*(\\d{2})(T(\\d{2})[^0-9]*(\\d{2})[^0-9]*(\\d{2})(.\\d+)?Z){0,1}$/", $ts, $matches)) {
if ($matches[1] >= 2038) {
$matches[1] = 2038;
Expand All @@ -894,6 +894,41 @@ public static function parseDate($ts) {
return 0;
}

/**
* Transforms an unix timestamp into an AS timestamp or a human readable format.
*
* Oh yeah, this is beautiful. Exchange outputs date fields differently in calendar items
* and emails. We could just always send one or the other, but unfortunately nokia's 'Mail for
* exchange' depends on this quirk. So we have to send a different date type depending on where
* it's used. Sigh.
*
* @param int $ts
* @param int $type int (StreamerType) (optional) if not set a human readable format is returned
*
* @return string
*/
public static function FormatDate($ts, $type = "") {
// fallback to a human readable format (used for logging)
$formatString = "yyyy-MM-dd HH:mm:SS' UTC'";
if ($type == Streamer::STREAMER_TYPE_DATE) {
$formatString = "yyyyMMdd'T'HHmmSS'Z'";
}
elseif ($type == Streamer::STREAMER_TYPE_DATE_DASHES) {
$formatString = "yyyy-MM-dd'T'HH:mm:SS'.000Z'";
}

$formatter = datefmt_create(
'en_US',
IntlDateFormatter::FULL,
IntlDateFormatter::FULL,
'UTC',
IntlDateFormatter::GREGORIAN,
$formatString
);

return datefmt_format($formatter, $ts);
}

/**
* Returns the appropriate SyncObjectResponse object based on message class.
*
Expand Down

0 comments on commit 2a3ca65

Please sign in to comment.