8000 [PropertyInfo] Extractors `getProperties()` always returns array even if nothing found · Issue #25803 · symfony/symfony · GitHub
[go: up one dir, main page]

Skip to content
[PropertyInfo] Extractors getProperties() always returns array even if nothing found #25803
Closed
@natepage

Description

@natepage
Q A
Bug report? yes
Feature request? no
BC Break report? no
RFC? no
Symfony version 4.0.3

Currently implementing an API using Api Platform component, I'm having an issue during the "denormalization" process. The ApiPlatform component uses Serializer to populate the entities based on the request. The Serializer uses PropertyInfo to retrieve the list of allowed properties on the entity but it is not able to do it in my case.

My entities don't have public properties or hard coded accessors/mutators, they are using the magic __call method to handle the process:

/**
 * @ApiResource()
 * @ORM\Entity(repositoryClass="App\Repositories\MerchantRepository")
 *
 * @method string getEmail()
 * @method self setEmail(string $email)
 */
class Merchant
{
     /**
     * @ORM\Id
     * @ORM\GeneratedValue
     * @ORM\Column(type="integer")
     */
    protected $id;

    /**
     * @var string
     *
     * @Assert\NotBlank()
     * @Assert\Email()
     * @ORM\Column(type="string", length=255)
     */
    protected $email;

    /**
     * Magic method to get/set information on this instance
     */
    public function __call(string $method, array $parameters)
    {
        // ...
    }
}

Because of this specificity the ReflectionExtractor isn't able to retrieve my properties because it tries to find them using reflection and only on public properties/methods. So I expect to get them from DoctrineExtractor, the problem is that the ReflectionExtractor::getProperties() method always return an array even if it is empty which as for result to skip the rest of extractors.

Symfony\Component\PropertyInfo\PropertyInfoExtractor:

    /**
     * Iterates over registered extractors and return the first value found.
     *
     * @return mixed
     */
    private function extract(iterable $extractors, string $method, array $arguments)
    {
        foreach ($extractors as $extractor) {
            $value = call_user_func_array(array($extractor, $method), $arguments);
            if (null !== $value) {
                return $value;
            }
        }
    }

The if statement is testing for different than null so when an empty array is returned it is valid then it stops iterating over the extractors even if nothing has been really found.

To fix this issue the ReflectionExtractor::getProperties() should return null when no properties have been found.

Symfony\Component\PropertyInfo\Extractor\ReflectionExtractor:

   /**
     * {@inheritdoc}
     */
    public function getProperties($class, array $context = array())
    {
        // ...
       
       return !empty($properties) ? array_values($properties) : null;
    }

Actually all PropertyListExtractorInterface::getProperties() implementation should return null when no properties have been found to allow another extractor to process the class.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions

      0