Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

IBX-6906: [DX] Introduced identifier-based view matchers #322

Merged
merged 8 commits into from
Feb 5, 2024
20 changes: 0 additions & 20 deletions phpstan-baseline.neon
Original file line number Diff line number Diff line change
Expand Up @@ -3825,16 +3825,6 @@ parameters:
count: 1
path: src/bundle/Core/Matcher/ServiceAwareMatcherFactory.php

-
message: "#^Method Ibexa\\\\Bundle\\\\Core\\\\Matcher\\\\ServiceAwareMatcherFactory\\:\\:__construct\\(\\) has parameter \\$relativeNamespace with no type specified\\.$#"
count: 1
path: src/bundle/Core/Matcher/ServiceAwareMatcherFactory.php

-
message: "#^Method Ibexa\\\\Bundle\\\\Core\\\\Matcher\\\\ServiceAwareMatcherFactory\\:\\:getMatcher\\(\\) should return Ibexa\\\\Core\\\\MVC\\\\Symfony\\\\Matcher\\\\ContentBased\\\\MatcherInterface but returns Ibexa\\\\Core\\\\MVC\\\\Symfony\\\\Matcher\\\\ViewMatcherInterface\\.$#"
count: 2
path: src/bundle/Core/Matcher/ServiceAwareMatcherFactory.php

-
message: "#^Method Ibexa\\\\Bundle\\\\Core\\\\Routing\\\\DefaultRouter\\:\\:generate\\(\\) has parameter \\$name with no type specified\\.$#"
count: 1
Expand Down Expand Up @@ -11890,11 +11880,6 @@ parameters:
count: 1
path: src/lib/MVC/Symfony/Matcher/ClassNameMatcherFactory.php

-
message: "#^Method Ibexa\\\\Core\\\\MVC\\\\Symfony\\\\Matcher\\\\ClassNameMatcherFactory\\:\\:__construct\\(\\) has parameter \\$relativeNamespace with no type specified\\.$#"
count: 1
path: src/lib/MVC/Symfony/Matcher/ClassNameMatcherFactory.php

-
message: "#^Method Ibexa\\\\Core\\\\MVC\\\\Symfony\\\\Matcher\\\\ClassNameMatcherFactory\\:\\:getMatcher\\(\\) should return Ibexa\\\\Core\\\\MVC\\\\Symfony\\\\Matcher\\\\ViewMatcherInterface but returns object\\.$#"
count: 1
Expand Down Expand Up @@ -26250,11 +26235,6 @@ parameters:
count: 1
path: tests/bundle/Core/Imagine/VariationPurger/LegacyStorageImageFileListTest.php

-
message: "#^Parameter \\#1 \\$matchers of class Ibexa\\\\Bundle\\\\Core\\\\Matcher\\\\ViewMatcherRegistry constructor expects array\\<Ibexa\\\\Core\\\\MVC\\\\Symfony\\\\Matcher\\\\ViewMatcherInterface\\>, array\\<int, Ibexa\\\\Core\\\\MVC\\\\Symfony\\\\Matcher\\\\ContentBased\\\\MatcherInterface\\|string\\> given\\.$#"
count: 1
path: tests/bundle/Core/Matcher/ViewMatcherRegistryTest.php

-
message: "#^Cannot access offset 'path' on array\\{scheme\\?\\: string, host\\?\\: string, port\\?\\: int\\<0, 65535\\>, user\\?\\: string, pass\\?\\: string, path\\?\\: string, query\\?\\: string, fragment\\?\\: string\\}\\|false\\.$#"
count: 2
Expand Down

This file was deleted.

2 changes: 0 additions & 2 deletions src/bundle/Core/IbexaCoreBundle.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@
use Ibexa\Bundle\Core\DependencyInjection\Compiler\StorageConnectionPass;
use Ibexa\Bundle\Core\DependencyInjection\Compiler\TranslationCollectorPass;
use Ibexa\Bundle\Core\DependencyInjection\Compiler\URLHandlerPass;
use Ibexa\Bundle\Core\DependencyInjection\Compiler\ViewMatcherRegistryPass;
use Ibexa\Bundle\Core\DependencyInjection\Compiler\ViewProvidersPass;
use Ibexa\Bundle\Core\DependencyInjection\Configuration\ComplexSettings\ComplexSettingParser;
use Ibexa\Bundle\Core\DependencyInjection\Configuration\Parser as ConfigParser;
Expand Down Expand Up @@ -78,7 +77,6 @@ public function build(ContainerBuilder $container)
$container->addCompilerPass(new PlaceholderProviderPass());
$container->addCompilerPass(new NotificationRendererPass());
$container->addCompilerPass(new ConsoleCacheWarmupPass());
$container->addCompilerPass(new ViewMatcherRegistryPass());
$container->addCompilerPass(new SiteAccessMatcherRegistryPass());
$container->addCompilerPass(new ConsoleCommandPass());
$container->addCompilerPass(new LazyDoctrineRepositoriesPass(), PassConfig::TYPE_BEFORE_REMOVING);
Expand Down
24 changes: 12 additions & 12 deletions src/bundle/Core/Matcher/ServiceAwareMatcherFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,24 +6,26 @@
*/
namespace Ibexa\Bundle\Core\Matcher;

