Media: improve the `human_readable_duration` function and tests.

Improve the `human_readable_duration` added in #39667:
* Remove upper limit.
* More resilient handling: remove negative prefix, trim.
* Correct @since to 5.1.0.
* Adds more test cases and improve inline docs.

Props birgire.
Fixes #39667.


git-svn-id: https://develop.svn.wordpress.org/trunk@44481 602fd350-edb4-49c9-b593-d223f7449a82
This commit is contained in:
Adam Silverstein 2019-01-08 19:55:31 +00:00
parent 559056f62f
commit f968e9d52f
2 changed files with 98 additions and 45 deletions

View File

@ -323,54 +323,68 @@ function size_format( $bytes, $decimals = 0 ) {
}
/**
* Convert a filelength to human readable format.
* Convert a duration to human readable format.
*
* @since 5.0
* @since 5.1.0
*
* @param string $filelength Duration will be in string format (HH:ii:ss) OR (ii:ss).
* @return boolean|string A human readable filelength string, false on failure.
* @param string $duration Duration will be in string format (HH:ii:ss) OR (ii:ss),
* with a possible prepended negative sign (-).
* @return string|false A human readable duration string, false on failure.
*/
function human_readable_duration( $filelength = '' ) {
// Return false if filelength is empty or not in format.
if ( ( empty( $filelength ) || ! is_string( $filelength ) ) ) {
function human_readable_duration( $duration = '' ) {
if ( ( empty( $duration ) || ! is_string( $duration ) ) ) {
return false;
}
// Validate filelength format.
if ( ! ( (bool) preg_match( '/^(([0-3]?[0-9])|([2][0-3])):([0-5]?[0-9])(:([0-5]?[0-9]))?$/', $filelength ) ) ) {
$duration = trim( $duration );
// Remove prepended negative sign.
if ( '-' === substr( $duration, 0, 1 ) ) {
$duration = substr( $duration, 1 );
}
// Extract duration parts.
$duration_parts = array_reverse( explode( ':', $duration ) );
$duration_count = count( $duration_parts );
$hour = null;
$minute = null;
$second = null;
if ( 3 === $duration_count ) {
// Validate HH:ii:ss duration format.
if ( ! ( (bool) preg_match( '/^([0-9]+):([0-5]?[0-9]):([0-5]?[0-9])$/', $duration ) ) ) {
return false;
}
// Three parts: hours, minutes & seconds.
list( $second, $minute, $hour ) = $duration_parts;
} elseif ( 2 === $duration_count ) {
// Validate ii:ss duration format.
if ( ! ( (bool) preg_match( '/^([0-5]?[0-9]):([0-5]?[0-9])$/', $duration ) ) ) {
return false;
}
// Two parts: minutes & seconds.
list( $second, $minute ) = $duration_parts;
} else {
return false;
}
$human_readable_duration = array();
// Extract duration.
$durations = array_reverse( explode( ':', $filelength ) );
$duration_count = count( $durations );
if ( 3 === $duration_count ) {
// Three parts: hours, minutes & seconds.
list( $second, $minute, $hour ) = $durations;
} elseif ( 2 === $duration_count ) {
// Two parts: minutes & seconds.
list( $second, $minute ) = $durations;
} else {
return false;
}
// Add the hour part to the string.
if ( ! empty( $hour ) && is_numeric( $hour ) ) {
if ( is_numeric( $hour ) ) {
/* translators: Time duration in hour or hours. */
$human_readable_duration[] = sprintf( _n( '%s hour', '%s hours', $hour ), (int) $hour );
}
// Add the minute part to the string.
if ( ! empty( $minute ) && is_numeric( $minute ) ) {
if ( is_numeric( $minute ) ) {
/* translators: Time duration in minute or minutes. */
$human_readable_duration[] = sprintf( _n( '%s minute', '%s minutes', $minute ), (int) $minute );
}
// Add the second part to the string.
if ( ! empty( $second ) && is_numeric( $second ) ) {
if ( is_numeric( $second ) ) {
/* translators: Time duration in second or seconds. */
$human_readable_duration[] = sprintf( _n( '%s second', '%s seconds', $second ), (int) $second );
}

View File

@ -1579,22 +1579,60 @@ class Tests_Functions extends WP_UnitTestCase {
}
/**
* Test the human_readable_duration function.
* Test human_readable_duration().
*
* @ticket 39667
* @dataProvider _datahuman_readable_duration()
* @dataProvider data_test_human_readable_duration
*
* @param $input
* @param $expected
* @param string $input Duration.
* @param string $expected Expected human readable duration.
*/
public function test_duration_format( $input, $expected ) {
public function test_human_readable_duration( $input, $expected ) {
$this->assertSame( $expected, human_readable_duration( $input ) );
}
public function _datahuman_readable_duration() {
/**
* Dataprovider for test_duration_format().
*
* @return array {
* @type array {
* @type string $input Duration.
* @type string $expect Expected human readable duration.
* }
* }
*/
public function data_test_human_readable_duration() {
return array(
array( array(), false ),
// Valid ii:ss cases.
array( '0:0', '0 minutes, 0 seconds' ),
array( '00:00', '0 minutes, 0 seconds' ),
array( '0:5', '0 minutes, 5 seconds' ),
array( '0:05', '0 minutes, 5 seconds' ),
array( '01:01', '1 minute, 1 second' ),
array( '30:00', '30 minutes, 0 seconds' ),
array( ' 30:00 ', '30 minutes, 0 seconds' ),
// Valid HH:ii:ss cases.
array( '0:0:0', '0 hours, 0 minutes, 0 seconds' ),
array( '00:00:00', '0 hours, 0 minutes, 0 seconds' ),
array( '00:30:34', '0 hours, 30 minutes, 34 seconds' ),
array( '01:01:01', '1 hour, 1 minute, 1 second' ),
array( '1:02:00', '1 hour, 2 minutes, 0 seconds' ),
array( '10:30:34', '10 hours, 30 minutes, 34 seconds' ),
array( '1234567890:59:59', '1234567890 hours, 59 minutes, 59 seconds' ),
// Valid ii:ss cases with negative sign.
array( '-00:00', '0 minutes, 0 seconds' ),
array( '-3:00', '3 minutes, 0 seconds' ),
array( '-03:00', '3 minutes, 0 seconds' ),
array( '-30:00', '30 minutes, 0 seconds' ),
// Valid HH:ii:ss cases with negative sign.
array( '-00:00:00', '0 hours, 0 minutes, 0 seconds' ),
array( '-1:02:00', '1 hour, 2 minutes, 0 seconds' ),
// Invalid cases.
array( null, false ),
array( '', false ),
array( ':', false ),
array( '::', false ),
array( array(), false ),
array( 'Batman Begins !', false ),
array( '', false ),
array( '-1', false ),
@ -1602,18 +1640,19 @@ class Tests_Functions extends WP_UnitTestCase {
array( 0, false ),
array( 1, false ),
array( '00', false ),
array( '00:00', '0 minutes, 0 seconds' ),
array( '00:00:00', '0 hours, 0 minutes, 0 seconds' ),
array( '10:30:34', '10 hours, 30 minutes, 34 seconds' ),
array( '00:30:34', '0 hours, 30 minutes, 34 seconds' ),
array( 'MM:30:00', false ),
array( '30:MM', false ),
array( 'MM:00', false ),
array( 'MM:MM', false ),
array( '01:01', '1 minute, 1 second' ),
array( '01:01:01', '1 hour, 1 minute, 1 second' ),
array( '0:05', '5 seconds' ),
array( '1:02:00', '1 hour, 2 minutes, 0 seconds' ),
array( '30:-10', false ),
array( ':30:00', false ), // Missing HH.
array( 'MM:30:00', false ), // Invalid HH.
array( '30:MM:00', false ), // Invalid ii.
array( '30:30:MM', false ), // Invalid ss.
array( '30:MM', false ), // Invalid ss.
array( 'MM:00', false ), // Invalid ii.
array( 'MM:MM', false ), // Invalid ii and ss.
array( '10 :30', false ), // Containing a space.
array( '59:61', false ), // Out of bound.
array( '61:59', false ), // Out of bound.
array( '3:59:61', false ), // Out of bound.
array( '03:61:59', false ), // Out of bound.
);
}
}