Skip to content

Commit

Permalink
New API functions for date conversions
Browse files Browse the repository at this point in the history
As requested in PR review, it is no longer possible to provide timestamp
(version date order) as an integer to REST API /projects/{{id}}/versions
endpoints.

It is worth noting that a Unix timestamp can technically still be given,
using the `@{integer}` syntax, since that is a valid format for the
DateTimeImmutable constructor. This could change in the future, if we
decide to only allow ISO-8601 format.

The datetime parsing and generation logic has been standardized in 2 new
date API functions:
- date_string_to_timestamp()
- date_timestamp_to_iso8601()

Use the new functions in:
- date_strtotime()
- ApiObjectFactory: methods datetime() and datetimeString();
  add new dateStringToTimestamp() method.
- VersionAddCommand
- VersionUpdateCommand

Fixes #34928
  • Loading branch information
dregad committed Feb 26, 2025
1 parent 0296679 commit 6f1e91b
Show file tree
Hide file tree
Showing 5 changed files with 85 additions and 37 deletions.
37 changes: 25 additions & 12 deletions api/soap/mc_api.php
Original file line number Diff line number Diff line change
Expand Up @@ -208,11 +208,13 @@ static function objectToArray( $p_object, $p_recursive = false ) {
}

/**
* Convert a timestamp to a soap DateTime variable
* @param integer $p_value Integer value to return as date time string.
* @return datetime in expected API format.
* Convert a timestamp to a soap DateTime variable or ISO-8601 date.
*
* @param int $p_value Unix Timestamp.
*
* @return SoapVar|string datetime in expected API format.
*/
static function datetime($p_value ) {
static function datetime( $p_value ) {
$t_string_value = self::datetimeString( $p_value );

if( ApiObjectFactory::$soap ) {
Expand All @@ -223,16 +225,27 @@ static function datetime($p_value ) {
}

/**
* Convert a timestamp to a DateTime string
* @param integer $p_timestamp Integer value to format as date time string.
* @return string for provided timestamp
* Convert a timestamp to an ISO-8601 formatted DateTime string.
*
* @param int|null $p_timestamp Unix timestamp.
*
* @return string|null Formatted datetime.
*/
static function datetimeString($p_timestamp ) {
if( $p_timestamp == null || date_is_null( $p_timestamp ) ) {
return null;
}
static function datetimeString( $p_timestamp ) {
return date_timestamp_to_iso8601( $p_timestamp );
}

return date( 'c', (int)$p_timestamp );
/**
* Converts a datetime string to a Unix timestamp.
*
* @param string $p_date_string Date string.
*
* @return int|null Unix timestamp, null when $p_date_string is blank.
*
* @throws ClientException When given string cannot be converted to Date.
*/
static function dateStringToTimestamp( $p_date_string ): ?int {
return date_string_to_timestamp( $p_date_string );
}

/**
Expand Down
6 changes: 2 additions & 4 deletions core/commands/VersionAddCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -80,10 +80,8 @@ function validate() {
array( 'name' ) );
}

$t_timestamp = $this->payload( 'timestamp', '' );
$this->timestamp = is_blank( $t_timestamp )
? null
: ( is_int( $t_timestamp ) ? $t_timestamp : strtotime( $t_timestamp ) );
$t_date_string = $this->payload( 'timestamp', '' );
$this->timestamp = date_string_to_timestamp( $t_date_string );
}

/**
Expand Down
9 changes: 3 additions & 6 deletions core/commands/VersionUpdateCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -153,12 +153,9 @@ protected function process() {
$t_version->obsolete = $t_obsolete;
}

$t_timestamp = $this->payload( 'timestamp' );
if( !is_blank( $t_timestamp ) ) {
if( !is_int( $t_timestamp ) ) {
$t_timestamp = strtotime( $t_timestamp );
}
$t_version->date_order = $t_timestamp;
$t_date_string = $this->payload( 'timestamp' );
if( !is_blank( $t_date_string ) ) {
$t_version->date_order = date_string_to_timestamp( $t_date_string );
}

version_update( $t_version );
Expand Down
67 changes: 53 additions & 14 deletions core/date_api.php
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,54 @@ function date_get_null() {
return 1;
}


/**
* Converts a datetime string to a Unix timestamp.
*
* @param string $p_date_string Date string.
*
* @return int|null Unix timestamp, null when $p_date_string is blank.
*
* @throws ClientException When given string cannot be converted to Date.
*/
function date_string_to_timestamp( string $p_date_string ): ?int {
if( is_blank( $p_date_string ) ) {
return null;
}

# @TODO if we ever decide to require strict ISO-8601 date formatting in the
# future, this should be enforced here.

try {
$t_dt = new DateTimeImmutable( $p_date_string );
}
catch( Exception $e ) {
throw new ClientException(
"Invalid date format '$p_date_string'",
ERROR_INVALID_DATE_FORMAT,
array( $p_date_string ),
$e
);
}
return $t_dt->getTimestamp();
}

/**
* Converts a timestamp to an ISO-8601 formatted date.
*
* @param int|null $p_timestamp Unix Timestamp.
*
* @return string|null ISO-8601 formatted date.
*/
function date_timestamp_to_iso8601( ?int $p_timestamp ): ?string {
if( $p_timestamp == null || date_is_null( $p_timestamp ) ) {
return null;
}

return date( 'c', (int)$p_timestamp );
}


/**
* Gets Unix timestamp from a date string.
*
Expand All @@ -87,21 +135,12 @@ function date_strtotime( $p_date_string ) {

$t_format = config_get( 'normal_date_format' );
$t_dt = DateTimeImmutable::createFromFormat( $t_format, $p_date_string );
if( $t_dt === false ) {
# date is not in expected format, try with default formats
try {
$t_dt = new DateTimeImmutable( $p_date_string );
}
catch( Exception $e ) {
throw new ClientException(
"Invalid date format '$p_date_string'",
ERROR_INVALID_DATE_FORMAT,
array( $p_date_string ),
$e
);
}
if( $t_dt !== false ) {
return $t_dt->getTimestamp();
}
return $t_dt->getTimestamp();

# date is not in expected format, try with default formats
return date_string_to_timestamp( $p_date_string );
}

/**
Expand Down
3 changes: 2 additions & 1 deletion manage_proj_ver_update.php
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@

$f_new_version = trim( $f_new_version );
$t_version = version_get( $f_version_id );
$t_timestamp = date_strtotime( $f_date_order );

$t_data = array(
'query' => array(
Expand All @@ -63,7 +64,7 @@
'description' => $f_description,
'released' => $f_released,
'obsolete' => $f_obsolete,
'timestamp' => date_strtotime( $f_date_order )
'timestamp' => date_timestamp_to_iso8601( $t_timestamp ),
)
);

Expand Down

0 comments on commit 6f1e91b

Please sign in to comment.