8000 Merge branch '2.7' · symfony/symfony@30935c7 · GitHub
[go: up one dir, main page]

Skip to content

Commit 30935c7

Browse files
committed
Merge branch '2.7'
* 2.7: removed deprecation notice for internal constant removed deprecated notices when using the security service [Validator] fixed deprecation notice for ElementMetadata Revert "minor #13434 fixed some deprecated notices (fabpot)" removed usage of the deprecated EsiListener class in core [security] Fetching current stored context when not explicitly specified [FrameworkBundle] Container parameters in Route#condition Deprecated setDefaultOptions() in favor of configureOptions() Conflicts: src/Symfony/Bridge/Doctrine/composer.json src/Symfony/Bridge/Propel1/composer.json src/Symfony/Bridge/Twig/AppVariable.php src/Symfony/Bundle/FrameworkBundle/composer.json src/Symfony/Bundle/SecurityBundle/Tests/Functional/Bundle/CsrfFormLoginBundle/Form/UserLoginFormType.php src/Symfony/Component/Form/Tests/ResolvedFormTypeTest.php
2 parents f7395c7 + a5e6b0d commit 30935c7

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

58 files changed

+306
-136
lines changed

UPGRADE-2.7.md

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
UPGRADE FROM 2.6 to 2.7
2+
=======================
3+
4+
Router
5+
------
6+
7+
* Route conditions now support container parameters which
8+
can be injected into condition using `%parameter%` notation.
9+
Due to the fact that it works by replacing all parameters
10+
with their corresponding values before passing condition
11+
expression for compilation there can be BC breaks where you
12+
could already have used percentage symbols. Single percentage symbol
13+
usage is not affected in any way. Conflicts may occur where
14+
you might have used `%` as a modulo operator, here's an example:
15+
`foo%bar%2` which would be compiled to `$foo % $bar % 2` in 2.6
16+
but in 2.7 you would get an error if `bar` parameter
17+
doesn't exist or unexpected result otherwise.
18+
19+
Form
20+
----
21+
22+
* In form types and extension overriding the "setDefaultOptions" of the
23+
AbstractType or AbstractExtensionType has been deprecated in favor of
24+
overriding the new "configureOptions" method.
25+
26+
The method "setDefaultOptions(OptionsResolverInterface $resolver)" will
27+
be renamed in Symfony 3.0 to "configureOptions(OptionsResolver $resolver)".
28+
29+
Before:
30+
31+
```php
32+
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
33+
34+
class TaskType extends AbstractType
35+
{
36+
// ...
37+
public function setDefaultOptions(OptionsResolverInterface $resolver)
38+
{
39+
$resolver->setDefaults(array(
40+
'data_class' => 'AppBundle\Entity\Task',
41+
));
42+
}
43+
}
44+
```
45+
46+
After:
47+
48+
```php
49+
use Symfony\Component\OptionsResolver\OptionsResolver;
50+
51+
class TaskType extends AbstractType
52+
{
53+
// ...
54+
public function configureOptions(OptionsResolver $resolver)
55+
{
56+
$resolver->setDefaults(array(
57+
'data_class' => 'AppBundle\Entity\Task',
58+
));
59+
}
60+
}
61+
```

UPGRADE-3.0.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,11 @@ UPGRADE FROM 2.x to 3.0
106106

107107
### Form
108108

109+
* The method `AbstractType::setDefaultOptions(OptionsResolverInterface $resolver)` and
110+
`AbstractTypeExtension::setDefaultOptions(OptionsResolverInterface $resolver)` have been
111+
renamed. You should use `AbstractType::configureOptions(OptionsResolver $resolver)` and
112+
`AbstractTypeExtension::configureOptions(OptionsResolver $resolver)` instead.
113+
109114
* The methods `Form::bind()` and `Form::isBound()` were removed. You should
110115
use `Form::submit()` and `Form::isSubmitted()` instead.
111116

src/Symfony/Bridge/Doctrine/Form/Type/DoctrineType.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
use Symfony\Bridge\Doctrine\Form\DataTransformer\CollectionToArrayTransformer;
2222
use Symfony\Component\Form\AbstractType;
2323
use Symfony\Component\OptionsResolver\Options;
24-
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
24+
use Symfony\Component\OptionsResolver\OptionsResolver;
2525
use Symfony\Component\PropertyAccess\PropertyAccess;
2626
use Symfony\Component\PropertyAccess\PropertyAccessorInterface;
2727

@@ -58,7 +58,7 @@ public function buildForm(FormBuilderInterface $builder, array $options)
5858
}
5959
}
6060