use Ibexa\Contracts\Core\MVC\View\ViewMatcherRegistryInterface;
use Ibexa\Contracts\Core\Repository\Repository;
use Ibexa\Core\MVC\Symfony\Matcher\ClassNameMatcherFactory;
use Ibexa\Core\MVC\Symfony\Matcher\ViewMatcherInterface;

/**
* A view matcher factory that also accepts services as matchers.
*
* If a service id is passed as the MatcherIdentifier, this service will be used for the matching.
* Otherwise, it will fallback to the class name based matcher factory.
* If a view matcher service is registered with `identifier` attribute, that service will be used for matching. *
* Otherwise, it will fall back to the class name-based matcher factory.
*/
final class ServiceAwareMatcherFactory extends ClassNameMatcherFactory
{
/** @var \Ibexa\Bundle\Core\Matcher\ViewMatcherRegistry */
private $viewMatcherRegistry;
private ViewMatcherRegistryInterface $viewMatcherRegistry;

public function __construct(
ViewMatcherRegistry $viewMatcherRegistry,
ViewMatcherRegistryInterface $viewMatcherRegistry,
Repository $repository,
$relativeNamespace = null,
?string $relativeNamespace = null,
array $matchConfig = []
) {
$this->viewMatcherRegistry = $viewMatcherRegistry;
Expand All @@ -33,18 +35,16 @@ public function __construct(

/**
* @param string $matcherIdentifier
*
* @return \Ibexa\Core\MVC\Symfony\Matcher\ContentBased\MatcherInterface
*
* @throws \Ibexa\Contracts\Core\Repository\Exceptions\NotFoundException
*/
protected function getMatcher($matcherIdentifier)
protected function getMatcher($matcherIdentifier): ViewMatcherInterface
{
if (strpos($matcherIdentifier, '@') === 0) {
return $this->viewMatcherRegistry->getMatcher(substr($matcherIdentifier, 1));
$matcherIdentifier = substr($matcherIdentifier, 1);
}

return parent::getMatcher($matcherIdentifier);
return $this->viewMatcherRegistry->hasMatcher($matcherIdentifier)
? $this->viewMatcherRegistry->getMatcher($matcherIdentifier)
: parent::getMatcher($matcherIdentifier);
}
}

Expand Down
20 changes: 16 additions & 4 deletions src/bundle/Core/Matcher/ViewMatcherRegistry.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,27 @@

namespace Ibexa\Bundle\Core\Matcher;

use Ibexa\Contracts\Core\MVC\View\ViewMatcherRegistryInterface;
use Ibexa\Core\Base\Exceptions\NotFoundException;
use Ibexa\Core\MVC\Symfony\Matcher\ViewMatcherInterface;

final class ViewMatcherRegistry
/**
* @internal
*/
final class ViewMatcherRegistry implements ViewMatcherRegistryInterface
{
/** @var \Ibexa\Core\MVC\Symfony\Matcher\ViewMatcherInterface[] */
private $matchers;

/**
* @param \Ibexa\Core\MVC\Symfony\Matcher\ViewMatcherInterface[] $matchers
* @param iterable<\Ibexa\Core\MVC\Symfony\Matcher\ViewMatcherInterface> $matchers
*/
public function __construct(array $matchers = [])
public function __construct(iterable $matchers = [])
{
$this->matchers = $matchers;
$this->matchers = [];
foreach ($matchers as $identifier => $matcher) {
$this->matchers[$identifier] = $matcher;
}
}

public function setMatcher(string $matcherIdentifier, ViewMatcherInterface $matcher): void
Expand All @@ -44,6 +51,11 @@ public function getMatcher(string $matcherIdentifier): ViewMatcherInterface

return $this->matchers[$matcherIdentifier];
}

public function hasMatcher(string $matcherIdentifier): bool
{
return isset($this->matchers[$matcherIdentifier]);
}
}

class_alias(ViewMatcherRegistry::class, 'eZ\Bundle\EzPublishCoreBundle\Matcher\ViewMatcherRegistry');
17 changes: 11 additions & 6 deletions src/bundle/Core/Resources/config/templating.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,12 @@ services:
- '@Ibexa\Core\MVC\Symfony\View\Configurator\ViewProvider'
- "@?logger"

Ibexa\Bundle\Core\Matcher\ViewMatcherRegistry: ~
Ibexa\Contracts\Core\MVC\View\ViewMatcherRegistryInterface:
alias: Ibexa\Bundle\Core\Matcher\ViewMatcherRegistry

Ibexa\Bundle\Core\Matcher\ViewMatcherRegistry:
arguments:
$matchers: !tagged_iterator { tag: 'ibexa.view.matcher', index_by: identifier }

ibexa.content_view_provider.configured:
class: Ibexa\Bundle\Core\View\Provider\Configured
Expand All @@ -40,7 +45,7 @@ services:
ibexa.content_view.matcher_factory:
class: Ibexa\Bundle\Core\Matcher\ServiceAwareMatcherFactory
arguments:
- '@Ibexa\Bundle\Core\Matcher\ViewMatcherRegistry'
- '@Ibexa\Contracts\Core\MVC\View\ViewMatcherRegistryInterface'
- '@ibexa.api.repository'
- 'Ibexa\Core\MVC\Symfony\Matcher\ContentBased'

Expand All @@ -61,7 +66,7 @@ services:
ibexa.content_view.default_matcher_factory:
class: Ibexa\Bundle\Core\Matcher\ServiceAwareMatcherFactory
arguments:
- '@Ibexa\Bundle\Core\Matcher\ViewMatcherRegistry'
- '@Ibexa\Contracts\Core\MVC\View\ViewMatcherRegistryInterface'
- '@ibexa.api.repository'
- 'Ibexa\Core\MVC\Symfony\Matcher\ContentBased'

Expand All @@ -82,9 +87,9 @@ services:
ibexa.location_view.matcher_factory:
class: Ibexa\Bundle\Core\Matcher\ServiceAwareMatcherFactory
arguments:
- '@Ibexa\Bundle\Core\Matcher\ViewMatcherRegistry'
- '@ibexa.api.repository'
- 'Ibexa\Core\MVC\Symfony\Matcher\ContentBased'
$viewMatcherRegistry: '@Ibexa\Contracts\Core\MVC\View\ViewMatcherRegistryInterface'
$repository: '@ibexa.api.repository'
$relativeNamespace: 'Ibexa\Core\MVC\Symfony\Matcher\ContentBased'

ibexa.location_view.matcher_factory.dynamically_configured:
class: Ibexa\Core\MVC\Symfony\Matcher\DynamicallyConfiguredMatcherFactoryDecorator
Expand Down
20 changes: 20 additions & 0 deletions src/contracts/MVC/View/ViewMatcherRegistryInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

/**
* @copyright Copyright (C) Ibexa AS. All rights reserved.
* @license For full copyright and license information view LICENSE file distributed with this source code.
*/
declare(strict_types=1);

namespace Ibexa\Contracts\Core\MVC\View;

use Ibexa\Core\MVC\Symfony\Matcher\ViewMatcherInterface;

interface ViewMatcherRegistryInterface
{
public function setMatcher(string $matcherIdentifier, ViewMatcherInterface $matcher): void;

public function getMatcher(string $matcherIdentifier): ViewMatcherInterface;

public function hasMatcher(string $matcherIdentifier): bool;
}
6 changes: 2 additions & 4 deletions src/lib/MVC/Symfony/Matcher/ClassNameMatcherFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,8 @@ class ClassNameMatcherFactory implements ConfigurableMatcherFactoryInterface

/**
* Namespace built-in matchers are relative to.
*
* @var string
*/
protected $matcherRelativeNamespace;
protected ?string $matcherRelativeNamespace;

/**
* Already matched value objects with their config hash.
Expand All @@ -49,7 +47,7 @@ class ClassNameMatcherFactory implements ConfigurableMatcherFactoryInterface
*/
protected $alreadyMatched = [];

public function __construct(Repository $repository, $relativeNamespace = null, array $matchConfig = [])
public function __construct(Repository $repository, ?string $relativeNamespace = null, array $matchConfig = [])
{
$this->repository = $repository;
$this->matcherRelativeNamespace = $relativeNamespace;
Expand Down

This file was deleted.

Loading
Loading