Skip to content

Commit 0f5b958

Browse files
committed
Add canonical URL generator
1 parent d0a7063 commit 0f5b958

File tree

8 files changed

+156
-1
lines changed

8 files changed

+156
-1
lines changed

src/Controller/Action/SearchAction.php

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
use Setono\SyliusMeilisearchPlugin\Engine\SearchEngineInterface;
1111
use Setono\SyliusMeilisearchPlugin\Engine\SearchRequest;
1212
use Setono\SyliusMeilisearchPlugin\Event\Search\SearchRequestCreated;
13+
use Setono\SyliusMeilisearchPlugin\Event\Search\SearchResponseCreated;
1314
use Setono\SyliusMeilisearchPlugin\Event\Search\SearchResponseParametersCreated;
1415
use Setono\SyliusMeilisearchPlugin\Event\Search\SearchResultReceived;
1516
use Setono\SyliusMeilisearchPlugin\Form\Builder\SearchFormBuilderInterface;
@@ -68,6 +69,15 @@ public function __invoke(Request $request): Response
6869

6970
$this->eventDispatcher->dispatch($searchResponseParametersCreatedEvent);
7071

71-
return new Response($this->twig->render($searchResponseParametersCreatedEvent->template, $searchResponseParametersCreatedEvent->context));
72+
$response = new Response(
73+
$this->twig->render(
74+
$searchResponseParametersCreatedEvent->template,
75+
$searchResponseParametersCreatedEvent->context
76+
)
77+
);
78+
79+
$this->eventDispatcher->dispatch(new SearchResponseCreated($request, $response));
80+
81+
return $response;
7282
}
7383
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Setono\SyliusMeilisearchPlugin\Event\Search;
6+
7+
use Symfony\Component\HttpFoundation\Request;
8+
use Symfony\Component\HttpFoundation\Response;
9+
10+
final class SearchResponseCreated
11+
{
12+
public function __construct(
13+
public readonly Request $request,
14+
public readonly Response $response
15+
) {
16+
}
17+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Setono\SyliusMeilisearchPlugin\EventSubscriber\Search;
6+
7+
use Setono\SyliusMeilisearchPlugin\Event\Search\SearchResponseCreated;
8+
use Setono\SyliusMeilisearchPlugin\UrlGenerator\CanonicalUrlGeneratorInterface;
9+
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
10+
use Symfony\Component\WebLink\GenericLinkProvider;
11+
use Symfony\Component\WebLink\Link;
12+
13+
final class CanonicalUrlSubscriber implements EventSubscriberInterface
14+
{
15+
public function __construct(
16+
private readonly CanonicalUrlGeneratorInterface $canonicalUrlGenerator
17+
) {
18+
}
19+
20+
public static function getSubscribedEvents(): array
21+
{
22+
return [
23+
SearchResponseCreated::class => 'onSearchResponseCreated',
24+
];
25+
}
26+
27+
public function onSearchResponseCreated(SearchResponseCreated $event): void
28+
{
29+
$link = new Link(Link::REL_CANONICAL, $this->canonicalUrlGenerator->generate($event->request));
30+
31+
if (null === $linkProvider = $event->request->attributes->get('_links')) {
32+
$event->request->attributes->set('_links', new GenericLinkProvider([$link]));
33+
34+
return;
35+
}
36+
37+
$event->request->attributes->set('_links', $linkProvider->withLink($link));
38+
}
39+
}

src/Resources/config/services/event_subscriber.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,5 +12,11 @@
1212

1313
<tag name="kernel.event_subscriber"/>
1414
</service>
15+
16+
<service id="Setono\SyliusMeilisearchPlugin\EventSubscriber\Search\CanonicalUrlSubscriber">
17+
<argument type="service" id="Setono\SyliusMeilisearchPlugin\UrlGenerator\CanonicalUrlGeneratorInterface"/>
18+
19+
<tag name="kernel.event_subscriber"/>
20+
</service>
1521
</services>
1622
</container>

src/Resources/config/services/url_generator.xml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,5 +21,12 @@
2121

2222
<tag name="setono_sylius_meilisearch.url_generator"/>
2323
</service>
24+
25+
<service id="Setono\SyliusMeilisearchPlugin\UrlGenerator\CanonicalUrlGeneratorInterface"
26+
alias="setono_sylius_meilisearch.canonical_url_generator"/>
27+
<service id="setono_sylius_meilisearch.canonical_url_generator"
28+
class="Setono\SyliusMeilisearchPlugin\UrlGenerator\CanonicalUrlGenerator">
29+
<argument type="service" id="router"/>
30+
</service>
2431
</services>
2532
</container>
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Setono\SyliusMeilisearchPlugin\UrlGenerator;
6+
7+
use Symfony\Component\HttpFoundation\Request;
8+
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
9+
10+
final class CanonicalUrlGenerator implements CanonicalUrlGeneratorInterface
11+
{
12+
public function __construct(
13+
private readonly UrlGeneratorInterface $urlGenerator,
14+
) {
15+
}
16+
17+
public function generate(Request $request, array $parameters = []): string
18+
{
19+
$routeName = $request->attributes->get('_route');
20+
21+
if (null === $routeName) {
22+
return $request->getUri();
23+
}
24+
25+
return $this->urlGenerator->generate(
26+
$routeName,
27+
array_merge($request->attributes->get('_route_params', []), $parameters),
28+
UrlGeneratorInterface::ABSOLUTE_URL
29+
);
30+
}
31+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Setono\SyliusMeilisearchPlugin\UrlGenerator;
6+
7+
use Symfony\Component\HttpFoundation\Request;
8+
9+
interface CanonicalUrlGeneratorInterface
10+
{
11+
public function generate(Request $request, array $parameters = []): string;
12+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Setono\SyliusMeilisearchPlugin\Tests\Unit\UrlGenerator;
6+
7+
use Setono\SyliusMeilisearchPlugin\UrlGenerator\CanonicalUrlGenerator;
8+
use PHPUnit\Framework\TestCase;
9+
use Symfony\Component\HttpFoundation\Request;
10+
use Symfony\Component\Routing\Generator\UrlGenerator;
11+
use Symfony\Component\Routing\RequestContext;
12+
use Symfony\Component\Routing\Route;
13+
use Symfony\Component\Routing\RouteCollection;
14+
15+
class CanonicalUrlGeneratorTest extends TestCase
16+
{
17+
public function testGenerate(): void
18+
{
19+
$routes = new RouteCollection();
20+
$routes->add('test_route', new Route('/test/{param1}'));
21+
$context = new RequestContext(host: 'example.com', scheme: 'https');
22+
$urlGenerator = new UrlGenerator($routes, $context);
23+
$canonicalUrlGenerator = new CanonicalUrlGenerator($urlGenerator);
24+
25+
$request = Request::create('https://example.com/test/value1?param2=value2#fragment');
26+
$request->attributes->set('_route', 'test_route');
27+
$request->attributes->set('_route_params', ['param1' => 'value1']);
28+
29+
$result = $canonicalUrlGenerator->generate($request);
30+
31+
self::assertSame('https://example.com/test/value1', $result);
32+
}
33+
}

0 commit comments

Comments
 (0)