61-
public function setDefaultOptions(OptionsResolverInterface $resolver)
61+
public function configureOptions(OptionsResolver $resolver)
6262
{
6363
$choiceListCache = & $this->choiceListCache;
6464
$registry = $this->registry;

src/Symfony/Bridge/Propel1/Form/Type/ModelType.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
use Symfony\Component\Form\AbstractType;
1717
use Symfony\Component\Form\FormBuilderInterface;
1818
use Symfony\Component\OptionsResolver\Options;
19-
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
19+
use Symfony\Component\OptionsResolver\OptionsResolver;
2020
use Symfony\Component\PropertyAccess\PropertyAccess;
2121
use Symfony\Component\PropertyAccess\PropertyAccessorInterface;
2222

@@ -78,7 +78,7 @@ public function buildForm(FormBuilderInterface $builder, array $options)
7878
/**
7979
* {@inheritdoc}
8080
*/
81-
public function setDefaultOptions(OptionsResolverInterface $resolver)
81+
public function configureOptions(OptionsResolver $resolver)
8282
{
8383
$propertyAccessor = $this->propertyAccessor;
8484

src/Symfony/Bridge/Propel1/Form/Type/TranslationCollectionType.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
use Symfony\Component\Form\AbstractType;
1515
use Symfony\Component\OptionsResolver\Exception\MissingOptionsException;
1616
use Symfony\Component\Form\FormBuilderInterface;
17-
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
17+
use Symfony\Component\OptionsResolver\OptionsResolver;
1818
use Symfony\Bridge\Propel1\Form\EventListener\TranslationCollectionFormListener;
1919

2020
/**
@@ -59,7 +59,7 @@ public function getName()
5959
/**
6060
* {@inheritdoc}
6161
*/
62-
public function setDefaultOptions(OptionsResolverInterface $resolver)
62+
public function configureOptions(OptionsResolver $resolver)
6363
{
6464
$resolver->setRequired(array(
6565
'languages',

src/Symfony/Bridge/Propel1/Form/Type/TranslationType.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313

1414
use Symfony\Component\Form\AbstractType;
1515
use Symfony\Component\Form\FormBuilderInterface;
16-
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
16+
use Symfony\Component\OptionsResolver\OptionsResolver;
1717
use Symfony\Bridge\Propel1\Form\EventListener\TranslationFormListener;
1818

1919
/**
@@ -44,7 +44,7 @@ public function getName()
4444
/**
4545
* {@inheritdoc}
4646
*/
47-
public function setDefaultOptions(OptionsResolverInterface $resolver)
47+
public function configureOptions(OptionsResolver $resolver)
4848
{
4949
$resolver->setRequired(array(
5050
'data_class',

src/Symfony/Bundle/FrameworkBundle/Resources/config/esi.xml

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

77
<parameters>
88
<parameter key="esi.class">Symfony\Component\HttpKernel\HttpCache\Esi</parameter>
9-
<parameter key="esi_listener.class">Symfony\Component\HttpKernel\EventListener\EsiListener</parameter>
9+
<parameter key="esi_listener.class">Symfony\Component\HttpKernel\EventListener\SurrogateListener</parameter>
1010
</parameters>
1111

1212
<services>

src/Symfony/Bundle/FrameworkBundle/Routing/Router.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff lin 10000 e change
@@ -113,6 +113,7 @@ private function resolveParameters(RouteCollection $collection)
113113
$methods = array_merge($methods, explode('|', $this->resolve($method)));
114114
}
115115
$route->setMethods($methods);
116+
$route->setCondition($this->resolve($route->getCondition()));
116117
}
117118
}
118119

src/Symfony/Bundle/FrameworkBundle/Tests/Routing/RouterTest.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,16 +28,18 @@ public function testGenerateWithServiceParam()
2828
),
2929
array(
3030
'_locale' => 'en|es',
31-
)
31+
), array(), '', array(), array(), '"%foo%" == "bar"'
3232
));
3333

3434
$sc = $this->getServiceContainer($routes);
3535
$sc->setParameter('locale', 'es');
36+
$sc->setParameter('foo', 'bar');
3637

3738
$router = new Router($sc, 'foo');
3839

3940
$this->assertSame('/en', $router->generate('foo', array('_locale' => 'en')));
4041
$this->assertSame('/', $router->generate('foo', array('_locale' => 'es')));
42+
$this->assertSame('"bar" == "bar"', $router->getRouteCollection()->get('foo')->getCondition());
4143
}
4244

4345
public function testDefaultsPlaceholders()

src/Symfony/Bundle/SecurityBundle/Resources/config/templating_php.xml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,9 @@
1212
<services>
1313
<service id="templating.helper.logout_url" class="%templating.helper.logout_url.class%">
1414
<tag name="templating.helper" alias="logout_url" />
15-
<argument type="service" id="service_container" />
15+
<argument type="service" id="request_stack" />
1616
<argument type="service" id="router" />
17+
<argument type="service" id="security.token_storage" />
1718
</service>
1819

1920
<service id="templating.helper.security" class="%templating.helper.security.class%">

