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

Add PHP 8.1 compatibility #678

Closed
wants to merge 4 commits into from
Closed

Add PHP 8.1 compatibility #678

wants to merge 4 commits into from

Conversation

atomiix
Copy link
Contributor

@atomiix atomiix commented Oct 7, 2021

The goal of this PR is to make smarty compatible with PHP 8.1.

The main issue was the use of the function strftime() which is deprecated in PHP 8.1. This problem is solve by the use of IntlDateFormatter after being sure that the intl extension is loaded.

Other deprecations have been removed too.

@wisskid
Copy link
Contributor

wisskid commented Oct 13, 2021

Hi @atomiix this looks great! However, I've been working on feature/php8-support to support PHP8.0 already.
In this branch, I switched from travis to gitlab-ci, added PHPUnit 8.5. I already rewrote all the expectException stuff too.

Could you rebase your PR on this branch (or wait until it is in master)?

Reviewing your PR, I see a couple of changes that do not seem to be explained by support for PHP8.1. E.g. the strtlower in libs/sysplugins/smarty_internal_method_loadplugin.php:87. Could you clarify those?

Thanks for your work!

@atomiix
Copy link
Contributor Author

atomiix commented Oct 20, 2021

hey @wisskid, I rebased my PR, it should be good now!

I also edited my description to explain why I added the strtolower in libs/sysplugins/smarty_internal_method_loadplugin.php

@atomiix
Copy link
Contributor Author

atomiix commented Nov 23, 2021

@wisskid just a friendly reminder as PHP 8.1 due date is in 2 days 🙃

@Progi1984
Copy link
Contributor

Good news. PHP 8.1 is available ;)

Copy link
Contributor

@wisskid wisskid left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great PR by the way, 2 comments made

libs/sysplugins/smarty_internal_method_loadplugin.php Outdated Show resolved Hide resolved

$formatter = null;
$format_compare = '%m';
if (class_exists('IntlDateFormatter')) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since IntlDateFormatter isn't included by default and the strftime deprecation notice is only a notice, wouldn't it be better to keep it as it was? We're adding complexity here, only fixing the deprecation notices on certain environments. I'm hoping PHP9 will include a way to handle this smoothly that is included by default?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately, I don't think that PHP 9.0 will handle it smoothly, from https://wiki.php.net/rfc/deprecations_php_8_1:

The strftime() and gmstrftime() functions exhibit similar issues as strptime(), in that the formats they support, as well as their behavior, is platform-dependent. Unlike strptime(), these functions are available on Windows, though with a different feature set than on Linux. Musl-based distributions like Alpine do not support timezone-related format specifiers correctly. These functions are also locale-based, and as such may exhibit thread-safety issues.

Once again date() or DateTime::format() provide portable alternatives, and IntlDateFormatter::format() provides a more sophisticated, localization-aware alternative.

The proposal is to deprecate strftime() and gmstrftime() in favor of these alternatives.

