From 2db153f3fb0fe1e755d1d4d89ccab4b3b71c108b Mon Sep 17 00:00:00 2001 From: Adrien Dupuis Date: Mon, 5 Feb 2024 11:55:39 +0100 Subject: [PATCH 1/5] create_custom_view_matcher.md: give an identifier to the matcher --- .../view_matcher/config/packages/views.yaml | 3 ++- .../front/view_matcher/config/services.yaml | 5 +++++ .../templates/create_custom_view_matcher.md | 17 +++++++++++++++-- 3 files changed, 22 insertions(+), 3 deletions(-) create mode 100644 code_samples/front/view_matcher/config/services.yaml diff --git a/code_samples/front/view_matcher/config/packages/views.yaml b/code_samples/front/view_matcher/config/packages/views.yaml index 24eee9d90f..b4af7ea127 100644 --- a/code_samples/front/view_matcher/config/packages/views.yaml +++ b/code_samples/front/view_matcher/config/packages/views.yaml @@ -12,4 +12,5 @@ ibexa: template: '@ibexadesign/full/featured_article.html.twig' match: Identifier\ContentType: article - \App\View\Matcher\Owner: [johndoe, janedoe] + #\App\View\Matcher\Owner: [johndoe, janedoe] + App\Owner: [johndoe, janedoe] diff --git a/code_samples/front/view_matcher/config/services.yaml b/code_samples/front/view_matcher/config/services.yaml new file mode 100644 index 0000000000..7eaa52ae83 --- /dev/null +++ b/code_samples/front/view_matcher/config/services.yaml @@ -0,0 +1,5 @@ +services: + App\View\Matcher\Owner: + autowire: true + tags: + - { name: ibexa.view.matcher, identifier: App\Owner } diff --git a/docs/templating/templates/create_custom_view_matcher.md b/docs/templating/templates/create_custom_view_matcher.md index cafd380c74..0c7b47646a 100644 --- a/docs/templating/templates/create_custom_view_matcher.md +++ b/docs/templating/templates/create_custom_view_matcher.md @@ -27,11 +27,24 @@ This matcher identifies Content items that have the provided owner or owners. The matcher checks whether the owner of the current content (by its ContentInfo or Location) matches any of the values passed in configuration (line 44). +## Matcher service + +You can configure your matcher as a service to have the opportunity to give him a matcher identifier easier to use than its fully qualified class name. +A matcher identifier is associated to its service using the `ibexa.view.matcher` tag as follows: + +``` yaml +[[= include_file('code_samples/front/view_matcher/config/services.yaml') =]] +``` + ## View configuration -To apply the matcher in view configuration, indicate the matcher by its fully qualified class name, preceded by `\`. +To apply the matcher in view configuration, indicate the matcher + +- by its fully qualified class name (FQCN) preceded by `\`, +- or by its identifier. -The following configuration uses a special template to render articles owned by the users with provided logins: +The following configuration uses a special template to render articles owned by the users with provided logins +(the FQCN as been commented to prefer its identifier): ``` yaml [[= include_file('code_samples/front/view_matcher/config/packages/views.yaml') =]] From 0f193a51ce7b83397063c66e051928f440f9e648 Mon Sep 17 00:00:00 2001 From: Adrien Dupuis Date: Mon, 5 Feb 2024 12:13:39 +0100 Subject: [PATCH 2/5] create_custom_view_matcher.md: Update example, introduce setMatchingConfig --- .../view_matcher/src/View/Matcher/Owner.php | 50 +++++++++++++++---- .../templates/create_custom_view_matcher.md | 1 + 2 files changed, 41 insertions(+), 10 deletions(-) diff --git a/code_samples/front/view_matcher/src/View/Matcher/Owner.php b/code_samples/front/view_matcher/src/View/Matcher/Owner.php index 329f0d82bd..106d55bcd7 100644 --- a/code_samples/front/view_matcher/src/View/Matcher/Owner.php +++ b/code_samples/front/view_matcher/src/View/Matcher/Owner.php @@ -2,29 +2,48 @@ namespace App\View\Matcher; +use Ibexa\Contracts\Core\Repository\UserService; use Ibexa\Contracts\Core\Repository\Values\Content\ContentInfo; use Ibexa\Contracts\Core\Repository\Values\Content\Location; -use Ibexa\Core\MVC\Symfony\Matcher\ContentBased\MultipleValued; +use Ibexa\Core\MVC\Symfony\Matcher\ContentBased\MatcherInterface; use Ibexa\Core\MVC\Symfony\View\ContentValueView; use Ibexa\Core\MVC\Symfony\View\LocationValueView; use Ibexa\Core\MVC\Symfony\View\View; +use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; -class Owner extends MultipleValued +class Owner implements MatcherInterface { - public function matchLocation(Location $location) + private UserService $userService; + + /** @var string[] */ + private array $matchingUserLogins; + + public function __construct(UserService $userService) + { + $this->userService = $userService; + } + + /** + * @throws \Ibexa\Contracts\Core\Repository\Exceptions\NotFoundException + */ + public function matchLocation(Location $location): bool { return $this->hasOwner($location->getContentInfo()); } - public function matchContentInfo(ContentInfo $contentInfo) + /** + * @throws \Ibexa\Contracts\Core\Repository\Exceptions\NotFoundException + */ + public function matchContentInfo(ContentInfo $contentInfo): bool { return $this->hasOwner($contentInfo); } + /** + * @throws \Ibexa\Contracts\Core\Repository\Exceptions\NotFoundException + */ public function match(View $view): ?bool { - $location = null; - if ($view instanceof LocationValueView) { return $this->matchLocation($view->getLocation()); } @@ -36,14 +55,25 @@ public function match(View $view): ?bool return false; } + /** + * @throws \Ibexa\Contracts\Core\Repository\Exceptions\NotFoundException + */ private function hasOwner(ContentInfo $contentInfo): bool { - $owner = $this->getRepository()->getUserService()->loadUser($contentInfo->ownerId); + $owner = $this->userService->loadUser($contentInfo->ownerId); + + return in_array($owner->login, $this->matchingUserLogins, true); + } - if (\array_key_exists($owner->login, $this->values)) { - return true; + /** + * @param array $matchingConfig + */ + public function setMatchingConfig($matchingConfig): void + { + if (!is_array($matchingConfig)) { + throw new InvalidArgumentException('App\Owner view matcher configuration has to be an array'); } - return false; + $this->matchingUserLogins = $matchingConfig; } } diff --git a/docs/templating/templates/create_custom_view_matcher.md b/docs/templating/templates/create_custom_view_matcher.md index 0c7b47646a..bae0c6596f 100644 --- a/docs/templating/templates/create_custom_view_matcher.md +++ b/docs/templating/templates/create_custom_view_matcher.md @@ -16,6 +16,7 @@ The matcher class must implement the following methods: - `matchLocation` - checks if a Location object matches. - `matchContentInfo` - checks if a ContentInfo object matches. - `match` - checks if the View object matches. +- `setMatchingConfig` - receives the matcher's config from the view rule. The following example shows how to implement an `Owner` matcher. This matcher identifies Content items that have the provided owner or owners. From 9cee44f5142920a074e4f5c88702836cf6b1f591 Mon Sep 17 00:00:00 2001 From: Adrien Dupuis Date: Mon, 5 Feb 2024 12:15:05 +0100 Subject: [PATCH 3/5] create_custom_view_matcher.md: Update example, introduce MatcherInterface --- docs/templating/templates/create_custom_view_matcher.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/templating/templates/create_custom_view_matcher.md b/docs/templating/templates/create_custom_view_matcher.md index bae0c6596f..da72895af7 100644 --- a/docs/templating/templates/create_custom_view_matcher.md +++ b/docs/templating/templates/create_custom_view_matcher.md @@ -7,7 +7,7 @@ description: You can create custom view matchers to configure template and contr In addition to the [built-in view matchers](view_matcher_reference.md), you can also create custom matchers to use in [template configuration](template_configuration.md#view-rules-and-matching). -To do it, create a matcher class that extends `Ibexa\Core\MVC\Symfony\Matcher\ContentBased\MultipleValued`. +To do it, create a matcher class that implements `Ibexa\Core\MVC\Symfony\Matcher\ContentBased\MatcherInterface`. ## Matcher class From 979e0f21adae56518d5e66f8a612c15eeeabfbbf Mon Sep 17 00:00:00 2001 From: Adrien Dupuis Date: Mon, 5 Feb 2024 12:47:51 +0100 Subject: [PATCH 4/5] create_custom_view_matcher.md: Rm FQCN, fix hl_lines --- .../front/view_matcher/config/packages/views.yaml | 1 - .../templates/create_custom_view_matcher.md | 15 +++++---------- 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/code_samples/front/view_matcher/config/packages/views.yaml b/code_samples/front/view_matcher/config/packages/views.yaml index b4af7ea127..6ab0dd583b 100644 --- a/code_samples/front/view_matcher/config/packages/views.yaml +++ b/code_samples/front/view_matcher/config/packages/views.yaml @@ -12,5 +12,4 @@ ibexa: template: '@ibexadesign/full/featured_article.html.twig' match: Identifier\ContentType: article - #\App\View\Matcher\Owner: [johndoe, janedoe] App\Owner: [johndoe, janedoe] diff --git a/docs/templating/templates/create_custom_view_matcher.md b/docs/templating/templates/create_custom_view_matcher.md index da72895af7..f61c84ff1a 100644 --- a/docs/templating/templates/create_custom_view_matcher.md +++ b/docs/templating/templates/create_custom_view_matcher.md @@ -21,7 +21,7 @@ The matcher class must implement the following methods: The following example shows how to implement an `Owner` matcher. This matcher identifies Content items that have the provided owner or owners. -``` php hl_lines="44" +``` php hl_lines="65" [[= include_file('code_samples/front/view_matcher/src/View/Matcher/Owner.php') =]] ``` @@ -30,8 +30,7 @@ matches any of the values passed in configuration (line 44). ## Matcher service -You can configure your matcher as a service to have the opportunity to give him a matcher identifier easier to use than its fully qualified class name. -A matcher identifier is associated to its service using the `ibexa.view.matcher` tag as follows: +You configure your matcher as a service, tag it `ibexa.view.matcher`, and associate it with the identifier to use in view rules: ``` yaml [[= include_file('code_samples/front/view_matcher/config/services.yaml') =]] @@ -39,15 +38,11 @@ A matcher identifier is associated to its service using the `ibexa.view.matcher` ## View configuration -To apply the matcher in view configuration, indicate the matcher +To apply the matcher in view configuration, indicate the matcher by its identifier. -- by its fully qualified class name (FQCN) preceded by `\`, -- or by its identifier. +The following configuration uses a special template to render articles owned by the users with provided logins: -The following configuration uses a special template to render articles owned by the users with provided logins -(the FQCN as been commented to prefer its identifier): - -``` yaml +``` yaml hl_lines="15" [[= include_file('code_samples/front/view_matcher/config/packages/views.yaml') =]] ``` From 6de3c2d5720e206b29993cd8fd8ffb5c5d9706b4 Mon Sep 17 00:00:00 2001 From: Adrien Dupuis Date: Mon, 5 Feb 2024 12:50:40 +0100 Subject: [PATCH 5/5] create_custom_view_matcher.md: Rm in-text line number It's already highlighted, and it's too easy to forget to update this number. --- docs/templating/templates/create_custom_view_matcher.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/templating/templates/create_custom_view_matcher.md b/docs/templating/templates/create_custom_view_matcher.md index f61c84ff1a..c947eec063 100644 --- a/docs/templating/templates/create_custom_view_matcher.md +++ b/docs/templating/templates/create_custom_view_matcher.md @@ -26,7 +26,7 @@ This matcher identifies Content items that have the provided owner or owners. ``` The matcher checks whether the owner of the current content (by its ContentInfo or Location) -matches any of the values passed in configuration (line 44). +matches any of the values passed in configuration. ## Matcher service