src/Symfony/Bundle/SecurityBundle/Templating/Helper/LogoutUrlHelper.php

Lines changed: 37 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@
1414
use Symfony\Component\DependencyInjection\ContainerInterface;
1515
use Symfony\Component\Form\Extension\Csrf\CsrfProvider\CsrfProviderAdapter;
1616
use Symfony\Component\Form\Extension\Csrf\CsrfProvider\CsrfProviderInterface;
17+
use Symfony\Component\HttpFoundation\RequestStack;
1718
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
19+
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
1820
use Symfony\Component\Security\Csrf\CsrfTokenManagerInterface;
1921
use Symfony\Component\Templating\Helper\Helper;
2022

@@ -25,20 +27,33 @@
2527
*/
2628
class LogoutUrlHelper extends Helper
2729
{
28-
private $container;
30+
private $requestStack;
2931
private $listeners = array();
3032
private $router;
33+
private $tokenStorage;
3134

3235
/**
3336
* Constructor.
3437
*
35-
* @param ContainerInterface $container A ContainerInterface instance
36-
* @param UrlGeneratorInterface $router A Router instance
38+
* @param ContainerInterface|RequestStack $requestStack A ContainerInterface instance or RequestStack
39+
* @param UrlGeneratorInterface $router The router service
40+
* @param TokenStorageInterface|null $tokenStorage The token storage service
41+
*
42+
* @deprecated Passing a ContainerInterface as a first argument is deprecated since 2.7 and will be removed in 3.0.
3743
*/
38-
public function __construct(ContainerInterface $container, UrlGeneratorInterface $router)
44+
public function __construct($requestStack, UrlGeneratorInterface $router, TokenStorageInterface $tokenStorage = null)
3945
{
40-
$this->container = $container;
46+
if ($requestStack instanceof ContainerInterface) {
47+
$this->requestStack = $requestStack->get('request_stack');
48+
trigger_error('The '.__CLASS__.' constructor will require a RequestStack instead of a ContainerInterface instance in 3.0.', E_USER_DEPRECATED);
49+
} elseif ($requestStack instanceof RequestStack) {
50+
$this->requestStack = $requestStack;
51+
} else {
52+
throw new \InvalidArgumentException(sprintf('%s takes either a RequestStack or a ContainerInterface object as its first argument.', __METHOD__));
53+
}
54+
4155
$this->router = $router;
56+
$this->tokenStorage = $tokenStorage;
4257
}
4358

4459
/**
@@ -64,7 +79,7 @@ public function registerListener($key, $logoutPath, $csrfTokenId, $csrfParameter
6479
/**
6580
* Generates the absolute logout path for the firewall.
6681
*
67-
* @param string $key The firewall key
82+
* @param string|null $key The firewall key or null to use the current firewall key
6883
*
6984
* @return string The logout path
7085
*/
@@ -76,7 +91,7 @@ public function getLogoutPath($key)
7691
/**
7792
* Generates the absolute logout URL for the firewall.
7893
*
79-
* @param string $key The firewall key
94+
* @param string|null $key The firewall key or null to use the current firewall key
8095
*
8196
* @return string The logout URL
8297
*/
@@ -88,15 +103,27 @@ public function getLogoutUrl($key)
88103
/**
89104
* Generates the logout URL for the firewall.
90105
*
91-
* @param string $key The firewall key
106+
* @param string|null $key The firewall key or null to use the current firewall key
92107
* @param bool|string $referenceType The type of reference (one of the constants in UrlGeneratorInterface)
93108
*
94109
* @return string The logout URL
95110
*
96-
* @throws \InvalidArgumentException if no LogoutListener is registered for the key
111+
* @throws \InvalidArgumentException if no LogoutListener is registered for the key or the key could not be found automatically.
97112
*/
98113
private function generateLogoutUrl($key, $referenceType)
99114
{
115+
// Fetch the current provider key from token, if possible
116+
if (null === $key && null !== $this->tokenStorage) {
117+
$token = $this->tokenStorage->getToken();
118+
if (null !== $token && method_exists($token, 'getProviderKey')) {
119+
$key = $token->getProviderKey();
120+
}
121+
}
122+
123+
if (null === $key) {
124+
throw new \InvalidArgumentException('Unable to find the current firewall LogoutListener, please provide the provider key manually.');
125+
}
126+
100127
if (!array_key_exists($key, $this->listeners)) {
101128
throw new \InvalidArgumentException(sprintf('No LogoutListener found for firewall key "%s".', $key));
102129
}
@@ -106,7 +133,7 @@ private function generateLogoutUrl($key, $referenceType)
106133
$parameters = null !== $csrfTokenManager ? array($csrfParameter => (string) $csrfTokenManager->getToken($csrfTokenId)) : array();
107134

108135
if ('/' === $logoutPath[0]) {
109-
$request = $this->container->get('request_stack')->getCurrentRequest();
136+
$request = $this->requestStack->getCurrentRequest();
110137

111138
$url = UrlGeneratorInterface::ABSOLUTE_URL === $referenceType ? $request->getUriForPath($logoutPath) : $request->getBasePath().$logoutPath;
112139

src/Symfony/Bundle/SecurityBundle/Tests/Functional/Bundle/CsrfFormLoginBundle/Form/UserLoginFormType.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
use Symfony\Component\Form\FormEvents;
1818
use Symfony\Component\Form\FormEvent;
1919
use Symfony\Component\HttpFoundation\RequestStack;
20-
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
20+
use Symfony\Component\OptionsResolver\OptionsResolver;
2121
use Symfony\Component\Security\Core\Security;
2222

2323
/**
@@ -74,7 +74,7 @@ public function buildForm(FormBuilderInterface $builder, array $options)
7474
/**
7575
* {@inheritdoc}
7676
*/
77-
public function setDefaultOptions(OptionsResolverInterface $resolver)
77+
public function configureOptions(OptionsResolver $resolver)
7878
{
7979
/* Note: the form's intention must correspond to that for the form login
8080
* listener in order for the CSRF token to validate successfully.

src/Symfony/Bundle/SecurityBundle/Tests/Functional/Bundle/FormLoginBundle/Resources/views/Login/after_login.html.twig

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,14 @@
33
{% block body %}
44
Hello {{ app.user.username }}!<br /><br />
55
You're browsing to path "{{ app.request.pathInfo }}".
6+
7+
<a href="{{ logout_path('default') }}">Log out</a>.
8+
<a href="{{ logout_url('default') }}">Log out</a>.
9+
10+
<a href="{{ logout_path('second_area') }}">Log out</a>.
11+
<a href="{{ logout_url('second_area') }}">Log out</a>.
12+
13+
<a href="{{ logout_path() }}">Log out</a>.
14+
<a href="{{ logout_url() }}">Log out</a>.
15+
616
{% endblock %}

src/Symfony/Bundle/SecurityBundle/Tests/Functional/FormLoginTest.php

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,40 @@ public function testFormLogin($config)
3636
$this->assertContains('You\'re browsing to path "/profile".', $text);
3737
}
3838

39+
/**
40+
* @dataProvider getConfigs
41+
*/
42+
public function testFormLogout($config)
43+
{
44+
$client = $this->createClient(array('test_case' => 'StandardFormLogin', 'root_config' => $config));
45+
$client->insulate();
46+
47+
$form = $client->request('GET', '/login')->selectButton('login')->form();
48+
$form['_username'] = 'johannes';
49+
$form['_password'] = 'test';
50+
$client->submit($form);
51+
52+
$this->assertRedirect($client->getResponse(), '/profile');
53+
54+
$crawler = $client->followRedirect();
55+
$text = $crawler->text();
56+
57+
$this->assertContains('Hello johannes!', $text);
58+
$this->assertContains('You\'re browsing to path "/profile".', $text);
59+
60+
$logoutLinks = $crawler->selectLink('Log out')->links();
61+
$this->assertCount(6, $logoutLinks);
62+
$this->assertSame($logoutLinks[0]->getUri(), $logoutLinks[1]->getUri());
63+
$this->assertSame($logoutLinks[2]->getUri(), $logoutLinks[3]->getUri());
64+
$this->assertSame($logoutLinks[4]->getUri(), $logoutLinks[5]->getUri());
65+
66+
$this->assertNotSame($logoutLinks[0]->getUri(), $logoutLinks[2]->getUri());
67+
$this->assertNotSame($logoutLinks[1]->getUri(), $logoutLinks[3]->getUri());
68+
69+
$this->assertSame($logoutLinks[0]->getUri(), $logoutLinks[4]->getUri());
70+
$this->assertSame($logoutLinks[1]->getUri(), $logoutLinks[5]->getUri());
71+
}
72+
3973
/**
4074
* @dataProvider getConfigs
4175
*/

src/Symfony/Bundle/SecurityBundle/Tests/Functional/app/StandardFormLogin/config.yml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,17 @@ security:
2323
form_login:
2424
check_path: /login_check
2525
default_target_path: /profile
26+
logout: ~
2627
anonymous: ~
2728

29+
# This firewall is here just to check its the logout functionality
30+
second_area:
31+
http_basic: ~
32+
anonymous: ~
33+
logout:
34+
target: /second/target
35+
path: /second/logout
36+
2837
access_control:
2938
- { path: ^/unprotected_resource$, roles: IS_AUTHENTICATED_ANONYMOUSLY }
3039
- { path: ^/secure-but-not-covered-by-access-control$, roles: IS_AUTHENTICATED_ANONYMOUSLY }

0 commit comments

Comments
 (0)
0