Issue #1944636 by alexpott, YesCT: Fixed PECL Intl extension usage in DateTimePlus class broken and untested.
parent
8498adcc20
commit
891f4c5d69
|
@ -637,9 +637,25 @@ class DateTimePlus extends \DateTime {
|
|||
|
||||
/**
|
||||
* Tests whether the IntlDateFormatter can be used.
|
||||
*
|
||||
* @param string $calendar
|
||||
* (optional) String calendar name to use for the date. Defaults to NULL.
|
||||
* @param string $langcode
|
||||
* (optional) String two letter language code to construct the locale string
|
||||
* by the intlDateFormatter class. Defaults to NULL.
|
||||
* @param string $country
|
||||
* (optional) String two letter country code to construct the locale string
|
||||
* by the intlDateFormatter class. Defaults to NULL.
|
||||
*
|
||||
* @return bool
|
||||
* TRUE if IntlDateFormatter can be used.
|
||||
*/
|
||||
public function canUseIntl() {
|
||||
return class_exists('IntlDateFormatter') && !empty($this->calendar) && !empty($this->langcode) && !empty($this->country);
|
||||
public function canUseIntl($calendar = NULL, $langcode = NULL, $country = NULL) {
|
||||
$langcode = !empty($langcode) ? $langcode : $this->langcode;
|
||||
$country = !empty($country) ? $country : $this->country;
|
||||
$calendar = !empty($calendar) ? $calendar : $this->calendar;
|
||||
|
||||
return class_exists('IntlDateFormatter') && !empty($calendar) && !empty($langcode) && !empty($country);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -691,14 +707,12 @@ class DateTimePlus extends \DateTime {
|
|||
$langcode = !empty($settings['langcode']) ? $settings['langcode'] : $this->langcode;
|
||||
$country = !empty($settings['country']) ? $settings['country'] : $this->country;
|
||||
$calendar = !empty($settings['calendar']) ? $settings['calendar'] : $this->calendar;
|
||||
$timezone = !empty($settings['timezone']) ? $settings['timezone'] : $this->getTimezone()->getName();
|
||||
$lenient = !empty($settings['lenient']) ? $settings['lenient'] : FALSE;
|
||||
|
||||
// Format the date and catch errors.
|
||||
try {
|
||||
|
||||
// If we have what we need to use the IntlDateFormatter, do so.
|
||||
if ($this->canUseIntl() && $format_string_type == static::INTL) {
|
||||
if ($this->canUseIntl($calendar, $langcode, $country) && $format_string_type == static::INTL) {
|
||||
|
||||
// Construct the $locale variable needed by the IntlDateFormatter.
|
||||
$locale = $langcode . '_' . $country;
|
||||
|
@ -716,9 +730,12 @@ class DateTimePlus extends \DateTime {
|
|||
|
||||
$date_type = !empty($settings['date_type']) ? $settings['date_type'] : \IntlDateFormatter::FULL;
|
||||
$time_type = !empty($settings['time_type']) ? $settings['time_type'] : \IntlDateFormatter::FULL;
|
||||
$formatter = new \IntlDateFormatter($locale, $date_type, $time_type, $timezone, $calendar_type);
|
||||
$timezone = !empty($settings['timezone']) ? $settings['timezone'] : $this->getTimezone()->getName();
|
||||
$formatter = new \IntlDateFormatter($locale, $date_type, $time_type, $timezone, $calendar_type, $format);
|
||||
|
||||
$lenient = !empty($settings['lenient']) ? $settings['lenient'] : FALSE;
|
||||
$formatter->setLenient($lenient);
|
||||
$value = $formatter->format($format);
|
||||
$value = $formatter->format($this);
|
||||
}
|
||||
|
||||
// Otherwise, use the parent method.
|
||||
|
|
|
@ -123,6 +123,7 @@ class DrupalDateTime extends DateTimePlus {
|
|||
|
||||
$format_string_type = isset($settings['format_string_type']) ? $settings['format_string_type'] : static::PHP;
|
||||
|
||||
$settings['calendar'] = !empty($settings['calendar']) ? $settings['calendar'] : $this->calendar;
|
||||
$settings['langcode'] = !empty($settings['langcode']) ? $settings['langcode'] : $this->langcode;
|
||||
$settings['country'] = !empty($settings['country']) ? $settings['country'] : $this->country;
|
||||
|
||||
|
@ -130,7 +131,7 @@ class DrupalDateTime extends DateTimePlus {
|
|||
try {
|
||||
|
||||
// If we have what we need to use the IntlDateFormatter, do so.
|
||||
if ($this->canUseIntl() && $format_string_type == parent::INTL) {
|
||||
if ($this->canUseIntl($settings['calendar'], $settings['langcode'], $settings['country']) && $format_string_type == parent::INTL) {
|
||||
$value = parent::format($format, $settings);
|
||||
}
|
||||
|
||||
|
|
|
@ -24,7 +24,7 @@ formats:
|
|||
name: 'HTML Datetime'
|
||||
pattern:
|
||||
php: 'Y-m-d\TH:i:sO'
|
||||
intl: "yyyy-MM-dd'Tkk:mm:ssZZ"
|
||||
intl: 'yyyy-MM-dd''T''kk:mm:ssZZ'
|
||||
locked: 1
|
||||
html_date:
|
||||
name: 'HTML Date'
|
||||
|
@ -48,7 +48,7 @@ formats:
|
|||
name: 'HTML Week'
|
||||
pattern:
|
||||
php: 'Y-\WW'
|
||||
intl: "Y-'WW"
|
||||
intl: 'Y-''W''WW'
|
||||
locked: 1
|
||||
html_month:
|
||||
name: 'HTML Month'
|
||||
|
|
|
@ -0,0 +1,87 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Contains \Drupal\system\Tests\Datetime\DateTimePlusIntlTest.
|
||||
*/
|
||||
|
||||
namespace Drupal\system\Tests\Datetime;
|
||||
|
||||
use Drupal\Component\Datetime\DateTimePlus;
|
||||
use Drupal\simpletest\DrupalUnitTestBase;
|
||||
|
||||
/**
|
||||
* Tests use of PHP's internationalization extension to format dates.
|
||||
*/
|
||||
class DateTimePlusIntlTest extends DrupalUnitTestBase {
|
||||
|
||||
/**
|
||||
* Modules to enable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public static $modules = array('system');
|
||||
|
||||
public static function getInfo() {
|
||||
return array(
|
||||
'name' => 'DateTimePlusIntl',
|
||||
'description' => 'Test DateTimePlus PECL Intl functionality.',
|
||||
'group' => 'Datetime',
|
||||
);
|
||||
}
|
||||
|
||||
public function setUp() {
|
||||
parent::setUp();
|
||||
// Install default config for system.
|
||||
$this->installConfig(array('system'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensures that PHP's Intl extension is installed.
|
||||
*
|
||||
* @return array
|
||||
* Array of errors containing a list of unmet requirements.
|
||||
*/
|
||||
function checkRequirements() {
|
||||
if (!class_exists('IntlDateFormatter')) {
|
||||
return array(
|
||||
'PHP\'s Intl extension needs to be installed and enabled.',
|
||||
);
|
||||
}
|
||||
return parent::checkRequirements();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that PHP and Intl default formats are equivalent.
|
||||
*/
|
||||
function testDateTimestampIntl() {
|
||||
|
||||
// Create date object from a unix timestamp and display it in local time.
|
||||
$input = '2007-01-31 21:00:00';
|
||||
$timezone = 'UTC';
|
||||
$intl_settings = array(
|
||||
'format_string_type' => DateTimePlus::INTL,
|
||||
'country' => 'US',
|
||||
'langcode' => 'en',
|
||||
);
|
||||
$php_settings = array(
|
||||
'country' => NULL,
|
||||
'langcode' => 'en',
|
||||
);
|
||||
|
||||
$intl_date = new DateTimePlus($input, $timezone, NULL, $intl_settings);
|
||||
$php_date = new DateTimePlus($input, $timezone, NULL, $php_settings);
|
||||
|
||||
$this->assertTrue($intl_date->canUseIntl(), 'DateTimePlus object can use intl when provided with country and langcode settings.');
|
||||
$this->assertFalse($php_date->canUseIntl(), 'DateTimePlus object will fallback to use PHP when not provided with country setting.');
|
||||
|
||||
$default_formats = config('system.date')->get('formats');
|
||||
|
||||
foreach ($default_formats as $format) {
|
||||
$php_format = $php_date->format($format['pattern']['php'], $php_settings);
|
||||
$intl_format = $intl_date->format($format['pattern']['intl'], $intl_settings);
|
||||
$this->assertIdentical($intl_format, $php_format);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue