Skip to content

Allowing non-nullable properties for AccessInterceptorScopeLocalizer #683

Open
@petr-buchin

Description

@petr-buchin

This is a follow up on #682.

After doing some research, I realized that enabling AccessInterceptorScopeLocalizer to work with non-nullable properties is pretty straightforward.

For now checking for non-accessible properties looks like follows in class Properties:

return new self(array_filter($this->properties, static function (ReflectionProperty $property): bool {
    if (! $property->hasType()) {
        return false;
    }

    return ! array_key_exists(
        $property->getName(),
        // https://bugs.php.net/bug.php?id=77673
        array_flip(array_keys($property->getDeclaringClass()->getDefaultProperties()))
    );
}));

To fix this behavior and allow non-nullable properties on objects being proxied, this code can be changed to something like follows:

return new self(array_filter($this->properties, static function (ReflectionProperty $property) use($realObject): bool {
    if (! $property->hasType()) {
        return false;
    }
    
    if ($property->getType()->allowsNull() && $property->getType()->hasDefaultValue()) {
        return false;
    }

    return ! $property->isInitialized($realObject);
}));

This code allows to proxy objects with non-nullable properties and moves responsibility of initializing properties to the user of this library.

However, the problem is that classes Properties and BindProxyProperties does not have access to the object being proxied, thus cannot use method ReflectionProperty::isInitialized().

It's possible to pass the instance of an object being proxied to this classes, but that would require changing signatures of some interface methods, and that would be a BC break.

I was thinking about using a temporary workaround (before next major release), such as ProxyContext class with static property, like ProxyContext::$objectBeingProxied, that would allow classes like BindProxyProperties to have access to the object being proxied without changing interfaces, but that is admittedly clunky.

@Ocramius do you have any thoughts on this?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions