Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Intl recommendation + PHP81_BC\strftime + Symfony ICU Polyfill #69

Merged
merged 4 commits into from
Jun 5, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 4 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,6 @@

Unfortunately branch 2.x in original repository was taken down.

## Incoming breaking changes

The `strftime` function is widely used in the framework codebase. We plan to replace it with `IntlDateFormatter::format()`, this method comes from the `Intl` extension. CakePHP2 doesn't use it, so it would be a **breaking change**. We'd like to start rolling it out in early **May 2024**.

If you have any concerns, let's discuss it under: https://github.com/kamilwylegala/cakephp2-php8/issues/65

## Why I created this fork? 🤔

CakePHP 2 stopped getting updates in the end of 2019 (AFAIR). Unfortunately in my case it's too expensive to migrate to newer versions of CakePHP. I started migrating to Symfony framework, but I still use ORM from CakePHP (and actually I like it). So in order to keep up with the newest PHP versions I decided to create fork of the framework.
Expand Down Expand Up @@ -38,6 +32,10 @@ Here are steps I took to migrate my project through all versions to PHP 8.1, may
- ~~Due to lack of tests ☝️~~ - **you also need to rely** on tests in your application after integrating with this fork.
- If after integration you spot any issues related to framework please let me know by creating an issue or pull request with fix.

### Breaking changes