So I guess this is the way we'll have to do it in PHP 9.0 and in the meantime, we can have strftime as a fallback. WDYT?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let me put it in another way: your change will still fail in PHP9, because strftime will be deleted by then (unless they reverse the decision). So what is the point of making the change in the first place?
Also: I know strftime is used a LOT in PHP libs, so the deprecation will trigger the need for a suitable alternative to be included in PHP9 by default. If that turns out to be IntlDateFormatter, we'll switch then.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree with @atomiix , having strftime as fallback is a good idea. I'm not in favor of having deprecation notices only because it's acceptable. When you're working you don't want to be spamed by useless messages you can avoid.
Adding IntlDateFormatter as alternative is a good idea, but the real check should be if (extension_loaded('intl')) { for a better understanding.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I also think avoiding any strftime would be beneficial. The intl extension is quite common nowadays, and Symfony has a polyfill (symfony/polyfill-intl-icu) which is an easy alternative if the intl extension is missing and provides a way of avoiding deprecation notices even without the extension.

@pineapps
Copy link

pineapps commented Dec 7, 2021

So are we going to merge this branch or.....?

@PierreRambaud
Copy link

So are we going to merge this branch or.....?

Maybe, maybe not, that's a hard question 🤔
Let the maintainer take time to estimate if the change is legit and can be accepted or not 😺

@j-applese3d
Copy link
Contributor

I noticed that modifier.date_format also uses strftime.
Would it make sense to also update that plugin at the same time?

@PierreRambaud
Copy link

I noticed that modifier.date_format also uses strftime. Would it make sense to also update that plugin at the same time?

I think yes, but the whole part needs to be refactored:

if ($formatter === 'strftime' || ($formatter === 'auto' && strpos($format, '%') !== false)) {

@atomiix
Copy link
Contributor Author

atomiix commented Dec 22, 2021

@j-applese3d you're right! I just added a new modifier date_format_intl. I guess that's a good compromise to avoid a BC break and still allow us to use IntlDateFormatter when needed.

@PierreRambaud
Copy link

@j-applese3d you're right! I just added a new modifier date_format_intl. I guess that's a good compromise to avoid a BC break and still allow us to use IntlDateFormatter when needed.

Not sure it's the right solution as the date_format will still be used.
Maybe you can do the same condition inside the current implementation as you did before, like "Is Intl available, yes, let's use it". And use it by default.

@atomiix
Copy link
Contributor Author

atomiix commented Dec 22, 2021

Maybe you can do the same condition inside the current implementation as you did before, like "Is Intl available, yes, let's use it". And use it by default.

The issue is that IntlDateFormatter cannot be 100% compatible with strftime. You can see in this gist that it's not 100% correct.

IMHO, for date_format, as you can fully customize the format, it's better to have a dedicated method

@wisskid
Copy link
Contributor

wisskid commented Dec 22, 2021

I like the idea of combining IntlDateFormatter with symfony/polyfill-intl-icu and replace all the strftime in the entire codebase.

@atomiix
Copy link
Contributor Author

atomiix commented Dec 22, 2021

@wisskid We'll have to keep in mind that symfony/polyfill-intl-icu is limited to english though. That being said, that's ok for me. Also, that means BC breaks as strftime format string is different than IntlDateFormatter's ones and not completely convertisable.

@iwiznia
Copy link

iwiznia commented Dec 30, 2021

I am working on a migration of a project to PHP 8.1 and can confirm that this PR solves all the problems I've been seeing.

@genyslt
Copy link

genyslt commented Jan 5, 2022

Any news?

@wisskid
Copy link
Contributor

wisskid commented Jan 10, 2022

I'm thinking we should separate the fixes for the fatal error on PHP8.1(#671) from the removal of deprecation notices strftime. The former is much more pressing now.

@genyslt
Copy link

genyslt commented Jan 13, 2022

Can you tell us estimated time, when you can fix it? Is there a lot of problems to run Smarty on php8.1?

@thirsch
Copy link
Contributor

thirsch commented Jan 17, 2022

Looks like there is not much missing to get 8.1 support. Is there anything we can do to speed up the merge/release? Maybe creating another PR with all changes except the strftime-issue?

@wisskid
Copy link
Contributor

wisskid commented Jan 17, 2022

Maybe creating another PR with all changes except the strftime-issue?

Yes that would be super. I'd merge that.

@thirsch thirsch mentioned this pull request Jan 18, 2022
@thirsch
Copy link
Contributor

thirsch commented Jan 18, 2022

Maybe creating another PR with all changes except the strftime-issue?

Yes that would be super. I'd merge that.

Okay, I've created another pr for only the non-intldate related stuff: #713

@scortellino
Copy link

There are 3 PR on PHP 8.1...Do we expect a merge soon like in coming days?

@wisskid
Copy link
Contributor

wisskid commented Jan 21, 2022

Closing this one in favor of #713
We'll handle the strftime issue later

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
waiting Waiting for answer
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet