Issue #1944636 by alexpott, YesCT: Fixed PECL Intl extension usage in DateTimePlus class broken and untested.

8.0.x
Nathaniel Catchpole 2013-05-03 14:21:32 +01:00
parent 8498adcc20
commit 891f4c5d69
4 changed files with 115 additions and 10 deletions

View File

@ -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.

View File

@ -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);
}

View File

@ -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'

View File

@ -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);
}
}
}