Skip to content

Commit

Permalink
[Doctrine][PropertyInfo] Detect if the ID is writeable
Browse files Browse the repository at this point in the history
  • Loading branch information
dunglas committed May 12, 2019
1 parent 6c5faef commit 4598235
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 13 deletions.
53 changes: 40 additions & 13 deletions src/Symfony/Bridge/Doctrine/PropertyInfo/DoctrineExtractor.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,10 @@
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;
Expand All @@ -26,7 +28,7 @@
*
* @author Kévin Dunglas <[email protected]>
*/
class DoctrineExtractor implements PropertyListExtractorInterface, PropertyTypeExtractorInterface
class DoctrineExtractor implements PropertyListExtractorInterface, PropertyTypeExtractorInterface, PropertyAccessExtractorInterface
{
private $entityManager;
private $classMetadataFactory;
Expand All @@ -51,12 +53,8 @@ public function __construct($entityManager)
*/
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());
Expand All @@ -77,12 +75,8 @@ public function getProperties($class, array $context = [])
*/
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)) {
Expand Down Expand Up @@ -176,6 +170,39 @@ public function getTypes($class, $property, array $context = [])
}
}

/**
* {@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.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
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;

/**
Expand Down Expand Up @@ -223,4 +224,13 @@ private function doTestGetTypesCatchException(bool $legacy)
{
$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'));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?php

/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <[email protected]>
*
* 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 <[email protected]>
*
* @Entity
*/
class DoctrineGeneratedValue
{
/**
* @Id
* @GeneratedValue(strategy="AUTO")
* @Column(type="integer")
*/
public $id;

/**
* @Column
*/
public $foo;
}

0 comments on commit 4598235

Please sign in to comment.