Skip to content

Commit 32b7a81

Browse files
committed
Add options in listeners: forceUseAttributeReader and separateXmlMapping
1 parent 1ec37fb commit 32b7a81

File tree

4 files changed

+103
-15
lines changed

4 files changed

+103
-15
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ a release.
1818
---
1919

2020
## [Unreleased]
21+
### Fixed
22+
- 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)
23+
2124
### Added
2225
- SoftDeleteable: `Gedmo\SoftDeleteable\Event\PreSoftDeleteEventArgs` and
2326
`Gedmo\SoftDeleteable\Event\PostSoftDeleteEventArgs` classes.

src/Mapping/Driver/File.php

Lines changed: 44 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -120,20 +120,56 @@ abstract protected function _loadMappingFile($file);
120120
*/
121121
protected function _getMapping($className)
122122
{
123-
// try loading mapping from original driver first
124123
$mapping = null;
125-
if (null !== $this->_originalDriver) {
126-
if ($this->_originalDriver instanceof FileDriver) {
127-
$mapping = $this->_originalDriver->getElement($className);
128-
}
124+
$separatedFile = strpos($this->locator->getFileExtension(), '.gedmo') === 0;
125+
126+
if($separatedFile){
127+
// try loading mapping from gedmo driver first
128+
$mapping = $this->getMappingFromGedmoFileDriver($className);
129129
}
130130

131-
// if no mapping found try to load mapping file again
131+
// if no mapping found try to load mapping file from original driver again
132132
if (null === $mapping) {
133-
$yaml = $this->_loadMappingFile($this->locator->findMappingFile($className));
134-
$mapping = $yaml[$className];
133+
// read .orm.xml
134+
$mapping = $this->getMappingFromOriginalDriver($className);
135+
}
136+
if (!$separatedFile && null === $mapping) {
137+
// if no mapping found try to load mapping file again
138+
$mapping = $this->getMappingFromGedmoFileDriver($className);
139+
}
140+
141+
return $mapping;
142+
}
143+
/**
144+
* Tries to get a mapping for a given class from gedmo driver.
145+
*
146+
* @param string $className
147+
*
148+
* @return array|object|null
149+
*/
150+
private function getMappingFromGedmoFileDriver($className){
151+
if(!$this->locator->fileExists($className)){
152+
return null;
135153
}
136154

155+
$mapping = $this->_loadMappingFile($this->locator->findMappingFile($className));
156+
return $mapping[$className] ?? null;
157+
}
158+
159+
/**
160+
* Tries to get a mapping for a given class from original doctrine driver.
161+
*
162+
* @param string $className
163+
*
164+
* @return array|object|null
165+
*/
166+
private function getMappingFromOriginalDriver($className){
167+
$mapping = null;
168+
if (null !== $this->_originalDriver) {
169+
if ($this->_originalDriver instanceof FileDriver) {
170+
$mapping = $this->_originalDriver->getElement($className);
171+
}
172+
}
137173
return $mapping;
138174
}
139175

src/Mapping/ExtensionMetadataFactory.php

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
use Doctrine\ODM\MongoDB\Mapping\ClassMetadata as DocumentClassMetadata;
1515
use Doctrine\ORM\Mapping\ClassMetadata as EntityClassMetadata;
1616
use Doctrine\ORM\Mapping\ClassMetadataInfo as LegacyEntityClassMetadata;
17+
use Doctrine\ORM\Mapping\Driver\AttributeDriver;
1718
use Doctrine\Persistence\Mapping\ClassMetadata;
1819
use Doctrine\Persistence\Mapping\Driver\DefaultFileLocator;
1920
use Doctrine\Persistence\Mapping\Driver\MappingDriver;
@@ -69,10 +70,22 @@ class ExtensionMetadataFactory
6970

7071
private ?CacheItemPoolInterface $cacheItemPool = null;
7172

73+
/**
74+
* Ignore doctrine driver class and force use attribute reader for gedmo properties
75+
* @var bool
76+
*/
77+
private $forceUseAttributeReader;
78+
79+
/**
80+
* Search mapping in .gedmo.xml and does not use doctrine *.orm.xml or *.dcm.xml file
81+
* @var bool
82+
*/
83+
private $separateXmlMapping;
84+
7285
/**
7386
* @param Reader|AttributeReader|object|null $annotationReader
7487
*/
75-
public function __construct(ObjectManager $objectManager, string $extensionNamespace, ?object $annotationReader = null, ?CacheItemPoolInterface $cacheItemPool = null)
88+
public function __construct(ObjectManager $objectManager, string $extensionNamespace, ?object $annotationReader = null, ?CacheItemPoolInterface $cacheItemPool = null, bool $forceUseAttributeReader = false, bool $separateXmlMapping = false)
7689
{
7790
if (null !== $annotationReader && !$annotationReader instanceof Reader && !$annotationReader instanceof AttributeReader) {
7891
trigger_deprecation(
@@ -88,6 +101,9 @@ public function __construct(ObjectManager $objectManager, string $extensionNames
88101
$this->objectManager = $objectManager;
89102
$this->annotationReader = $annotationReader;
90103
$this->extensionNamespace = $extensionNamespace;
104+
$this->forceUseAttributeReader = $forceUseAttributeReader;
105+
$this->separateXmlMapping = $separateXmlMapping;
106+
91107
$omDriver = $objectManager->getConfiguration()->getMetadataDriverImpl();
92108
$this->driver = $this->getDriver($omDriver);
93109
$this->cacheItemPool = $cacheItemPool;
@@ -171,6 +187,10 @@ public static function getCacheId($className, $extensionNamespace)
171187
return str_replace('\\', '_', $className).'_$'.strtoupper(str_replace('\\', '_', $extensionNamespace)).'_CLASSMETADATA';
172188
}
173189

190+
private function getFileExtension($fileExtension)
191+
{
192+
return $this->separateXmlMapping ? str_replace(['.orm.','.dcm.'], '.gedmo.', $fileExtension) : $fileExtension;
193+
}
174194
/**
175195
* Get the extended driver instance which will
176196
* read the metadata required by extension
@@ -192,11 +212,12 @@ protected function getDriver($omDriver)
192212
$driverName = substr($className, strrpos($className, '\\') + 1);
193213
if ($omDriver instanceof MappingDriverChain || 'DriverChain' === $driverName) {
194214
$driver = new Chain();
215+
$attributeDriver = $this->forceUseAttributeReader ? new AttributeDriver([]) : null;
195216
foreach ($omDriver->getDrivers() as $namespace => $nestedOmDriver) {
196-
$driver->addDriver($this->getDriver($nestedOmDriver), $namespace);
217+
$driver->addDriver($this->getDriver($attributeDriver ?? $nestedOmDriver), $namespace);
197218
}
198219
if (null !== $omDriver->getDefaultDriver()) {
199-
$driver->setDefaultDriver($this->getDriver($omDriver->getDefaultDriver()));
220+
$driver->setDefaultDriver($this->getDriver($attributeDriver ?? $omDriver->getDefaultDriver()));
200221
}
201222
} else {
202223
$driverName = substr($driverName, 0, strpos($driverName, 'Driver'));
@@ -230,12 +251,14 @@ protected function getDriver($omDriver)
230251
$driver->setOriginalDriver($omDriver);
231252
if ($driver instanceof FileDriver) {
232253
if ($omDriver instanceof MappingDriver) {
233-
$driver->setLocator($omDriver->getLocator());
254+
$locator = clone $omDriver->getLocator();
255+
$locator->setFileExtension($this->getFileExtension( $locator->getFileExtension()));
256+
$driver->setLocator($locator);
234257
// BC for Doctrine 2.2
235258
} elseif ($isSimplified) {
236-
$driver->setLocator(new SymfonyFileLocator($omDriver->getNamespacePrefixes(), $omDriver->getFileExtension()));
259+
$driver->setLocator(new SymfonyFileLocator($omDriver->getNamespacePrefixes(), $this->getFileExtension( $omDriver->getFileExtension())));
237260
} else {
238-
$driver->setLocator(new DefaultFileLocator($omDriver->getPaths(), $omDriver->getFileExtension()));
261+
$driver->setLocator(new DefaultFileLocator($omDriver->getPaths(), $this->getFileExtension( $omDriver->getFileExtension())));
239262
}
240263
}
241264

src/Mapping/MappedEventSubscriber.php

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,12 +94,36 @@ abstract class MappedEventSubscriber implements EventSubscriber
9494
*/
9595
private $cacheItemPool;
9696

97+
98+
/**
99+
* Ignore doctrine driver class and force use attribute reader for gedmo properties
100+
* @var bool
101+
*/
102+
private $forceUseAttributeReader = false;
103+
104+
/**
105+
* Search mapping in .gedmo.xml and does not use doctrine *.orm.xml or *.dcm.xml file
106+
* @var bool
107+
*/
108+
private $separateXmlMapping = false;
109+
110+
97111
public function __construct()
98112
{
99113
$parts = explode('\\', $this->getNamespace());
100114
$this->name = end($parts);
101115
}
102116

117+
118+
public function setForceUseAttributeReader(bool $forceUseAttributeReader) {
119+
$this->forceUseAttributeReader = $forceUseAttributeReader;
120+
}
121+
public function setSeparateXmlMapping(bool $separateXmlMapping) {
122+
$this->separateXmlMapping = $separateXmlMapping;
123+
}
124+
125+
126+
103127
/**
104128
* Get the configuration for specific object class
105129
* if cache driver is present it scans it also
@@ -178,7 +202,9 @@ public function getExtensionMetadataFactory(ObjectManager $objectManager)
178202
$objectManager,
179203
$this->getNamespace(),
180204
$this->annotationReader,
181-
$this->getCacheItemPool($objectManager)
205+
$this->getCacheItemPool($objectManager),
206+
$this->forceUseAttributeReader,
207+
$this->separateXmlMapping
182208
);
183209
}
184210

0 commit comments

Comments
 (0)