Skip to content

Commit

Permalink
Make the annotation/attribute reader optional in the extension metada…
Browse files Browse the repository at this point in the history
…ta factory
  • Loading branch information
mbabker committed Nov 28, 2023
1 parent 8a1f28b commit 181ca22
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 24 deletions.
44 changes: 31 additions & 13 deletions src/Mapping/ExtensionMetadataFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -61,20 +61,20 @@ class ExtensionMetadataFactory
protected $extensionNamespace;

/**
* Custom annotation reader
* Metadata annotation reader
*
* @var Reader|AttributeReader|object
* @var Reader|AttributeReader|object|null
*/
protected $annotationReader;

private ?CacheItemPoolInterface $cacheItemPool = null;

/**
* @param Reader|AttributeReader|object $annotationReader
* @param Reader|AttributeReader|object|null $annotationReader
*/
public function __construct(ObjectManager $objectManager, string $extensionNamespace, object $annotationReader, ?CacheItemPoolInterface $cacheItemPool = null)
public function __construct(ObjectManager $objectManager, string $extensionNamespace, ?object $annotationReader = null, ?CacheItemPoolInterface $cacheItemPool = null)
{
if (!$annotationReader instanceof Reader && !$annotationReader instanceof AttributeReader) {
if (null !== $annotationReader && !$annotationReader instanceof Reader && !$annotationReader instanceof AttributeReader) {
trigger_deprecation(
'gedmo/doctrine-extensions',
'3.11',
Expand All @@ -98,7 +98,7 @@ public function __construct(ObjectManager $objectManager, string $extensionNames
*
* @param ClassMetadata&(DocumentClassMetadata|EntityClassMetadata|LegacyEntityClassMetadata) $meta
*
* @return array<string, mixed> the metatada configuration
* @return array<string, mixed> the metadata configuration
*/
public function getExtensionMetadata($meta)
{
Expand Down Expand Up @@ -209,8 +209,20 @@ protected function getDriver($omDriver)
// create driver instance
$driverClassName = $this->extensionNamespace.'\Mapping\Driver\\'.$driverName;
if (!class_exists($driverClassName)) {
$driverClassName = $this->extensionNamespace.'\Mapping\Driver\Annotation';
$originalDriverClassName = $driverClassName;

// try to fall back to either an annotation or attribute driver depending on the available dependencies
if (interface_exists(Reader::class)) {
$driverClassName = $this->extensionNamespace.'\Mapping\Driver\Annotation';
} elseif (\PHP_VERSION_ID >= 80000) {
$driverClassName = $this->extensionNamespace.'\Mapping\Driver\Attribute';

Check warning on line 218 in src/Mapping/ExtensionMetadataFactory.php

View check run for this annotation

Codecov / codecov/patch

src/Mapping/ExtensionMetadataFactory.php#L217-L218

Added lines #L217 - L218 were not covered by tests
}

if (!class_exists($driverClassName)) {
if ($originalDriverClassName !== $driverClassName) {
throw new RuntimeException("Failed to create mapping driver: ({$originalDriverClassName}), the extension driver nor a fallback annotation or attribute driver could be found.");

Check warning on line 223 in src/Mapping/ExtensionMetadataFactory.php

View check run for this annotation

Codecov / codecov/patch

src/Mapping/ExtensionMetadataFactory.php#L222-L223

Added lines #L222 - L223 were not covered by tests
}

throw new RuntimeException("Failed to fallback to annotation driver: ({$driverClassName}), extension driver was not found.");
}
}
Expand All @@ -227,14 +239,20 @@ protected function getDriver($omDriver)
}
}

if ($driver instanceof AttributeDriverInterface) {
if ($this->annotationReader instanceof AttributeReader) {
$driver->setAnnotationReader($this->annotationReader);
if ($driver instanceof AnnotationDriverInterface) {
if (null === $this->annotationReader) {
throw new RuntimeException("Cannot use metadata driver ({$driverClassName}), an annotation or attribute reader was not provided.");

Check warning on line 244 in src/Mapping/ExtensionMetadataFactory.php

View check run for this annotation

Codecov / codecov/patch

src/Mapping/ExtensionMetadataFactory.php#L244

Added line #L244 was not covered by tests
}

if ($driver instanceof AttributeDriverInterface) {
if ($this->annotationReader instanceof AttributeReader) {
$driver->setAnnotationReader($this->annotationReader);
} else {
$driver->setAnnotationReader(new AttributeAnnotationReader(new AttributeReader(), $this->annotationReader));
}
} else {
$driver->setAnnotationReader(new AttributeAnnotationReader(new AttributeReader(), $this->annotationReader));
$driver->setAnnotationReader($this->annotationReader);
}
} elseif ($driver instanceof AnnotationDriverInterface) {
$driver->setAnnotationReader($this->annotationReader);
}
}

Expand Down
24 changes: 13 additions & 11 deletions src/Mapping/MappedEventSubscriber.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
use Doctrine\Persistence\Mapping\ClassMetadata;
use Doctrine\Persistence\ObjectManager;
use Gedmo\Exception\InvalidArgumentException;
use Gedmo\Exception\RuntimeException;
use Gedmo\Mapping\Driver\AttributeReader;
use Gedmo\Mapping\Event\AdapterInterface;
use Gedmo\ReferenceIntegrity\Mapping\Validator as ReferenceIntegrityValidator;
Expand Down Expand Up @@ -81,14 +80,14 @@ abstract class MappedEventSubscriber implements EventSubscriber
/**
* Custom annotation reader
*
* @var Reader|AttributeReader|object|null
* @var Reader|AttributeReader|object|false|null
*/
private $annotationReader;
private $annotationReader = false;

/**
* @var Reader|AttributeReader|null
* @var Reader|AttributeReader|false|null
*/
private static $defaultAnnotationReader;
private static $defaultAnnotationReader = false;

/**
* @var CacheItemPoolInterface|null
Expand Down Expand Up @@ -171,8 +170,8 @@ public function getExtensionMetadataFactory(ObjectManager $objectManager)
{
$oid = spl_object_id($objectManager);
if (!isset($this->extensionMetadataFactory[$oid])) {
if (null === $this->annotationReader) {
// create default annotation reader for extensions
if (false === $this->annotationReader) {
// create default annotation/attribute reader for extensions
$this->annotationReader = $this->getDefaultAnnotationReader();
}
$this->extensionMetadataFactory[$oid] = new ExtensionMetadataFactory(
Expand Down Expand Up @@ -307,19 +306,22 @@ protected function setFieldValue(AdapterInterface $adapter, $object, $field, $ol
}

/**
* Create default annotation reader for extensions
* Get the default annotation or attribute reader for extensions, creating it if necessary.
*
* @return Reader|AttributeReader
* If a reader cannot be created due to missing requirements, no default will be set as the reader is only required for annotation or attribute metadata,
* and the {@see ExtensionMetadataFactory} can handle raising an error if it tries to create a mapping driver that requires this reader.
*
* @return Reader|AttributeReader|null
*/
private function getDefaultAnnotationReader()
{
if (null === self::$defaultAnnotationReader) {
if (false === self::$defaultAnnotationReader) {
if (class_exists(PsrCachedReader::class)) {
self::$defaultAnnotationReader = new PsrCachedReader(new AnnotationReader(), new ArrayAdapter());
} elseif (\PHP_VERSION_ID >= 80000) {
self::$defaultAnnotationReader = new AttributeReader();

Check warning on line 322 in src/Mapping/MappedEventSubscriber.php

View check run for this annotation

Codecov / codecov/patch

src/Mapping/MappedEventSubscriber.php#L321-L322

Added lines #L321 - L322 were not covered by tests
} else {
throw new RuntimeException(sprintf('Cannot create a default annotation reader in "%1$s". Ensure you are running PHP 8 to use attributes, have installed the "doctrine/annotations" package, or call "%1$s::setAnnotationReader()" with a configured reader.', self::class));
self::$defaultAnnotationReader = null;

Check warning on line 324 in src/Mapping/MappedEventSubscriber.php

View check run for this annotation

Codecov / codecov/patch

src/Mapping/MappedEventSubscriber.php#L324

Added line #L324 was not covered by tests
}
}

Expand Down

0 comments on commit 181ca22

Please sign in to comment.