Skip to content

Commit

Permalink
feat: nested mapping hierarchy
Browse files Browse the repository at this point in the history
  • Loading branch information
jhabaj committed Jan 10, 2025
1 parent cd92b0a commit 29eea79
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 10 deletions.
24 changes: 14 additions & 10 deletions src/Application/PresenterFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -107,22 +107,26 @@ public function formatPresenterClass(string $presenter): string
if (!Nette\Utils\Strings::match($presenter, '#^[a-zA-Z\x7f-\xff][a-zA-Z0-9\x7f-\xff:]*$#D')) {
throw new InvalidPresenterException("Presenter name must be alphanumeric string, '$presenter' is invalid.");
}
$parts = explode(':', $presenter);
$mapping = $this->mapping['*'];
$parts = explode(':', $presenter);

$key = '';
foreach ($parts as $part) {
$key = $key ? $key . ':' . $part : $part;
if (isset($parts[1], $this->mapping[$key])) {
$mapping = $this->mapping['*'];

$key = $presenter;
while (strrpos($key, ':') != false) {
$key = substr($key, 0, strrpos($key, ':'));

if (isset($this->mapping[$key])) {
$mapping = $this->mapping[$key];
$parts = array_slice($parts, count(explode(':', $key)));

$parts = array_slice($parts, substr_count($key, ':') + 1);
break;
}

}

while ($part = array_shift($parts)) {
$mapping[0] .= strtr($mapping[$parts ? 1 : 2], ['**' => "$part\\$part", '*' => $part]);
}
while ($part = array_shift($parts)) {
$mapping[0] .= strtr($mapping[$parts ? 1 : 2], ['**' => "$part\\$part", '*' => $part]);
}

return $mapping[0];
}
Expand Down
16 changes: 16 additions & 0 deletions tests/Application/PresenterFactory.formatPresenterClass.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ test('defined module', function () {
$factory->setMapping([
'Foo2' => 'App2\*\*Presenter',
'Foo3' => 'My\App\*Mod\*Presenter',
'Foo4' => 'My\App\*Mod\*Presenter',
'Foo4:Bar' => 'Other\App\*Mod\*Presenter',
]);

Expand All @@ -33,6 +34,9 @@ test('defined module', function () {
Assert::same('My\App\BarPresenter', $factory->formatPresenterClass('Foo3:Bar'));
Assert::same('My\App\BarMod\BazPresenter', $factory->formatPresenterClass('Foo3:Bar:Baz'));

Assert::same('My\App\FooPresenter', $factory->formatPresenterClass('Foo4:Foo'));
Assert::same('My\App\FooMod\BarPresenter', $factory->formatPresenterClass('Foo4:Foo:Bar'));

Assert::same('Other\App\BazPresenter', $factory->formatPresenterClass('Foo4:Bar:Baz'));
Assert::same('Other\App\BazMod\FooPresenter', $factory->formatPresenterClass('Foo4:Bar:Baz:Foo'));

Expand All @@ -46,6 +50,7 @@ test('auto module', function () {
$factory->setMapping([
'Foo2' => 'App2\*Presenter',
'Foo3' => 'My\App\*Presenter',
'Foo4' => 'My\App\*Presenter',
'Foo4:Bar' => 'Other\App\*Presenter',
]);

Expand All @@ -56,6 +61,9 @@ test('auto module', function () {
Assert::same('My\App\BarPresenter', $factory->formatPresenterClass('Foo3:Bar'));
Assert::same('My\App\BarModule\BazPresenter', $factory->formatPresenterClass('Foo3:Bar:Baz'));

Assert::same('My\App\FooPresenter', $factory->formatPresenterClass('Foo4:Foo'));
Assert::same('My\App\FooModule\BarPresenter', $factory->formatPresenterClass('Foo4:Foo:Bar'));

Assert::same('Other\App\BazPresenter', $factory->formatPresenterClass('Foo4:Bar:Baz'));
Assert::same('Other\App\BazModule\FooPresenter', $factory->formatPresenterClass('Foo4:Bar:Baz:Foo'));
});
Expand All @@ -67,6 +75,7 @@ test('location ** & defined module', function () {
$factory->setMapping([
'Foo2' => 'App2\*\**Presenter',
'Foo3' => 'My\App\*Mod\**Presenter',
'Foo4' => 'My\App\*Mod\**Presenter',
'Foo4:Bar' => 'Other\App\*Mod\**Presenter',
]);

Expand All @@ -81,6 +90,9 @@ test('location ** & defined module', function () {
Assert::same('My\App\Bar\BarPresenter', $factory->formatPresenterClass('Foo3:Bar'));
Assert::same('My\App\BarMod\Baz\BazPresenter', $factory->formatPresenterClass('Foo3:Bar:Baz'));

Assert::same('My\App\Foo\FooPresenter', $factory->formatPresenterClass('Foo4:Foo'));
Assert::same('My\App\FooMod\Bar\BarPresenter', $factory->formatPresenterClass('Foo4:Foo:Bar'));

Assert::same('Other\App\Baz\BazPresenter', $factory->formatPresenterClass('Foo4:Bar:Baz'));
Assert::same('Other\App\BazMod\Foo\FooPresenter', $factory->formatPresenterClass('Foo4:Bar:Baz:Foo'));

Expand All @@ -95,6 +107,7 @@ test('location ** & auto module', function () {
'*' => '**Presenter',
'Foo2' => 'App2\**Presenter',
'Foo3' => 'My\App\**Presenter',
'Foo4' => 'My\App\**Presenter',
'Foo4:Bar' => 'Other\App\**Presenter',
]);

Expand All @@ -105,6 +118,9 @@ test('location ** & auto module', function () {
Assert::same('My\App\Bar\BarPresenter', $factory->formatPresenterClass('Foo3:Bar'));
Assert::same('My\App\BarModule\Baz\BazPresenter', $factory->formatPresenterClass('Foo3:Bar:Baz'));

Assert::same('My\App\Foo\FooPresenter', $factory->formatPresenterClass('Foo4:Foo'));
Assert::same('My\App\FooModule\Bar\BarPresenter', $factory->formatPresenterClass('Foo4:Foo:Bar'));

Assert::same('Other\App\Baz\BazPresenter', $factory->formatPresenterClass('Foo4:Bar:Baz'));
Assert::same('Other\App\BazModule\Foo\FooPresenter', $factory->formatPresenterClass('Foo4:Bar:Baz:Foo'));
});
Expand Down

0 comments on commit 29eea79

Please sign in to comment.