Skip to content

Commit 3bc4e4f

Browse files
feature #33122 [WebLink] implement PSR-13 directly (nicolas-grekas)
This PR was merged into the 4.4 branch. Discussion ---------- [WebLink] implement PSR-13 directly | Q | A | ------------- | --- | Branch? | 4.4 | Bug fix? | no | New feature? | yes | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | - | License | MIT | Doc PR | - Implementing PSR-13 is simple enough and the repo we're using is [freezed](https://github.com/php-fig/link-util/pulls). This also allows us to add some type declarations. We're going to need them before merging #30323. Commits ------- b570ee1 [WebLink] implement PSR-13 directly
2 parents 1aa41ed + b570ee1 commit 3bc4e4f

File tree

15 files changed

+454
-16
lines changed

15 files changed

+454
-16
lines changed

composer.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@
2020
"ext-xml": "*",
2121
"doctrine/event-manager": "~1.0",
2222
"doctrine/persistence": "~1.0",
23-
"fig/link-util": "^1.0",
2423
"twig/twig": "^1.41|^2.10",
2524
"psr/cache": "~1.0",
2625
"psr/container": "^1.0",

src/Symfony/Bridge/Twig/Extension/WebLinkExtension.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@
1111

1212
namespace Symfony\Bridge\Twig\Extension;
1313

14-
use Fig\Link\GenericLinkProvider;
15-
use Fig\Link\Link;
1614
use Symfony\Component\HttpFoundation\RequestStack;
15+
use Symfony\Component\WebLink\GenericLinkProvider;
16+
use Symfony\Component\WebLink\Link;
1717
use Twig\Extension\AbstractExtension;
1818
use Twig\TwigFunction;
1919

src/Symfony/Bridge/Twig/Tests/Extension/WebLinkExtensionTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,11 @@
1111

1212
namespace Symfony\Bridge\Twig\Tests\Extension;
1313

14-
use Fig\Link\Link;
1514
use PHPUnit\Framework\TestCase;
1615
use Symfony\Bridge\Twig\Extension\WebLinkExtension;
1716
use Symfony\Component\HttpFoundation\Request;
1817
use Symfony\Component\HttpFoundation\RequestStack;
18+
use Symfony\Component\WebLink\Link;
1919

