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

[1.x] Allow control over feature serialization #125

Merged
merged 2 commits into from
Nov 8, 2024
Merged

Conversation

timacdonald
Copy link
Member

@timacdonald timacdonald commented Nov 6, 2024

This PR adds a contract that objects may implement to control how they are serialized.

This is kinda already possible via the existing FeatureScopeable interface but is not really the intention of that contract.

The exciting FeatureScopeable interface allows you to return a value, which may be an object or a scalar, that represents the scope. This value is passed to the feature resolver.

Feature::define('foo', function (string $email) {
    return str_ends_with($email, '@laravel.com');
});

class Foo implements FeatureScopeable
{
    public function toFeatureIdentifier(string $driver): mixed
    {
        return $this->email;
    }
}

With the above in place we can now call Feature::active($user) and the feature resolver will receive the user's email address. The email address also ends up stored in the database.

But what if you want to be able to pass in the entire user object and still control how the object is serialized? This is where the new contract comes in.

Feature::define('foo', function (User $user) {
    return $user->isAdmin() || str_ends_with($user->email, '@laravel.com');
});

class Foo implements FeatureScopeSerializable
{
    public function featureScopeSerialize(): mixed
    {
        return $this->email;
    }
}

Now the feature resolver will receive the user object, not the email. However, the email will end up stored in the database.

One contract does not necessarily replace the other. I can imagine a set up where objects return a rich object from toFeatureIdentifier which then implements the FeatureScopeSerializable contract.

Naming

I matched PHP's JsonSerializable interface naming for this.

interface JsonSerializable => interfaceFeatureScopeSerializable
function jsonSerialize() => function featureScopeSerialize()

@timacdonald timacdonald marked this pull request as draft November 7, 2024 22:18
@timacdonald timacdonald marked this pull request as ready for review November 7, 2024 22:45
@taylorotwell taylorotwell merged commit cf9cbe2 into 1.x Nov 8, 2024
7 checks passed
@taylorotwell taylorotwell deleted the scope-serializer branch November 8, 2024 03:41
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