From f4ce2f1a4048f6a88db260495cd0880f41c133b2 Mon Sep 17 00:00:00 2001 From: Joseph Bielawski Date: Fri, 4 Jan 2013 09:48:20 +0100 Subject: [PATCH 1/5] Update .travis.yml Add PHP 5.5 to Travis-CI testing and allow it to fail. --- .travis.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.travis.yml b/.travis.yml index bb120a4e50..326e0c79b7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,5 +4,10 @@ php: - 5.3.3 - 5.3 - 5.4 + - 5.5 + +matrix: + allow_failures: + - php: 5.5 before_script: php vendors.php From 8ae773b4864c7fdd2902c657e8598d9350ca4e6f Mon Sep 17 00:00:00 2001 From: Joseph Bielawski Date: Thu, 20 Dec 2012 22:10:24 +0100 Subject: [PATCH 2/5] [Form] Fix failing `MonthChoiceList` in PHP 5.5 --- .../Extension/Core/ChoiceList/MonthChoiceList.php | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/Symfony/Component/Form/Extension/Core/ChoiceList/MonthChoiceList.php b/src/Symfony/Component/Form/Extension/Core/ChoiceList/MonthChoiceList.php index 0d2e10e840..477cb6e4e1 100644 --- a/src/Symfony/Component/Form/Extension/Core/ChoiceList/MonthChoiceList.php +++ b/src/Symfony/Component/Form/Extension/Core/ChoiceList/MonthChoiceList.php @@ -39,7 +39,11 @@ class MonthChoiceList extends PaddedChoiceList $pattern = $this->formatter->getPattern(); $timezone = $this->formatter->getTimezoneId(); - $this->formatter->setTimezoneId('UTC'); + if (version_compare(phpversion(), '5.5.0alpha1', '<')) { + $this->formatter->setTimezoneId('UTC'); + } else { + $this->formatter->setTimezone('UTC'); + } if (preg_match('/M+/', $pattern, $matches)) { $this->formatter->setPattern($matches[0]); @@ -53,6 +57,10 @@ class MonthChoiceList extends PaddedChoiceList $this->formatter->setPattern($pattern); } - $this->formatter->setTimezoneId($timezone); + if (version_compare(phpversion(), '5.5.0alpha1', '<')) { + $this->formatter->setTimezoneId($timezone); + } else { + $this->formatter->setTimezone($timezone); + } } } From 913b564da1364f33be6967694b87d66aabf5beb4 Mon Sep 17 00:00:00 2001 From: Joseph Bielawski Date: Fri, 4 Jan 2013 13:44:28 +0100 Subject: [PATCH 3/5] [Locale] Fix failing `StubIntlDateFormatter` in PHP 5.5 --- .../Locale/Stub/StubIntlDateFormatter.php | 31 ++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/src/Symfony/Component/Locale/Stub/StubIntlDateFormatter.php b/src/Symfony/Component/Locale/Stub/StubIntlDateFormatter.php index 877c40c5fd..38fe8ae98a 100644 --- a/src/Symfony/Component/Locale/Stub/StubIntlDateFormatter.php +++ b/src/Symfony/Component/Locale/Stub/StubIntlDateFormatter.php @@ -188,6 +188,9 @@ class StubIntlDateFormatter $argumentError = 'datefmt_format: takes either an array or an integer timestamp value '; } elseif (version_compare(\PHP_VERSION, '5.3.4', '>=') && !is_int($timestamp) && !$timestamp instanceof \DateTime) { $argumentError = 'datefmt_format: takes either an array or an integer timestamp value or a DateTime object'; + if (version_compare(\PHP_VERSION, '5.5.0alpha1', '>=') && !is_int($timestamp)) { + $argumentError = sprintf('datefmt_format: string \'%s\' is not numeric, which would be required for it to be a valid date', $timestamp); + } } if (null !== $argumentError) { @@ -313,9 +316,30 @@ class StubIntlDateFormatter return $this->timeZoneId; } + // In PHP 5.5 default timezone depends on `date_default_timezone_get()` method + if (version_compare(\PHP_VERSION, '5.5.0alpha1', '>=')) { + return date_default_timezone_get(); + } + return null; } + /** + * Returns the formatter's timezone + * + * @return \DateTimeZone The timezone identifier used by the formatter + * + * @see http://www.php.net/manual/en/intldateformatter.gettimezone.php + */ + public function getTimeZone() + { + if (!$this->unitializedTimeZoneId) { + return new \DateTimeZone($this->timeZoneId); + } + + return new \DateTimeZone(date_default_timezone_get()); + } + /** * Returns whether the formatter is lenient * @@ -490,13 +514,18 @@ class StubIntlDateFormatter return true; } + public function setTimeZone($timeZoneId) + { + return $this->setTimeZoneId($timeZoneId); + } + /** * Create and returns a DateTime object with the specified timestamp and with the * current time zone * * @param int $timestamp * - * @return DateTime + * @return \DateTime */ protected function createDateTime($timestamp) { From b2ce9835967801e40e8a3a1f38b58fc08c76be18 Mon Sep 17 00:00:00 2001 From: Joseph Bielawski Date: Fri, 4 Jan 2013 13:44:59 +0100 Subject: [PATCH 4/5] [Locale] Fix failing `StubIntlDateFormatter` tests in PHP 5.5 --- .../Locale/Stub/StubIntlDateFormatterTest.php | 205 +++++++++++++++--- 1 file changed, 174 insertions(+), 31 deletions(-) diff --git a/tests/Symfony/Tests/Component/Locale/Stub/StubIntlDateFormatterTest.php b/tests/Symfony/Tests/Component/Locale/Stub/StubIntlDateFormatterTest.php index c99120998d..ea6062546c 100644 --- a/tests/Symfony/Tests/Component/Locale/Stub/StubIntlDateFormatterTest.php +++ b/tests/Symfony/Tests/Component/Locale/Stub/StubIntlDateFormatterTest.php @@ -43,14 +43,26 @@ class StubIntlDateFormatterTest extends LocaleTestCase public function testConstructorDefaultTimeZoneStub() { $formatter = new StubIntlDateFormatter('en', StubIntlDateFormatter::MEDIUM, StubIntlDateFormatter::SHORT); - $this->assertNull($formatter->getTimeZoneId()); + + // In PHP 5.5 default timezone depends on `date_default_timezone_get()` method + if ($this->isGreaterOrEqualThanPhpVersion('5.5.0alpha1')) { + $this->assertEquals(date_default_timezone_get(), $formatter->getTimeZoneId()); + } else { + $this->assertNull($formatter->getTimeZoneId()); + } } public function testConstructorDefaultTimeZoneIntl() { $this->skipIfIntlExtensionIsNotLoaded(); $formatter = new \IntlDateFormatter('en', StubIntlDateFormatter::MEDIUM, StubIntlDateFormatter::SHORT); - $this->assertNull($formatter->getTimeZoneId()); + + // In PHP 5.5 default timezone depends on `date_default_timezone_get()` method + if ($this->isGreaterOrEqualThanPhpVersion('5.5.0alpha1')) { + $this->assertEquals(date_default_timezone_get(), $formatter->getTimeZoneId()); + } else { + $this->assertNull($formatter->getTimeZoneId()); + } } public function testFormatWithUnsupportedTimestampArgument() @@ -356,6 +368,13 @@ class StubIntlDateFormatterTest extends LocaleTestCase public function formatErrorProvider() { + // With PHP 5.5 IntlDateFormatter accepts empty values ('0') + if ($this->isGreaterOrEqualThanPhpVersion('5.5.0alpha1')) { + return array( + array('y-M-d', 'foobar', 'datefmt_format: string \'foobar\' is not numeric, which would be required for it to be a valid date: U_ILLEGAL_ARGUMENT_ERROR') + ); + } + $message = 'datefmt_format: takes either an array or an integer timestamp value : U_ILLEGAL_ARGUMENT_ERROR'; if ($this->isGreaterOrEqualThanPhpVersion('5.3.4')) { @@ -391,7 +410,7 @@ class StubIntlDateFormatterTest extends LocaleTestCase public function formatWithTimezoneProvider() { - return array( + $data = array( array(0, 'UTC', '1970-01-01 00:00:00'), array(0, 'GMT', '1970-01-01 00:00:00'), array(0, 'GMT-03:00', '1969-12-31 21:00:00'), @@ -415,12 +434,17 @@ class StubIntlDateFormatterTest extends LocaleTestCase array(0, 'Europe/Dublin', '1970-01-01 01:00:00'), array(0, 'Europe/Warsaw', '1970-01-01 01:00:00'), array(0, 'Pacific/Fiji', '1970-01-01 12:00:00'), - - // When time zone not exists, uses UTC by default - array(0, 'Foo/Bar', '1970-01-01 00:00:00'), - array(0, 'UTC+04:30', '1970-01-01 00:00:00'), - array(0, 'UTC+04:AA', '1970-01-01 00:00:00'), ); + + // As of PHP 5.5, intl ext no longer fallbacks invalid time zones to UTC + if (!$this->isGreaterOrEqualThanPhpVersion('5.5.0alpha1')) { + // When time zone not exists, uses UTC by default + $data[] = array(0, 'Foo/Bar', '1970-01-01 00:00:00'); + $data[] = array(0, 'UTC+04:30', '1970-01-01 00:00:00'); + $data[] = array(0, 'UTC+04:AA', '1970-01-01 00:00:00'); + } + + return $data; } /** @@ -429,7 +453,13 @@ class StubIntlDateFormatterTest extends LocaleTestCase public function testFormatWithTimezoneFormatOptionAndDifferentThanUtcStub() { $formatter = $this->createStubFormatter('zzzz'); - $formatter->setTimeZoneId('Pacific/Fiji'); + + if ($this->isGreaterOrEqualThanPhpVersion('5.5.0alpha1')) { + $formatter->setTimeZone('Pacific/Fiji'); + } else { + $formatter->setTimeZoneId('Pacific/Fiji'); + } + $formatter->format(0); } @@ -437,7 +467,12 @@ class StubIntlDateFormatterTest extends LocaleTestCase { $this->skipIfIntlExtensionIsNotLoaded(); $formatter = $this->createIntlFormatter('zzzz'); - $formatter->setTimeZoneId('Pacific/Fiji'); + + if ($this->isGreaterOrEqualThanPhpVersion('5.5.0alpha1')) { + $formatter->setTimeZone('Pacific/Fiji'); + } else { + $formatter->setTimeZoneId('Pacific/Fiji'); + } $expected = $this->isGreaterOrEqualThanIcuVersion('49') ? 'Fiji Standard Time' : 'Fiji Time'; $this->assertEquals($expected, $formatter->format(0)); @@ -446,7 +481,13 @@ class StubIntlDateFormatterTest extends LocaleTestCase public function testFormatWithGmtTimezoneStub() { $formatter = $this->createStubFormatter('zzzz'); - $formatter->setTimeZoneId('GMT+03:00'); + + if ($this->isGreaterOrEqualThanPhpVersion('5.5.0alpha1')) { + $formatter->setTimeZone('GMT+03:00'); + } else { + $formatter->setTimeZoneId('GMT+03:00'); + } + $this->assertEquals('GMT+03:00', $formatter->format(0)); } @@ -454,7 +495,13 @@ class StubIntlDateFormatterTest extends LocaleTestCase { $this->skipIfIntlExtensionIsNotLoaded(); $formatter = $this->createIntlFormatter('zzzz'); - $formatter->setTimeZoneId('GMT+03:00'); + + if ($this->isGreaterOrEqualThanPhpVersion('5.5.0alpha1')) { + $formatter->setTimeZone('GMT+03:00'); + } else { + $formatter->setTimeZoneId('GMT+03:00'); + } + $this->assertEquals('GMT+03:00', $formatter->format(0)); } @@ -485,6 +532,10 @@ class StubIntlDateFormatterTest extends LocaleTestCase public function testFormatWithDefaultTimezoneStubShouldUseTheTzEnvironmentVariableWhenAvailable() { + if ($this->isGreaterOrEqualThanPhpVersion('5.5.0alpha1')) { + $this->markTestSkipped('StubIntlDateFormatter in PHP 5.5 no longer depends on TZ environment.'); + } + $tz = getenv('TZ'); putenv('TZ=Europe/London'); @@ -502,6 +553,29 @@ class StubIntlDateFormatterTest extends LocaleTestCase putenv('TZ='.$tz); } + public function testFormatWithDefaultTimezoneStubShouldUseDefaultDateTimeZoneVariable() + { + if (!$this->isGreaterOrEqualThanPhpVersion('5.5.0alpha1')) { + $this->markTestSkipped('Only in PHP 5.5 StubIntlDateFormatter depends on default timezone (`date_default_timezone_get()`).'); + } + + $tz = date_default_timezone_get(); + date_default_timezone_set('Europe/London'); + + $formatter = new \IntlDateFormatter('en', StubIntlDateFormatter::MEDIUM, StubIntlDateFormatter::SHORT); + $formatter->setPattern('yyyy-MM-dd HH:mm:ss'); + + $this->assertEquals( + $this->createDateTime(0)->format('Y-m-d H:i:s'), + $formatter->format(0) + ); + + $this->assertEquals('Europe/London', date_default_timezone_get()); + + // Restores TZ. + date_default_timezone_set($tz); + } + /** * It seems IntlDateFormatter caches the timezone id when not explicitly set via constructor or by the * setTimeZoneId() method. Since testFormatWithDefaultTimezoneIntl() runs using the default environment @@ -511,6 +585,10 @@ class StubIntlDateFormatterTest extends LocaleTestCase */ public function testFormatWithDefaultTimezoneIntlShouldUseTheTzEnvironmentVariableWhenAvailable() { + if ($this->isGreaterOrEqualThanPhpVersion('5.5.0alpha1')) { + $this->markTestSkipped('IntlDateFormatter in PHP 5.5 no longer depends on TZ environment.'); + } + $this->skipIfIntlExtensionIsNotLoaded(); $this->skipIfICUVersionIsTooOld(); @@ -531,6 +609,35 @@ class StubIntlDateFormatterTest extends LocaleTestCase putenv('TZ='.$tz); } + /** + * @runInSeparateProcess + */ + public function testFormatWithDefaultTimezoneIntlShouldUseDefaultDateTimeZoneVariable() + { + if (!$this->isGreaterOrEqualThanPhpVersion('5.5.0alpha1')) { + $this->markTestSkipped('Only in PHP 5.5 IntlDateFormatter depends on default timezone (`date_default_timezone_get()`).'); + } + + $this->skipIfIntlExtensionIsNotLoaded(); + $this->skipIfICUVersionIsTooOld(); + + $tz = date_default_timezone_get(); + date_default_timezone_set('Europe/Paris'); + + $formatter = new \IntlDateFormatter('en', StubIntlDateFormatter::MEDIUM, StubIntlDateFormatter::SHORT); + $formatter->setPattern('yyyy-MM-dd HH:mm:ss'); + + $this->assertEquals('Europe/Paris', date_default_timezone_get()); + + $this->assertEquals( + $this->createDateTime(0)->format('Y-m-d H:i:s'), + $formatter->format(0) + ); + + // Restores TZ. + date_default_timezone_set($tz); + } + /** * @expectedException Symfony\Component\Locale\Exception\NotImplementedException */ @@ -994,38 +1101,59 @@ class StubIntlDateFormatterTest extends LocaleTestCase * @covers Symfony\Component\Locale\Stub\StubIntlDateFormatter::getTimeZoneId * @dataProvider setTimeZoneIdProvider() */ - public function testSetTimeZoneIdStub($timeZoneId) + public function testSetTimeZoneIdStub($timeZoneId, $expectedTimeZoneId) { $formatter = $this->createStubFormatter(); - $formatter->setTimeZoneId($timeZoneId); + + if ($this->isGreaterOrEqualThanPhpVersion('5.5.0alpha1')) { + $formatter->setTimeZone($timeZoneId); + } else { + $formatter->setTimeZoneId($timeZoneId); + } + $this->assertEquals($timeZoneId, $formatter->getTimeZoneId()); } /** * @dataProvider setTimeZoneIdProvider() */ - public function testSetTimeZoneIdIntl($timeZoneId) + public function testSetTimeZoneIdIntl($timeZoneId, $expectedTimeZoneId) { $this->skipIfIntlExtensionIsNotLoaded(); $formatter = $this->createIntlFormatter(); - $formatter->setTimeZoneId($timeZoneId); - $this->assertEquals($timeZoneId, $formatter->getTimeZoneId()); + + if ($this->isGreaterOrEqualThanPhpVersion('5.5.0alpha1')) { + $formatter->setTimeZone($timeZoneId); + } else { + $formatter->setTimeZoneId($timeZoneId); + } + + $this->assertEquals($expectedTimeZoneId, $formatter->getTimeZoneId()); } public function setTimeZoneIdProvider() { - return array( - array('UTC'), - array('GMT'), - array('GMT-03:00'), - array('GMT-0300'), - array('Europe/Zurich'), - - // When time zone not exists, uses UTC by default - array('Foo/Bar'), - array('GMT+00:AA'), - array('GMT+00AA'), + $data = array( + array('UTC', 'UTC'), + array('GMT', 'GMT'), + array('GMT-03:00', 'GMT-03:00'), + array('Europe/Zurich', 'Europe/Zurich'), ); + + // When time zone not exists, uses UTC by default + if ($this->isGreaterOrEqualThanPhpVersion('5.5.0alpha1')) { + $data[] = array('GMT-0300', 'UTC'); + $data[] = array('Foo/Bar', 'UTC'); + $data[] = array('GMT+00:AA', 'UTC'); + $data[] = array('GMT+00AA', 'UTC'); + } else { + $data[] = array('GMT-0300', 'GMT-0300'); + $data[] = array('Foo/Bar', 'Foo/Bar'); + $data[] = array('GMT+00:AA', 'GMT+00:AA'); + $data[] = array('GMT+00AA', 'GMT+00AA'); + } + + return $data; } /** @@ -1034,14 +1162,25 @@ class StubIntlDateFormatterTest extends LocaleTestCase public function testSetTimeZoneIdWithGmtTimeZoneWithMinutesOffsetStub() { $formatter = $this->createStubFormatter(); - $formatter->setTimeZoneId('GMT+00:30'); + + if ($this->isGreaterOrEqualThanPhpVersion('5.5.0alpha1')) { + $formatter->setTimeZone('GMT+00:30'); + } else { + $formatter->setTimeZoneId('GMT+00:30'); + } } public function testSetTimeZoneIdWithGmtTimeZoneWithMinutesOffsetIntl() { $this->skipIfIntlExtensionIsNotLoaded(); $formatter = $this->createIntlFormatter(); - $formatter->setTimeZoneId('GMT+00:30'); + + if ($this->isGreaterOrEqualThanPhpVersion('5.5.0alpha1')) { + $formatter->setTimeZone('GMT+00:30'); + } else { + $formatter->setTimeZoneId('GMT+00:30'); + } + $this->assertEquals('GMT+00:30', $formatter->getTimeZoneId()); } @@ -1063,7 +1202,11 @@ class StubIntlDateFormatterTest extends LocaleTestCase protected function createDateTime($timestamp = null) { - $timeZone = getenv('TZ') ?: 'UTC'; + if ($this->isGreaterOrEqualThanPhpVersion('5.5.0alpha1')) { + $timeZone = date_default_timezone_get(); + } else { + $timeZone = getenv('TZ') ?: 'UTC'; + } $dateTime = new \DateTime(); $dateTime->setTimestamp(null === $timestamp ? time() : $timestamp); From 73d9cef188511a2dee17a99630f2fc62cb3eded8 Mon Sep 17 00:00:00 2001 From: Joseph Bielawski Date: Fri, 4 Jan 2013 15:29:23 +0100 Subject: [PATCH 5/5] [Locale] Adjust `StubIntlDateFormatter` to have new methods added in PHP 5.5 --- .../Locale/Stub/StubIntlDateFormatter.php | 70 +++++++++++++++---- 1 file changed, 57 insertions(+), 13 deletions(-) diff --git a/src/Symfony/Component/Locale/Stub/StubIntlDateFormatter.php b/src/Symfony/Component/Locale/Stub/StubIntlDateFormatter.php index 38fe8ae98a..d64044710f 100644 --- a/src/Symfony/Component/Locale/Stub/StubIntlDateFormatter.php +++ b/src/Symfony/Component/Locale/Stub/StubIntlDateFormatter.php @@ -217,6 +217,24 @@ class StubIntlDateFormatter return $formatted; } + /** + * Formats an object + * + * @param object $object + * @param mixed $format + * @param string $locale + * + * @return string The formatted value + * + * @see http://www.php.net/manual/en/intldateformatter.formatobject.php + * + * @throws MethodNotImplementedException + */ + public function formatObject($object, $format = null, $locale = null) + { + throw new MethodNotImplementedException(__METHOD__); + } + /** * Returns the formatter's calendar * @@ -229,6 +247,20 @@ class StubIntlDateFormatter return self::GREGORIAN; } + /** + * Returns the formatter's calendar object + * + * @return object The calendar's object being used by the formatter + * + * @see http://www.php.net/manual/en/intldateformatter.getcalendarobject.php + * + * @throws MethodNotImplementedException + */ + public function getCalendarObject() + { + throw new MethodNotImplementedException(__METHOD__); + } + /** * Returns the formatter's datetype * @@ -327,17 +359,15 @@ class StubIntlDateFormatter /** * Returns the formatter's timezone * - * @return \DateTimeZone The timezone identifier used by the formatter + * @return mixed The timezone used by the formatter * * @see http://www.php.net/manual/en/intldateformatter.gettimezone.php + * + * @throws MethodNotImplementedException */ public function getTimeZone() { - if (!$this->unitializedTimeZoneId) { - return new \DateTimeZone($this->timeZoneId); - } - - return new \DateTimeZone(date_default_timezone_get()); + throw new MethodNotImplementedException(__METHOD__); } /** @@ -482,11 +512,16 @@ class StubIntlDateFormatter public function setTimeZoneId($timeZoneId) { if (null === $timeZoneId) { - // TODO: changes were made to ext/intl in PHP 5.4.4 release that need to be investigated since it will - // use ini's date.timezone when the time zone is not provided. As a not well tested workaround, uses UTC. - // See the first two items of the commit message for more information: - // https://github.com/php/php-src/commit/eb346ef0f419b90739aadfb6cc7b7436c5b521d9 - $timeZoneId = getenv('TZ') ?: 'UTC'; + // In PHP 5.5 if $timeZoneId is null it fallbacks to `date_default_timezone_get()` method + if (version_compare(\PHP_VERSION, '5.5.0alpha1', '>=')) { + $timeZoneId = date_default_timezone_get(); + } else { + // TODO: changes were made to ext/intl in PHP 5.4.4 release that need to be investigated since it will + // use ini's date.timezone when the time zone is not provided. As a not well tested workaround, uses UTC. + // See the first two items of the commit message for more information: + // https://github.com/php/php-src/commit/eb346ef0f419b90739aadfb6cc7b7436c5b521d9 + $timeZoneId = getenv('TZ') ?: 'UTC'; + } $this->unitializedTimeZoneId = true; } @@ -514,9 +549,18 @@ class StubIntlDateFormatter return true; } - public function setTimeZone($timeZoneId) + /** + * This method was added in PHP 5.5 as replacement for `setTimeZoneId()` + * + * @param mixed $timeZone + * + * @return Boolean true on success or false on failure + * + * @see http://www.php.net/manual/en/intldateformatter.settimezone.php + */ + public function setTimeZone($timeZone) { - return $this->setTimeZoneId($timeZoneId); + return $this->setTimeZoneId($timeZone); } /**