-
-
Notifications
You must be signed in to change notification settings - Fork 9.7k
Closed
Description
Symfony version(s) affected
5.4.34
Description
enable_lazy_ghost_objects is set to true
have a Class with Complex Structure and Collections
use Doctrine\Common\Collections\Collection;
interface PageInterface
{
/**
* @return Collection<array-key, PageInterface>
*/
public function getChildren(): Collection;
/**
* @return Collection<array-key, BlockInterface>
*/
public function getBlocks(): Collection;
}
use Doctrine\Common\Collections\Collection;
interface BlockInterface
{
/**
* @return Collection<int, BlockInterface>
*/
public function getChildren(): Collection;
}
How to reproduce
doctrine:
dbal:
url: '%env(resolve:DATABASE_URL)%'
# IMPORTANT: You MUST configure your server version,
# either here or in the DATABASE_URL env var (see .env file)
#server_version: '13'
orm:
auto_generate_proxy_classes: true
enable_lazy_ghost_objects: true
have entity classes that implement this interfaces:
use Doctrine\Common\Collections\Collection;
interface PageInterface
{
/**
* @return Collection<array-key, PageInterface>
*/
public function getChildren(): Collection;
/**
* @return Collection<array-key, BlockInterface>
*/
public function getBlocks(): Collection;
}
use Doctrine\Common\Collections\Collection;
interface BlockInterface
{
/**
* @return Collection<int, BlockInterface>
*/
public function getChildren(): Collection;
}
now use Symfony Normalizer to try to normalize the Page object when the Collections aren't fully loaded yet
This ErrorException happened:
ErrorException:
User Notice: Undefined property: Proxies\__CG__\App\Entity\SonataPageBlock::$lazyObjectState in D:\*****\******\******\sonata\private\vendor\symfony\property-access\PropertyAccessor.php on line 488
at D:\*****\******\******\sonata\private\vendor\symfony\var-exporter\LazyGhostTrait.php:193
at Proxies\__CG__\App\Entity\SonataPageBlock->__get('lazyObjectState')
(D:\*****\******\******\sonata\private\vendor\symfony\property-access\PropertyAccessor.php:488)
at Symfony\Component\PropertyAccess\PropertyAccessor->readProperty(array(object(SonataPageBlock)), 'lazyObjectState', false)
(D:\*****\******\******\sonata\private\vendor\symfony\property-access\PropertyAccessor.php:154)
at Symfony\Component\PropertyAccess\PropertyAccessor->getValue(object(SonataPageBlock), 'lazyObjectState')
(D:\*****\******\******\sonata\private\vendor\symfony\serializer\Normalizer\ObjectNormalizer.php:136)
at Symfony\Component\Serializer\Normalizer\ObjectNormalizer->getAttributeValue(object(SonataPageBlock), 'lazyObjectState', null, array('datetime_format' => 'U', 'skip_null_values' => true, 'callbacks' => array('blocks' => object(Closure), 'parent' => object(Closure)), 'cache_key' => false, 'circular_reference_limit_counters' => array('00000000000005400000000000000000' => 1, '00000000000008a70000000000000000' => 1)))
(D:\*****\******\******\sonata\private\vendor\symfony\serializer\Normalizer\AbstractObjectNormalizer.php:190)
at Symfony\Component\Serializer\Normalizer\AbstractObjectNormalizer->normalize(object(SonataPageBlock), null, array('datetime_format' => 'U', 'skip_null_values' => true, 'callbacks' => array('blocks' => object(Closure), 'parent' => object(Closure)), 'cache_key' => false, 'circular_reference_limit_counters' => array('00000000000005400000000000000000' => 1, '00000000000008a70000000000000000' => 1)))
(D:\*****\******\******\sonata\private\vendor\symfony\serializer\Serializer.php:161)
at Symfony\Component\Serializer\Serializer->normalize(object(SonataPageBlock), null, array('datetime_format' => 'U', 'skip_null_values' => true, 'callbacks' => array('blocks' => object(Closure), 'parent' => object(Closure)), 'cache_key' => false, 'circular_reference_limit_counters' => array('00000000000005400000000000000000' => 1)))
(D:\*****\******\******\sonata\private\vendor\symfony\serializer\Serializer.php:179)
at Symfony\Component\Serializer\Serializer->normalize(array(object(SonataPageBlock), object(SonataPageBlock), object(SonataPageBlock), object(SonataPageBlock), object(SonataPageBlock), object(SonataPageBlock), object(SonataPageBlock), object(SonataPageBlock), object(SonataPageBlock), object(SonataPageBlock)), null, array('datetime_format' => 'U', 'skip_null_values' => true, 'callbacks' => array('blocks' => object(Closure), 'parent' => object(Closure)), 'cache_key' => false, 'circular_reference_limit_counters' => array('00000000000005400000000000000000' => 1)))
(D:\*****\******\******\sonata\private\vendor\symfony\serializer\Normalizer\AbstractObjectNormalizer.php:224)
at Symfony\Component\Serializer\Normalizer\AbstractObjectNormalizer->normalize(object(SonataPagePage), null, array('datetime_format' => 'U', 'skip_null_values' => true, 'callbacks' => array('blocks' => object(Closure), 'parent' => object(Closure)), 'cache_key' => false, 'circular_reference_limit_counters' => array('00000000000005400000000000000000' => 1)))
(D:\*****\******\******\sonata\private\vendor\symfony\serializer\Serializer.php:161)
at Symfony\Component\Serializer\Serializer->normalize(object(SonataPagePage), null, array('datetime_format' => 'U', 'skip_null_values' => true, 'callbacks' => array('blocks' => object(Closure), 'parent' => object(Closure))))
Possible Solution
calling Collection->getValues()
might not be enough, the 'blocks' Closure already does it
AbstractNormalizer::CALLBACKS => [
'blocks' => static fn (Collection $collection, PageInterface $object, string $attribute, ?string $format = null, array $context = []) => $collection->filter(static fn (BlockInterface $block) => !$block->hasParent())->getValues(),
]
Additional Context
Related Sonata Issue:
sonata-project/SonataPageBundle#1747