doctrine / doctrine/persistence
Wrong Manager returned for similar Namespaces
- Dominant language
- PHP
- Stars
- 4k
- Forks
- 76
- Avg merge
- 3d 20h
- Merged PRs (30d)
- 2
Description
### Bug Report
| Q | A
|-------------------------------------------- | ------
| Version | 4.0.0
#### Summary
The wrong Manager can be selected if configured Managers have similar namespaces.
#### Current behavior
The wrong Manager is returned when two or more Managers with similar namespaces are configured.
#### Expected behavior
The correct Manager should be selected.
#### How to reproduce
Configure Manager `A` with the namespace:
`App\Entity`
and Manager `B` with:
`App\EntityFoo`
---
`MappingDriverChain::isTransient` will select `A` for a `B`-configured Manager because:
`str_starts_with($className, $namespace)` returns `true` for both.
A solution could be to find the best match rather than selecting the first driver that matches the namespace prefix.
## Solution proposal
Find the best namespace overlap:
```php
public function isTransient(string $className): bool
{
$driver = $this->findBestMatchingDriver($className) ?? $this->defaultDriver;
return $driver ? $driver->isTransient($className) : true;
}
private function findBestMatchingDriver(string $className): ?MappingDriver
{
$bestDriver = null;
$maxOverlap = 0;
foreach ($this->drivers as $namespace => $driver) {
if ( ! str_starts_with($className, $namespace)) {
continue;
}
$currentOverlap = similar_text($className, $namespace);
if ($currentOverlap > $maxOverlap) {
$maxOverlap = $currentOverlap;
$bestDriver = $driver;
}
}
return $bestDriver;
}
```
I could create a pull request with tests if this approach is heading in the right direction. A huge thank you to all contributors!
Contributor guide
Assessment
This issue has not been assessed yet.