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 Jul 27, 2023
1 parent f21d888 commit b82af95
Show file tree
Hide file tree
Showing 4 changed files with 102 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.12.0] - 2023-07-08
### Added
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 @@ -116,20 +116,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 @@ -13,6 +13,7 @@
use Doctrine\Common\Annotations\Reader;
use Doctrine\ODM\MongoDB\Mapping\ClassMetadata as DocumentClassMetadata;
use Doctrine\ORM\Mapping\ClassMetadataInfo as EntityClassMetadata;
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 @@ -71,10 +72,22 @@ class ExtensionMetadataFactory
*/
private $cacheItemPool;

/**
* 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 $annotationReader
*/
public function __construct(ObjectManager $objectManager, string $extensionNamespace, object $annotationReader, ?CacheItemPoolInterface $cacheItemPool = null)
public function __construct(ObjectManager $objectManager, string $extensionNamespace, object $annotationReader, ?CacheItemPoolInterface $cacheItemPool = null, $forceUseAttributeReader = false, $separateXmlMapping = false)
{
if (!$annotationReader instanceof Reader && !$annotationReader instanceof AttributeReader) {
trigger_deprecation(
Expand All @@ -90,6 +103,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 @@ -155,6 +171,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 @@ -176,11 +196,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 All @@ -202,12 +223,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
28 changes: 27 additions & 1 deletion src/Mapping/MappedEventSubscriber.php
Original file line number Diff line number Diff line change
Expand Up @@ -95,12 +95,36 @@ abstract class MappedEventSubscriber implements EventSubscriber
*/
private $cacheItemPool;


/**
* 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 @@ -179,7 +203,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 b82af95

Please sign in to comment.