[Doctrine][PropertyInfo] Detect if the ID is writeable

This commit is contained in:
Kévin Dunglas 2019-05-12 22:36:09 +02:00
parent 6c5faef5cb
commit 4598235192
No known key found for this signature in database
GPG Key ID: 4D04EBEF06AAF3A6
3 changed files with 87 additions and 13 deletions

View File

@ -15,8 +15,10 @@ use Doctrine\Common\Persistence\Mapping\ClassMetadataFactory;
use Doctrine\Common\Persistence\Mapping\MappingException;
use Doctrine\DBAL\Types\Type as DBALType;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\Mapping\ClassMetadata;
use Doctrine\ORM\Mapping\ClassMetadataInfo;
use Doctrine\ORM\Mapping\MappingException as OrmMappingException;
use Symfony\Component\PropertyInfo\PropertyAccessExtractorInterface;
use Symfony\Component\PropertyInfo\PropertyListExtractorInterface;
use Symfony\Component\PropertyInfo\PropertyTypeExtractorInterface;
use Symfony\Component\PropertyInfo\Type;
@ -26,7 +28,7 @@ use Symfony\Component\PropertyInfo\Type;
*
* @author Kévin Dunglas <dunglas@gmail.com>
*/
class DoctrineExtractor implements PropertyListExtractorInterface, PropertyTypeExtractorInterface
class DoctrineExtractor implements PropertyListExtractorInterface, PropertyTypeExtractorInterface, PropertyAccessExtractorInterface
{
private $entityManager;
private $classMetadataFactory;
@ -51,12 +53,8 @@ class DoctrineExtractor implements PropertyListExtractorInterface, PropertyTypeE
*/
public function getProperties($class, array $context = [])
{
try {
$metadata = $this->entityManager ? $this->entityManager->getClassMetadata($class) : $this->classMetadataFactory->getMetadataFor($class);
} catch (MappingException $exception) {
return;
} catch (OrmMappingException $exception) {
return;
if (null === $metadata = $this->getMetadata($class)) {
return null;
}
$properties = array_merge($metadata->getFieldNames(), $metadata->getAssociationNames());
@ -77,12 +75,8 @@ class DoctrineExtractor implements PropertyListExtractorInterface, PropertyTypeE
*/
public function getTypes($class, $property, array $context = [])
{
try {
$metadata = $this->entityManager ? $this->entityManager->getClassMetadata($class) : $this->classMetadataFactory->getMetadataFor($class);
} catch (MappingException $exception) {
return;
} catch (OrmMappingException $exception) {
return;
if (null === $metadata = $this->getMetadata($class)) {
return null;
}
if ($metadata->hasAssociation($property)) {
@ -176,6 +170,39 @@ class DoctrineExtractor implements PropertyListExtractorInterface, PropertyTypeE
}
}
/**
* {@inheritdoc}
*/
public function isReadable($class, $property, array $context = [])
{
return null;
}
/**
* {@inheritdoc}
*/
public function isWritable($class, $property, array $context = [])
{
if (
null === ($metadata = $this->getMetadata($class))
|| ClassMetadata::GENERATOR_TYPE_NONE === $metadata->generatorType
|| !\in_array($property, $metadata->getIdentifierFieldNames(), true)
) {
return null;
}
return false;
}
private function getMetadata(string $class): ?ClassMetadata
{
try {
return $this->entityManager ? $this->entityManager->getClassMetadata($class) : $this->classMetadataFactory->getMetadataFor($class);
} catch (MappingException | OrmMappingException $exception) {
return null;
}
}
/**
* Determines whether an association is nullable.
*

View File

@ -16,6 +16,7 @@ use Doctrine\ORM\EntityManager;
use Doctrine\ORM\Tools\Setup;
use PHPUnit\Framework\TestCase;
use Symfony\Bridge\Doctrine\PropertyInfo\DoctrineExtractor;
use Symfony\Bridge\Doctrine\Tests\PropertyInfo\Fixtures\DoctrineGeneratedValue;
use Symfony\Component\PropertyInfo\Type;
/**
@ -223,4 +224,13 @@ class DoctrineExtractorTest extends TestCase
{
$this->assertNull($this->createExtractor($legacy)->getTypes('Not\Exist', 'baz'));
}
public function testGeneratedValueNotWritable()
{
$extractor = $this->createExtractor();
$this->assertFalse($extractor->isWritable(DoctrineGeneratedValue::class, 'id'));
$this->assertNull($extractor->isReadable(DoctrineGeneratedValue::class, 'id'));
$this->assertNull($extractor->isWritable(DoctrineGeneratedValue::class, 'foo'));
$this->assertNull($extractor->isReadable(DoctrineGeneratedValue::class, 'foo'));
}
}

View File

@ -0,0 +1,37 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Bridge\Doctrine\Tests\PropertyInfo\Fixtures;
use Doctrine\ORM\Mapping\Column;
use Doctrine\ORM\Mapping\Entity;
use Doctrine\ORM\Mapping\GeneratedValue;
use Doctrine\ORM\Mapping\Id;
/**
* @author Kévin Dunglas <dunglas@gmail.com>
*
* @Entity
*/
class DoctrineGeneratedValue
{
/**
* @Id
* @GeneratedValue(strategy="AUTO")
* @Column(type="integer")
*/
public $id;
/**
* @Column
*/
public $foo;
}