- In order to get rid of `strftime()` deprecation notices, it's required to switch to `IntlDateFormatter` class. This class is available in `intl` extension. Fork doesn't require it explicitly but to be able to use its functions Symfony ICU Polyfill is installed. To provide `strftime` behavior compatibility, `PHP81_BC\strftime` is used. `PHP81_BC` doesn't fully cover strftime, your code should work but there is a chance you'll get slightly different results. Discussed (here)[https://github.com/kamilwylegala/cakephp2-php8/pull/64] and (here)[https://github.com/kamilwylegala/cakephp2-php8/issues/65].

## Installation

This repository **is not** available in packagist, therefore your project's `composer.json` must be changed to point to custom repository.
Expand Down
8 changes: 6 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,15 @@
"source": "https://github.com/cakephp/cakephp"
},
"require": {
"php": "^8.0"
"php": "^8.0",
"ext-mbstring": "*",
"symfony/polyfill-intl-icu": "^1.29",
"php81_bc/strftime": "^0.7.5"
},
"suggest": {
"ext-openssl": "You need to install ext-openssl or ext-mcrypt to use AES-256 encryption",
"ext-mcrypt": "You need to install ext-openssl or ext-mcrypt to use AES-256 encryption"
"ext-mcrypt": "You need to install ext-openssl or ext-mcrypt to use AES-256 encryption",
"ext-intl": "Required to use IntlDateFormatter instead of strftime, if not Symfony polyfill will be used."
},
"require-dev": {
"phpunit/phpunit": "^9.5",
Expand Down
22 changes: 11 additions & 11 deletions lib/Cake/Test/Case/Utility/CakeTimeTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -279,9 +279,7 @@ public function testTimeAgoInWordsWithFormat() {
$this->assertEquals('on 2007-09-25', $result);

$result = $this->Time->timeAgoInWords('2007-9-25', '%x');
// @codingStandardsIgnoreStart
$this->assertEquals('on ' . @strftime('%x', strtotime('2007-9-25')), $result);
// @codingStandardsIgnoreEnd
$this->assertEquals('on ' . PHP81_BC\strftime('%x', strtotime('2007-9-25')), $result);

$result = $this->Time->timeAgoInWords(
strtotime('+2 weeks +2 days'),
Expand All @@ -306,7 +304,7 @@ public function testTimeAgoInWordsWithFormat() {
array('end' => '1 month', 'format' => '%x')
);
// @codingStandardsIgnoreStart
$this->assertEquals('on ' . @strftime('%x', strtotime('+2 months +2 days')), $result);
$this->assertEquals('on ' . PHP81_BC\strftime('%x', strtotime('+2 months +2 days')), $result);
// @codingStandardsIgnoreEnd
}

Expand Down Expand Up @@ -476,11 +474,11 @@ public function testNiceShort() {
* @return void
*/
public function testNiceShortI18n() {
$restore = setlocale(LC_ALL, 0);
setlocale(LC_ALL, 'es_ES');
$restore = Locale::getDefault();
Locale::setDefault('es_ES');
$time = strtotime('2015-01-07 03:05:00');
$this->assertEquals('ene 7th 2015, 03:05', $this->Time->niceShort($time));
setlocale(LC_ALL, $restore);
Locale::setDefault($restore);
}

/**
Expand Down Expand Up @@ -1166,20 +1164,22 @@ public function testConvertPercentE() {
* @return void
*/
public function testI18nFormat() {
$resetLocale = Locale::getDefault();
App::build(array(
'Locale' => array(CAKE . 'Test' . DS . 'test_app' . DS . 'Locale' . DS)
), App::RESET);
Configure::write('Config.language', 'time_test');

$time = strtotime('Thu Jan 14 13:59:28 2010');

Locale::setDefault('en_US');
$result = $this->Time->i18nFormat($time);
$expected = '14/01/10';
$this->assertEquals($expected, $result);

$result = $this->Time->i18nFormat($time, '%c');
// @codingStandardsIgnoreStart
$expected = 'jue 14 ene 2010 13:59:28 ' . mb_convert_encoding(@strftime('%Z', $time), 'UTF-8', 'ISO-8859-1');
$expected = 'jue 14 ene 2010 13:59:28 ' . mb_convert_encoding(PHP81_BC\strftime('%Z', $time), 'UTF-8', 'ISO-8859-1');
// @codingStandardsIgnoreEnd
$this->assertEquals($expected, $result);

Expand All @@ -1194,9 +1194,7 @@ public function testI18nFormat() {
$this->assertEquals($expected, $result);

$result = $this->Time->i18nFormat($time, '%c');
// @codingStandardsIgnoreStart
$expected = 'mié 13 ene 2010 13:59:28 ' . mb_convert_encoding(@strftime('%Z', $time), 'UTF-8', 'ISO-8859-1');
// @codingStandardsIgnoreEnd
$expected = 'mié 13 ene 2010 13:59:28 ' . mb_convert_encoding(PHP81_BC\strftime('%Z', $time), 'UTF-8', 'ISO-8859-1');
$this->assertEquals($expected, $result);

$result = $this->Time->i18nFormat($time, 'Time is %r, and date is %x');
Expand All @@ -1206,6 +1204,8 @@ public function testI18nFormat() {
$result = $this->Time->i18nFormat('invalid date', '%x', 'Date invalid');
$expected = 'Date invalid';
$this->assertEquals($expected, $result);

Locale::setDefault($resetLocale);
}

public function testI18nFormatTimezoneConversionToUTC() {
Expand Down
5 changes: 2 additions & 3 deletions lib/Cake/Utility/CakeTime.php
Original file line number Diff line number Diff line change
Expand Up @@ -1167,9 +1167,8 @@ public static function listTimezones($filter = null, $country = null, $options =
* @return string formatted string with correct encoding.
*/
protected static function _strftime($format, $timestamp) {
// @codingStandardsIgnoreStart
$format = @strftime($format, $timestamp);
// @codingStandardsIgnoreEnd
$format = PHP81_BC\strftime($format, $timestamp);

$encoding = Configure::read('App.encoding');
if (!empty($encoding) && $encoding === 'UTF-8') {
if (function_exists('mb_check_encoding')) {
Expand Down
6 changes: 2 additions & 4 deletions lib/Cake/View/Helper/FormHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -2767,9 +2767,7 @@ protected function _getDateTimeValue($value, $timeFormat) {
}

if (is_numeric($value)) {
// @codingStandardsIgnoreStart
$value = @strftime('%Y-%m-%d %H:%M:%S', $value);
// @codingStandardsIgnoreEnd
$value = PHP81_BC\strftime('%Y-%m-%d %H:%M:%S', $value);
}
$meridian = 'am';
$pos = strpos($value, '-');
Expand Down Expand Up @@ -3024,7 +3022,7 @@ protected function _generateOptions($name, $options = array()) {
} else {
for ($m = 1; $m <= 12; $m++) {
// @codingStandardsIgnoreStart
$data[sprintf("%02s", $m)] = @strftime("%m", mktime(1, 1, 1, $m, 1, 1999));
$data[sprintf("%02s", $m)] = PHP81_BC\strftime("%m", mktime(1, 1, 1, $m, 1, 1999));
// @codingStandardsIgnoreEnd
}
}
Expand Down
Loading