Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

[VarExporter][DoctrineBundle] Accessing unknown properties on lazy ghost objects generates notices instead exceptions #48970

Copy link
Copy link
Closed
@kiler129

Description

@kiler129
Issue body actions

Symfony version(s) affected

6.2.4

Description

Initially this bug looked like an issue with EasyAdmin Bundle, as it is triggered by its code. The simplest way to do it is to add a field which doesn't exist on an entity, e.g.:

        yield TextField::new('type.thresholds_matches', 'Thresholds')
                       ->setVirtual(true)
                       ->setTemplatePath('admin/field/measurement_threshold.html.twig');

When enable_lazy_ghost_objects is disabled this works correctly and simply renders an empty field/custom template. However, the issue isn't actually in EAB but in LazyGhostTrait breaking the PropertyAccessorInterface promise:

* @throws Exception\InvalidArgumentException If the property path is invalid
* @throws Exception\AccessException If a property/index does not exist or is not public
* @throws Exception\UnexpectedTypeException If a value within the path is neither object
* nor array
*/
public function getValue(object|array $objectOrArray, string|PropertyPathInterface $propertyPath): mixed;

->getValue() should produce an exception when a given property doesn't exist, which EAB relies on: https://github.com/EasyCorp/EasyAdminBundle/blob/4db1860871809ca0be610ba5dab9be26ba165351/src/Field/Configurator/CommonPreConfigurator.php#L49-L53

How to reproduce

PoC reproducer, pick your own entity of course. In my case the type field is configured as:

    #[ORM\ManyToOne]
    #[ORM\JoinColumn(nullable: false)]
    private ?MeasurementType $type = null;

The test code I used:

<php declare(strict_types=1);

#[AsCommand(name: 'app:sandbox')]
class SandboxCommand extends Command
{
    public function __construct(private ManagerRegistry $doctrine, private PropertyAccessorInterface $propertyAccessor)
    {
        parent::__construct();
    }

    protected function execute(InputInterface $input, OutputInterface $output): int
    {
        $repo = $this->doctrine->getRepository(InanimateObjectMeasurement::class);
        $ent = $repo->findOneBy([]);

        dump($ent);
        dump($this->propertyAccessor->getValue($ent, 'value'));
        dump($this->propertyAccessor->getValue($ent, 'type.thresholds_matches'));
        
        return 0;
    }

With enable_lazy_ghost_objects=false:

 % bin/console app:sandbox -v
"183/88"

In PropertyAccessor.php line 453:
                                                                                                                               
  [Symfony\Component\PropertyAccess\Exception\NoSuchPropertyException]                                                         
  Can't get a way to read the property "thresholds_matches" in class "Proxies\__CG__\App\Entity\Measurement\MeasurementType". 

With enable_lazy_ghost_objects=true:

 % bin/console app:sandbox -v
"183/88"

In LazyGhostTrait.php line 191:
                                                                                                                                                                                                                                       
  [ErrorException]                                                                                                                                                                                                                     
  User Notice: Undefined property: Proxies\__CG__\App\Entity\Measurement\MeasurementType::$thresholds_matches in /app/vendor/symfony/property-access/PropertyAccessor.php on line 428  
                                                                                                                                                                                                                                       

Possible Solution

No response

Additional Context

No response

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

      Morty Proxy This is a proxified and sanitized view of the page, visit original site.