doctrine / doctrine/persistence

Wrong Manager returned for similar Namespaces

Open
#404 4 comments 0 reactions 0 assignees View on GitHub
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

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.