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

Feature/support scaled percentages #54049

Conversation

muscle-hamster
Copy link

Summary

This change aligns the return value of the percentage method in the Illuminate/Support/Number class with the behavior of the underlying PHP NumberFormatter class. The NumberFormatter class expects a decimal input and returns a scaled value by a factor of 100 (e.g., 0.75 becomes 75%).

While returning the original, unscaled input localized and formatted is useful, it's also important to provide the scaled and formatted percentage as it is commonly expected in most applications.

Benefits to End Users

  • Localization: Users will benefit from properly localized and formatted percentages that are consistent with common practices, including the handling of decimals and percentage symbols.
  • Backward Compatibility: This change does not break existing functionality. The default behavior remains the same, and developers can choose to opt into the scaled version via an optional parameter.
  • Enhanced Flexibility: This update allows developers to format percentages in both the unscaled and scaled formats without changing their current workflows, making it easier to implement localized percentage formatting where necessary.

Why It Doesn't Break Existing Features

  • Backward Compatibility: The introduction of a scaled parameter (defaulting to false) ensures that existing implementations of the percentage method remain unaffected. The method will continue returning the percentage as before unless the scaled parameter is explicitly set to true.
  • Opt-in Behavior: The ability to opt into the scaled, localized format gives developers control over how percentages are presented, without altering the default behavior that many existing projects rely on.

How It Makes Building Web Applications Easier

  • Simplified Localization: Web applications that need to display percentages in various languages and formats (e.g., 75% in English or 75% in French) can now easily take advantage of the built-in localization capabilities of the NumberFormatter class.
  • Reduced Complexity: Developers no longer need to manually scale or format percentage values, reducing boilerplate code and making the development process faster and less error-prone.
  • Consistency: By aligning with the NumberFormatter's behavior, this change ensures consistent handling of percentages across applications, aligning with established practices in web and software development.

This change more closely aligns the return value of the percentage
method in the `Illuminate/Support/Numbers` class with the return value
of the underlying PHP NumberFormatter class. The NumberFormatter class
expects a decimal and returns a scaled value by a factor of 100. While I
think it is potentially useful to get back the original input localized
and formatted, I also think it is useful to get back the scaled and
formatted version of the input as well.

The changes made here were to help maintain backward compatibility with
the current implementation of the percentage method.
Copy link
Contributor

@shaedrich shaedrich left a comment

Choose a reason for hiding this comment

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

I agree that this is not a breaking change, however, due to its implementation already diverging from the one of the underlying NumberFormatter class, this doesn't actually bring the implementations (much|any) closer together, due to the introduction of a new workaround parameter that doesn't exist on said base class. The original implementation is unfortunate and this is probably the only way to fix this without introducing breaking changes, if we actually want to change the behavior at this point still.

Comment on lines +133 to 137
if ($scaled) {
return $formatter->format($number);
}

return $formatter->format($number / 100);
Copy link
Contributor

@shaedrich shaedrich Dec 31, 2024

Choose a reason for hiding this comment

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

We could do the following instead, in case, we want to do something with the formatted output or the like in the future:

Suggested change
if ($scaled) {
return $formatter->format($number);
}
return $formatter->format($number / 100);
if (! $scaled) {
$number /= 1000;
}
return $formatter->format($number);

Copy link
Author

Choose a reason for hiding this comment

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

This was close to my original implementation but breaks backward compatibility. I do like this much better though. Should I refactor and point to the master branch instead of 11.x?

@muscle-hamster
Copy link
Author

I agree this implementation is not ideal but as you mentioned this is the cleanest way I could think of without making braking changes.

I still think this is worth fixing and valuable to the framework. Would you prefer if I made breaking changes and got them in with the next major release?

@shaedrich
Copy link
Contributor

Would you prefer if I made breaking changes and got them in with the next major release?

In the end, this would be Taylor's choice to make

@taylorotwell
Copy link
Member

Thanks for your pull request to Laravel!

Unfortunately, I'm going to delay merging this code for now. To preserve our ability to adequately maintain the framework, we need to be very careful regarding the amount of code we include.

If applicable, please consider releasing your code as a package so that the community can still take advantage of your contributions!

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

Successfully merging this pull request may close these issues.

3 participants