Skip to content

Commit

Permalink
Add options in listeners: forceUseAttributeReader and separateXmlMapping
Browse files Browse the repository at this point in the history
  • Loading branch information
eisberg committed Jun 27, 2024
1 parent e85560e commit 3b0553f
Show file tree
Hide file tree
Showing 4 changed files with 101 additions and 15 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ a release.
---

## [Unreleased]
### Fixed
- Mapping Driver: Configure usage separately with Doctrine `.orm.xml` -> `.gedmo.xml` files, also add an alternative option - force the use of AttributeReader and ignore the configuration of the Doctrine chain driver (#2613)

## [3.16.1]
### Fixed
Expand Down
52 changes: 44 additions & 8 deletions src/Mapping/Driver/File.php
Original file line number Diff line number Diff line change
Expand Up @@ -120,20 +120,56 @@ abstract protected function _loadMappingFile($file);
*/
protected function _getMapping($className)
{
// try loading mapping from original driver first
$mapping = null;
if (null !== $this->_originalDriver) {
if ($this->_originalDriver instanceof FileDriver) {
$mapping = $this->_originalDriver->getElement($className);
}
$separatedFile = strpos($this->locator->getFileExtension(), '.gedmo') === 0;

if($separatedFile){
// try loading mapping from gedmo driver first
$mapping = $this->getMappingFromGedmoFileDriver($className);
}

// if no mapping found try to load mapping file again
// if no mapping found try to load mapping file from original driver again
if (null === $mapping) {
$yaml = $this->_loadMappingFile($this->locator->findMappingFile($className));
$mapping = $yaml[$className];
// read .orm.xml
$mapping = $this->getMappingFromOriginalDriver($className);
}
if (!$separatedFile && null === $mapping) {
// if no mapping found try to load mapping file again
$mapping = $this->getMappingFromGedmoFileDriver($className);
}

return $mapping;
}
/**
* Tries to get a mapping for a given class from gedmo driver.
*
* @param string $className
*
* @return array|object|null
*/
private function getMappingFromGedmoFileDriver($className){
if(!$this->locator->fileExists($className)){
return null;
}

$mapping = $this->_loadMappingFile($this->locator->findMappingFile($className));
return $mapping[$className] ?? null;
}

/**
* Tries to get a mapping for a given class from original doctrine driver.
*
* @param string $className
*
* @return array|object|null
*/
private function getMappingFromOriginalDriver($className){
$mapping = null;
if (null !== $this->_originalDriver) {
if ($this->_originalDriver instanceof FileDriver) {
$mapping = $this->_originalDriver->getElement($className);
}
}
return $mapping;
}

Expand Down
35 changes: 29 additions & 6 deletions src/Mapping/ExtensionMetadataFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
use Doctrine\ODM\MongoDB\Mapping\ClassMetadata as DocumentClassMetadata;
use Doctrine\ORM\Mapping\ClassMetadata as EntityClassMetadata;
use Doctrine\ORM\Mapping\ClassMetadataInfo as LegacyEntityClassMetadata;
use Doctrine\ORM\Mapping\Driver\AttributeDriver;
use Doctrine\Persistence\Mapping\ClassMetadata;
use Doctrine\Persistence\Mapping\Driver\DefaultFileLocator;
use Doctrine\Persistence\Mapping\Driver\MappingDriver;
Expand Down Expand Up @@ -70,12 +71,24 @@ class ExtensionMetadataFactory

private ?CacheItemPoolInterface $cacheItemPool = null;

/**
* Ignore doctrine driver class and force use attribute reader for gedmo properties
* @var bool
*/
private $forceUseAttributeReader;

/**
* Search mapping in .gedmo.xml and does not use doctrine *.orm.xml or *.dcm.xml file
* @var bool
*/
private $separateXmlMapping;

/**
* @param Reader|AttributeReader|object|null $annotationReader
*
* @note Providing any object as the third argument is deprecated, as of 4.0 an {@see AttributeReader} will be required
*/
public function __construct(ObjectManager $objectManager, string $extensionNamespace, ?object $annotationReader = null, ?CacheItemPoolInterface $cacheItemPool = null)
public function __construct(ObjectManager $objectManager, string $extensionNamespace, ?object $annotationReader = null, ?CacheItemPoolInterface $cacheItemPool = null, bool $forceUseAttributeReader = false, bool $separateXmlMapping = false)
{
if (null !== $annotationReader) {
if ($annotationReader instanceof Reader) {
Expand All @@ -101,6 +114,9 @@ public function __construct(ObjectManager $objectManager, string $extensionNames
$this->objectManager = $objectManager;
$this->annotationReader = $annotationReader;
$this->extensionNamespace = $extensionNamespace;
$this->forceUseAttributeReader = $forceUseAttributeReader;
$this->separateXmlMapping = $separateXmlMapping;

$omDriver = $objectManager->getConfiguration()->getMetadataDriverImpl();
$this->driver = $this->getDriver($omDriver);
$this->cacheItemPool = $cacheItemPool;
Expand Down Expand Up @@ -184,6 +200,10 @@ public static function getCacheId($className, $extensionNamespace)
return str_replace('\\', '_', $className).'_$'.strtoupper(str_replace('\\', '_', $extensionNamespace)).'_CLASSMETADATA';
}

private function getFileExtension($fileExtension)
{
return $this->separateXmlMapping ? str_replace(['.orm.','.dcm.'], '.gedmo.', $fileExtension) : $fileExtension;
}
/**
* Get the extended driver instance which will
* read the metadata required by extension
Expand All @@ -205,11 +225,12 @@ protected function getDriver($omDriver)
$driverName = substr($className, strrpos($className, '\\') + 1);
if ($omDriver instanceof MappingDriverChain || 'DriverChain' === $driverName) {
$driver = new Chain();
$attributeDriver = $this->forceUseAttributeReader ? new AttributeDriver([]) : null;
foreach ($omDriver->getDrivers() as $namespace => $nestedOmDriver) {
$driver->addDriver($this->getDriver($nestedOmDriver), $namespace);
$driver->addDriver($this->getDriver($attributeDriver ?? $nestedOmDriver), $namespace);
}
if (null !== $omDriver->getDefaultDriver()) {
$driver->setDefaultDriver($this->getDriver($omDriver->getDefaultDriver()));
$driver->setDefaultDriver($this->getDriver($attributeDriver ?? $omDriver->getDefaultDriver()));
}
} else {
$driverName = substr($driverName, 0, strpos($driverName, 'Driver'));
Expand Down Expand Up @@ -243,12 +264,14 @@ protected function getDriver($omDriver)
$driver->setOriginalDriver($omDriver);
if ($driver instanceof FileDriver) {
if ($omDriver instanceof MappingDriver) {
$driver->setLocator($omDriver->getLocator());
$locator = clone $omDriver->getLocator();
$locator->setFileExtension($this->getFileExtension( $locator->getFileExtension()));
$driver->setLocator($locator);
// BC for Doctrine 2.2
} elseif ($isSimplified) {
$driver->setLocator(new SymfonyFileLocator($omDriver->getNamespacePrefixes(), $omDriver->getFileExtension()));
$driver->setLocator(new SymfonyFileLocator($omDriver->getNamespacePrefixes(), $this->getFileExtension( $omDriver->getFileExtension())));
} else {
$driver->setLocator(new DefaultFileLocator($omDriver->getPaths(), $omDriver->getFileExtension()));
$driver->setLocator(new DefaultFileLocator($omDriver->getPaths(), $this->getFileExtension( $omDriver->getFileExtension())));
}
}

Expand Down
27 changes: 26 additions & 1 deletion src/Mapping/MappedEventSubscriber.php
Original file line number Diff line number Diff line change
Expand Up @@ -99,12 +99,35 @@ abstract class MappedEventSubscriber implements EventSubscriber

private ?ClockInterface $clock = null;

/**
* Ignore doctrine driver class and force use attribute reader for gedmo properties
* @var bool
*/
private $forceUseAttributeReader = false;

/**
* Search mapping in .gedmo.xml and does not use doctrine *.orm.xml or *.dcm.xml file
* @var bool
*/
private $separateXmlMapping = false;


public function __construct()
{
$parts = explode('\\', $this->getNamespace());
$this->name = end($parts);
}


public function setForceUseAttributeReader(bool $forceUseAttributeReader) {
$this->forceUseAttributeReader = $forceUseAttributeReader;
}
public function setSeparateXmlMapping(bool $separateXmlMapping) {
$this->separateXmlMapping = $separateXmlMapping;
}



/**
* Get the configuration for specific object class
* if cache driver is present it scans it also
Expand Down Expand Up @@ -183,7 +206,9 @@ public function getExtensionMetadataFactory(ObjectManager $objectManager)
$objectManager,
$this->getNamespace(),
$this->annotationReader,
$this->getCacheItemPool($objectManager)
$this->getCacheItemPool($objectManager),
$this->forceUseAttributeReader,
$this->separateXmlMapping
);
}

Expand Down

0 comments on commit 3b0553f

Please sign in to comment.