[12.x] Expressive cast configuration and standardization #57124
+1,392
−0
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
What?
This is basically a refactoring of the Eloquent Casts that allows to expressively configure a casts, and standardize features like encryption, caching and mapping (for iterable casts like Collections or even Fluent).
This PR solves some problems for the built-in casts:
AsFluent
,AsHtmlString
andAsUri
are not encryptable.map
orusing
on anAsArrayObject
, whileAsCollection
does.This is opt-in, meaning, there are no changes to the already included casts, but I believe the new way to declare casts should be preferred when possible when the developer requires the new features. Aka, this PR is non breaking.
How?
The way it works is by introducing an entry-point class called
To
, with static methods that return an object that configure the selected cast enabled by #56687.Note
As
is reserved by PHP and won't work, that's why I decanted to useTo
.The static methods are:
To::fluent()
AsFluent
To::htmlString()
AsHtmlString
To::stringable()
AsStringable
To::uri()
AsUri
To::arrayObject()
AsArrayObject
To::collection()
AsCollection
For example, we can now fluently configure an
ArrayObject
to use a custom Array Object class and items or even disable caching for a Fluent object.To achieve all this, the
To
class instances two objects depending on what is being casted:ToIterable
orToString
. Once these are set into the cast array, these will serialize into strings with the cast configuration.A minor adjustment had to be made for the
ArrayObject
. Due to theserialize()
method present in the original cast, theArrayObjectCast
had to be created. Aside from that, I believe this implementation is cleaner in the sense that one Cast handles iterable objects, while other does for stringable objects.Finally, if the developer is using a custom class with
using()
, the class check is deferred until the cast is used, like currently is done.Extensibility
The
ToIterable
can also be extended by developers since both mapping and final instantiation is done usingmapItems()
andmakeIterableObject()
, respectively.