2020
/**
2121
* @author Kévin Dunglas <dunglas@gmail.com>

src/Symfony/Bridge/Twig/composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@
4242
"symfony/console": "^3.4|^4.0|^5.0",
4343
"symfony/var-dumper": "^3.4|^4.0|^5.0",
4444
"symfony/expression-language": "^3.4|^4.0|^5.0",
45-
"symfony/web-link": "^3.4|^4.0|^5.0",
45+
"symfony/web-link": "^4.4|^5.0",
4646
"symfony/workflow": "^4.3|^5.0"
4747
},
4848
"conflict": {

src/Symfony/Bundle/FrameworkBundle/Controller/ControllerTrait.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,8 @@
1212
namespace Symfony\Bundle\FrameworkBundle\Controller;
1313

1414
use Doctrine\Common\Persistence\ManagerRegistry;
15-
use Fig\Link\GenericLinkProvider;
16-
use Fig\Link\Link;
1715
use Psr\Container\ContainerInterface;
16+
use Psr\Link\LinkInterface;
1817
use Symfony\Component\Form\Extension\Core\Type\FormType;
1918
use Symfony\Component\Form\FormBuilderInterface;
2019
use Symfony\Component\Form\FormInterface;
@@ -33,6 +32,7 @@
3332
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
3433
use Symfony\Component\Security\Csrf\CsrfToken;
3534
use Symfony\Component\WebLink\EventListener\AddLinkHeaderListener;
35+
use Symfony\Component\WebLink\GenericLinkProvider;
3636

3737
/**
3838
* Common features needed in controllers.
@@ -420,7 +420,7 @@ protected function dispatchMessage($message, array $stamps = []): Envelope
420420
*
421421
* @final
422422
*/
423-
protected function addLink(Request $request, Link $link)
423+
protected function addLink(Request $request, LinkInterface $link)
424424
{
425425
if (!class_exists(AddLinkHeaderListener::class)) {
426426
throw new \LogicException('You can not use the "addLink" method if the WebLink component is not available. Try running "composer require symfony/web-link".');

src/Symfony/Bundle/FrameworkBundle/Tests/Controller/ControllerTraitTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111

1212
namespace Symfony\Bundle\FrameworkBundle\Tests\Controller;
1313

14-
use Fig\Link\Link;
1514
use Symfony\Bundle\FrameworkBundle\Controller\ControllerTrait;
1615
use Symfony\Bundle\FrameworkBundle\Tests\TestCase;
1716
use Symfony\Component\DependencyInjection\Container;
@@ -29,6 +28,7 @@
2928
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
3029
use Symfony\Component\Security\Core\User\User;
3130
use Symfony\Component\Serializer\SerializerInterface;
31+
use Symfony\Component\WebLink\Link;
3232

3333
abstract class ControllerTraitTest extends TestCase
3434
{

src/Symfony/Bundle/FrameworkBundle/composer.json

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@
3131
},
3232
"require-dev": {
3333
"doctrine/cache": "~1.0",
34-
"fig/link-util": "^1.0",
3534
"symfony/asset": "^3.4|^4.0|^5.0",
3635
"symfony/browser-kit": "^4.3|^5.0",
3736
"symfony/console": "^4.3|^5.0",
@@ -58,7 +57,7 @@
5857
"symfony/workflow": "^4.3|^5.0",
5958
"symfony/yaml": "^3.4|^4.0|^5.0",
6059
"symfony/property-info": "^3.4|^4.0|^5.0",
61-
"symfony/web-link": "^3.4|^4.0|^5.0",
60+
"symfony/web-link": "^4.4|^5.0",
6261
"doctrine/annotations": "~1.0",
6362
"phpdocumentor/reflection-docblock": "^3.0|^4.0",
6463
"twig/twig": "~1.34|~2.4"

src/Symfony/Component/WebLink/CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,11 @@
11
CHANGELOG
22
=========
33

4+
4.4.0
5+
-----
6+
7+
* implement PSR-13 directly
8+
49
3.3.0
510
-----
611

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\WebLink;
13+
14+
use Psr\Link\EvolvableLinkProviderInterface;
15+
use Psr\Link\LinkInterface;
16+
17+
class GenericLinkProvider implements EvolvableLinkProviderInterface
18+
{
19+
/**
20+
* @var LinkInterface[]
21+
*/
22+
private $links = [];
23+
24+
/**
25+
* @param LinkInterface[] $links
26+
*/
27+
public function __construct(array $links = [])
28+
{
29+
$that = $this;
30+
31+
foreach ($links as $link) {
32+
$that = $that->withLink($link);
33+
}
34+
35+
$this->links = $that->links;
36+
}
37+
38+
/**
39+
* {@inheritdoc}
40+
*/
41+
public function getLinks(): array
42+
{
43+
return array_values($this->links);
44+
}
45+
46+
/**
47+
* {@inheritdoc}
48+
*/
49+
public function getLinksByRel($rel): array
50+
{
51+
$links = [];
52+
53+
foreach ($this->links as $link) {
54+
if (\in_array($rel, $link->getRels())) {
55+
$links[] = $link;
56+
}
57+
}
58+
59+
return $links;
60+
}
61+
62+
/**
63+
* {@inheritdoc}
64+
*/
65+
public function withLink(LinkInterface $link)
66+
{
67+
$that = clone $this;
68+
$that->links[spl_object_id($link)] = $link;
69+
70+
return $that;
71+
}
72+
73+
/**
74+
* {@inheritdoc}
75+
*/
76+
public function withoutLink(LinkInterface $link)
77+
{
78+
$that = clone $this;
79+
unset($that->links[spl_object_id($link)]);
80+
81+
return $that;
82+
}
83+
}
Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\WebLink;
13+
14+
use Psr\Link\EvolvableLinkInterface;
15+
16+
class Link implements EvolvableLinkInterface
17+
{
18+
// Relations defined in https://www.w3.org/TR/html5/links.html#links and applicable on link elements
19+
public const REL_ALTERNATE = 'alternate';
20+
public const REL_AUTHOR = 'author';
21+
public const REL_HELP = 'help';
22+
public const REL_ICON = 'icon';
23+
public const REL_LICENSE = 'license';
24+
public const REL_SEARCH = 'search';
25+
public const REL_STYLESHEET = 'stylesheet';
26+
public const REL_NEXT = 'next';
27+
public const REL_PREV = 'prev';
28+
29+
// Relation defined in https://www.w3.org/TR/preload/
30+
public const REL_PRELOAD = 'preload';
31+
32+
// Relations defined in https://www.w3.org/TR/resource-hints/
33+
public const REL_DNS_PREFETCH = 'dns-prefetch';
34+
public const REL_PRECONNECT = 'preconnect';
35+
public const REL_PREFETCH = 'prefetch';
36+
public const REL_PRERENDER = 'prerender';
37+
38+
// Extra relations
39+
public const REL_MERCURE = 'mercure';
40+
41+
private $href = '';
42+
43+
/**
44+
* @var string[]
45+
*/
46+
private $rel = [];
47+
48+
/**
49+
* @var string[]
50+
*/
51+
private $attributes = [];
52+
53+
public function __construct(string $rel = null, string $href = '')
54+
{
55+
if (null !== $rel) {
56+
$this->rel[$rel] = $rel;
57+
}
58+
$this->href = $href;
59+
}
60+
61+
/**
62+
* {@inheritdoc}
63+
*/
64+
public function getHref(): string
65+
{
66+
return $this->href;
67+
}
68+
69+
/**
70+
* {@inheritdoc}
71+
*/
72+
public function isTemplated(): bool
73+
{
74+
return $this->hrefIsTemplated($this->href);
75+
}
76+
77+
/**
78+
* {@inheritdoc}
79+
*/
80+
public function getRels(): array
81+
{
82+
return array_values($this->rel);
83+
}
84+
85+
/**
86+
* {@inheritdoc}
87+
*/
88+
public function getAttributes(): array
89+
{
90+
return $this->attributes;
91+
}
92+
93+
/**
94+
* {@inheritdoc}
95+
*/
96+
public function withHref($href)
97+
{
98+
$that = clone $this;
99+
$that->href = $href;
100+
$that->templated = $this->hrefIsTemplated($href);
101+
102+
return $that;
103+
}
104+
105+
/**
106+
* {@inheritdoc}
107+
*/
108+
public function withRel($rel)
109+
{
110+
$that = clone $this;
111+
$that->rel[$rel] = $rel;
112+
113+
return $that;
114+
}
115+
116+
/**
117+
* {@inheritdoc}
118+
*/
119+
public function withoutRel($rel)
120+
{
121+
$that = clone $this;
122+
unset($that->rel[$rel]);
123+
124+
return $that;
125+
}
126+
127+
/**
128+
* {@inheritdoc}
129+
*/
130+
public function withAttribute($attribute, $value)
131+
{
132+
$that = clone $this;
133+
$that->attributes[$attribute] = $value;
134+
135+
return $that;
136+
}
137+
138+
/**
139+
* {@inheritdoc}
140+
*/
141+
public function withoutAttribute($attribute)
142+
{
143+
$that = clone $this;
144+
unset($that->attributes[$attribute]);
145+
146+
return $that;
147+
}
148+
149+
private function hrefIsTemplated(string $href): bool
150+
{
151+
return false !== strpos($href, '{') || false !== strpos($href, '}');
152+
}
153+
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy