Skip to content

Commit 32cfb01

Browse files
mikadamczykglye
authored andcommitted
EZP-31644: Fixed serialization of Compound SiteAccess matcher (ezsystems#3037)
* Fixed serialization of Compound SiteAccess matcher * Added tests for serialization of matchers (cherry picked from commit f816402)
1 parent 7fef916 commit 32cfb01

File tree

14 files changed

+396
-23
lines changed

14 files changed

+396
-23
lines changed

eZ/Bundle/EzPublishCoreBundle/Fragment/DecoratedFragmentRenderer.php

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
*/
99
namespace eZ\Bundle\EzPublishCoreBundle\Fragment;
1010

11-
use eZ\Publish\Core\MVC\Symfony\Component\Serializer\SerializerTrait;
1211
use eZ\Publish\Core\MVC\Symfony\SiteAccess\SiteAccessAware;
1312
use eZ\Publish\Core\MVC\Symfony\SiteAccess;
1413
use Symfony\Component\HttpFoundation\Request;
@@ -18,7 +17,7 @@
1817

1918
class DecoratedFragmentRenderer implements FragmentRendererInterface, SiteAccessAware
2019
{
21-
use SerializerTrait;
20+
use SiteAccessSerializationTrait;
2221

2322
/**
2423
* @var \Symfony\Component\HttpKernel\Fragment\FragmentRendererInterface
@@ -71,11 +70,7 @@ public function render($uri, Request $request, array $options = array())
7170
// Serialize the siteaccess to get it back after.
7271
// @see eZ\Publish\Core\MVC\Symfony\EventListener\SiteAccessMatchListener
7372
$siteAccess = $request->attributes->get('siteaccess');
74-
$uri->attributes['serialized_siteaccess'] = json_encode($siteAccess);
75-
$uri->attributes['serialized_siteaccess_matcher'] = $this->getSerializer()->serialize(
76-
$siteAccess->matcher,
77-
'json'
78-
);
73+
$this->serializeSiteAccess($siteAccess, $uri);
7974
}
8075

8176
return $this->innerRenderer->render($uri, $request, $options);

eZ/Bundle/EzPublishCoreBundle/Fragment/InlineFragmentRenderer.php

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
*/
99
namespace eZ\Bundle\EzPublishCoreBundle\Fragment;
1010

11-
use eZ\Publish\Core\MVC\Symfony\Component\Serializer\SerializerTrait;
1211
use eZ\Publish\Core\MVC\Symfony\SiteAccess\SiteAccessAware;
1312
use eZ\Publish\Core\MVC\Symfony\SiteAccess;
1413
use Symfony\Component\HttpFoundation\Request;
@@ -19,7 +18,7 @@
1918

2019
class InlineFragmentRenderer extends BaseRenderer implements SiteAccessAware
2120
{
22-
use SerializerTrait;
21+
use SiteAccessSerializationTrait;
2322

2423
/**
2524
* @var \Symfony\Component\HttpKernel\Fragment\FragmentRendererInterface
@@ -54,11 +53,7 @@ public function render($uri, Request $request, array $options = array())
5453
if ($request->attributes->has('siteaccess')) {
5554
/** @var \eZ\Publish\Core\MVC\Symfony\SiteAccess $siteAccess */
5655
$siteAccess = $request->attributes->get('siteaccess');
57-
$uri->attributes['serialized_siteaccess'] = json_encode($siteAccess);
58-
$uri->attributes['serialized_siteaccess_matcher'] = $this->getSerializer()->serialize(
59-
$siteAccess->matcher,
60-
'json'
61-
);
56+
$this->serializeSiteAccess($siteAccess, $uri);
6257
}
6358
if ($request->attributes->has('semanticPathinfo')) {
6459
$uri->attributes['semanticPathinfo'] = $request->attributes->get('semanticPathinfo');
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<?php
2+
3+
/**
4+
* @copyright Copyright (C) eZ Systems AS. All rights reserved.
5+
* @license For full copyright and license information view LICENSE file distributed with this source code.
6+
*/
7+
namespace eZ\Bundle\EzPublishCoreBundle\Fragment;
8+
9+
use eZ\Publish\Core\MVC\Symfony\Component\Serializer\SerializerTrait;
10+
use eZ\Publish\Core\MVC\Symfony\SiteAccess;
11+
use Symfony\Component\HttpKernel\Controller\ControllerReference;
12+
13+
trait SiteAccessSerializationTrait
14+
{
15+
use SerializerTrait;
16+
17+
public function serializeSiteAccess(SiteAccess $siteAccess, ControllerReference $uri)
18+
{
19+
// Serialize the siteaccess to get it back after. @see eZ\Publish\Core\MVC\Symfony\EventListener\SiteAccessMatchListener
20+
$uri->attributes['serialized_siteaccess'] = json_encode($siteAccess);
21+
$uri->attributes['serialized_siteaccess_matcher'] = $this->getSerializer()->serialize(
22+
$siteAccess->matcher,
23+
'json'
24+
);
25+
if ($siteAccess->matcher instanceof SiteAccess\Matcher\CompoundInterface) {
26+
$subMatchers = $siteAccess->matcher->getSubMatchers();
27+
foreach ($subMatchers as $subMatcher) {
28+
$uri->attributes['serialized_siteaccess_sub_matchers'][get_class($subMatcher)] = $this->getSerializer()->serialize(
29+
$subMatcher,
30+
'json'
31+
);
32+
}
33+
}
34+
}
35+
}

eZ/Bundle/EzPublishCoreBundle/Tests/Fragment/DecoratedFragmentRendererTest.php

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,12 @@
99
namespace eZ\Bundle\EzPublishCoreBundle\Tests\Fragment;
1010

1111
use eZ\Bundle\EzPublishCoreBundle\Fragment\DecoratedFragmentRenderer;
12-
use eZ\Publish\Core\MVC\Symfony\Component\Serializer\SerializerTrait;
1312
use eZ\Publish\Core\MVC\Symfony\SiteAccess;
14-
use PHPUnit\Framework\TestCase;
1513
use Symfony\Component\HttpFoundation\Request;
1614
use Symfony\Component\HttpKernel\Controller\ControllerReference;
1715

18-
class DecoratedFragmentRendererTest extends TestCase
16+
class DecoratedFragmentRendererTest extends FragmentRendererBaseTest
1917
{
20-
use SerializerTrait;
21-
2218
/**
2319
* @var \PHPUnit_Framework_MockObject_MockObject
2420
*/
@@ -124,4 +120,17 @@ public function testRendererControllerReference()
124120
$reference->attributes['serialized_siteaccess_matcher']
125121
);
126122
}
123+
124+
public function getRequest(SiteAccess $siteAccess)
125+
{
126+
$request = new Request();
127+
$request->attributes->set('siteaccess', $siteAccess);
128+
129+
return $request;
130+
}
131+
132+
public function getRenderer()
133+
{
134+
return new DecoratedFragmentRenderer($this->innerRenderer);
135+
}
127136
}
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
<?php
2+
3+
/**
4+
* @copyright Copyright (C) eZ Systems AS. All rights reserved.
5+
* @license For full copyright and license information view LICENSE file distributed with this source code.
6+
*/
7+
namespace eZ\Bundle\EzPublishCoreBundle\Tests\Fragment;
8+
9+
use eZ\Publish\Core\MVC\Symfony\Component\Serializer\SerializerTrait;
10+
use eZ\Publish\Core\MVC\Symfony\SiteAccess;
11+
use PHPUnit\Framework\TestCase;
12+
use Symfony\Component\HttpKernel\Controller\ControllerReference;
13+
14+
abstract class FragmentRendererBaseTest extends TestCase
15+
{
16+
use SerializerTrait;
17+
18+
public function testRendererControllerReferenceWithCompoundMatcher()
19+
{
20+
$reference = new ControllerReference('FooBundle:bar:baz');
21+
$compoundMatcher = new SiteAccess\Matcher\Compound\LogicalAnd([]);
22+
$subMatchers = [
23+
'Map\URI' => new SiteAccess\Matcher\Map\URI([]),
24+
'Map\Host' => new SiteAccess\Matcher\Map\Host([]),
25+
];
26+
$compoundMatcher->setSubMatchers($subMatchers);
27+
$siteAccess = new SiteAccess(
28+
'test',
29+
'test',
30+
$compoundMatcher
31+
);
32+
33+
$request = $this->getRequest($siteAccess);
34+
$options = ['foo' => 'bar'];
35+
$expectedReturn = '/_fragment?foo=bar';
36+
$this->innerRenderer
37+
->expects($this->once())
38+
->method('render')
39+
->with($reference, $request, $options)
40+
->will($this->returnValue($expectedReturn));
41+
42+
$renderer = $this->getRenderer();
43+
$this->assertSame($expectedReturn, $renderer->render($reference, $request, $options));
44+
$this->assertArrayHasKey('serialized_siteaccess', $reference->attributes);
45+
$serializedSiteAccess = json_encode($siteAccess);
46+
$this->assertSame($serializedSiteAccess, $reference->attributes['serialized_siteaccess']);
47+
$this->assertArrayHasKey('serialized_siteaccess_matcher', $reference->attributes);
48+
$this->assertSame(
49+
$this->getSerializer()->serialize(
50+
$siteAccess->matcher,
51+
'json'
52+
),
53+
$reference->attributes['serialized_siteaccess_matcher']
54+
);
55+
$this->assertArrayHasKey('serialized_siteaccess_sub_matchers', $reference->attributes);
56+
foreach ($siteAccess->matcher->getSubMatchers() as $subMatcher) {
57+
$this->assertSame(
58+
$this->getSerializer()->serialize(
59+
$subMatcher,
60+
'json'
61+
),
62+
$reference->attributes['serialized_siteaccess_sub_matchers'][get_class($subMatcher)]
63+
);
64+
}
65+
66+
return $reference;
67+
}
68+
69+
abstract public function getRequest(SiteAccess $siteAccess);
70+
71+
abstract public function getRenderer();
72+
}

eZ/Bundle/EzPublishCoreBundle/Tests/Fragment/InlineFragmentRendererTest.php

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,12 @@
77
namespace eZ\Bundle\EzPublishCoreBundle\Tests\Fragment;
88

99
use eZ\Bundle\EzPublishCoreBundle\Fragment\InlineFragmentRenderer;
10-
use eZ\Publish\Core\MVC\Symfony\Component\Serializer\SerializerTrait;
1110
use eZ\Publish\Core\MVC\Symfony\SiteAccess;
1211
use Symfony\Component\HttpFoundation\Request;
1312
use Symfony\Component\HttpKernel\Controller\ControllerReference;
1413

1514
class InlineFragmentRendererTest extends DecoratedFragmentRendererTest
1615
{
17-
use SerializerTrait;
18-
1916
public function testRendererControllerReference()
2017
{
2118
$reference = new ControllerReference('FooBundle:bar:baz');
@@ -55,4 +52,31 @@ public function testRendererControllerReference()
5552
$this->assertTrue(isset($reference->attributes['viewParametersString']));
5653
$this->assertSame('/(foo)/bar', $reference->attributes['viewParametersString']);
5754
}
55+
56+
public function testRendererControllerReferenceWithCompoundMatcher()
57+
{
58+
$reference = parent::testRendererControllerReferenceWithCompoundMatcher();
59+
60+
$this->assertArrayHasKey('semanticPathinfo', $reference->attributes);
61+
$this->assertSame('/foo/bar', $reference->attributes['semanticPathinfo']);
62+
$this->assertArrayHasKey('viewParametersString', $reference->attributes);
63+
$this->assertSame('/(foo)/bar', $reference->attributes['viewParametersString']);
64+
65+
return $reference;
66+
}
67+
68+
public function getRequest(SiteAccess $siteAccess)
69+
{
70+
$request = new Request();
71+
$request->attributes->set('siteaccess', $siteAccess);
72+
$request->attributes->set('semanticPathinfo', '/foo/bar');
73+
$request->attributes->set('viewParametersString', '/(foo)/bar');
74+
75+
return $request;
76+
}
77+
78+
public function getRenderer()
79+
{
80+
return new InlineFragmentRenderer($this->innerRenderer);
81+
}
5882
}

eZ/Publish/Core/MVC/Symfony/Component/Serializer/SerializerTrait.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ trait SerializerTrait
1818
public function getSerializer()
1919
{
2020
return new Serializer(
21-
[(new PropertyNormalizer())->setIgnoredAttributes(['request'])],
21+
[(new PropertyNormalizer())->setIgnoredAttributes(['request', 'container', 'matcherBuilder'])],
2222
[new JsonEncoder()]
2323
);
2424
}

eZ/Publish/Core/MVC/Symfony/EventListener/SiteAccessMatchListener.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,13 @@ public function onKernelRequest(GetResponseEvent $event)
9595
)
9696
);
9797
}
98+
if ($request->attributes->get('serialized_siteaccess_sub_matchers')) {
99+
$subMatchers = [];
100+
foreach ($request->attributes->get('serialized_siteaccess_sub_matchers') as $matcherClass => $serializedData) {
101+
$subMatchers[$matcherClass] = $serializer->deserialize($serializedData, $matcherClass, 'json');
102+
}
103+
$siteAccess->matcher->setSubMatchers($subMatchers);
104+
}
98105
}
99106

100107
$request->attributes->set(

eZ/Publish/Core/MVC/Symfony/EventListener/Tests/SiteAccessMatchListenerTest.php

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,66 @@ public function testOnKernelRequestSerializedSA()
134134
$this->assertFalse($request->attributes->has('serialized_siteaccess'));
135135
}
136136

137+
public function testOnKernelRequestSerializedSAWithCompoundMatcher()
138+
{
139+
$compoundMatcher = new SiteAccess\Matcher\Compound\LogicalAnd([]);
140+
$subMatchers = [
141+
SiteAccess\Matcher\Map\URI::class => new SiteAccess\Matcher\Map\URI([]),
142+
SiteAccess\Matcher\Map\Host::class => new SiteAccess\Matcher\Map\Host([]),
143+
];
144+
$compoundMatcher->setSubMatchers($subMatchers);
145+
$siteAccess = new SiteAccess(
146+
'test',
147+
'matching_type',
148+
$compoundMatcher
149+
);
150+
$request = new Request();
151+
$request->attributes->set('serialized_siteaccess', json_encode($siteAccess));
152+
$request->attributes->set(
153+
'serialized_siteaccess_matcher',
154+
$this->getSerializer()->serialize(
155+
$siteAccess->matcher,
156+
'json'
157+
)
158+
);
159+
$serializedSubMatchers = [];
160+
foreach ($subMatchers as $subMatcher) {
161+
$serializedSubMatchers[get_class($subMatcher)] = $this->getSerializer()->serialize(
162+
$subMatcher,
163+
'json'
164+
);
165+
}
166+
$request->attributes->set(
167+
'serialized_siteaccess_sub_matchers',
168+
$serializedSubMatchers
169+
);
170+
$event = new GetResponseEvent(
171+
$this->createMock(HttpKernelInterface::class),
172+
$request,
173+
HttpKernelInterface::MASTER_REQUEST
174+
);
175+
176+
$this->userHashMatcher
177+
->expects($this->once())
178+
->method('matches')
179+
->with($request)
180+
->will($this->returnValue(false));
181+
182+
$this->saRouter
183+
->expects($this->never())
184+
->method('match');
185+
186+
$postSAMatchEvent = new PostSiteAccessMatchEvent($siteAccess, $request, $event->getRequestType());
187+
$this->eventDispatcher
188+
->expects($this->once())
189+
->method('dispatch')
190+
->with(MVCEvents::SITEACCESS, $this->equalTo($postSAMatchEvent));
191+
192+
$this->listener->onKernelRequest($event);
193+
$this->assertEquals($siteAccess, $request->attributes->get('siteaccess'));
194+
$this->assertFalse($request->attributes->has('serialized_siteaccess'));
195+
}
196+
137197
public function testOnKernelRequestSiteAccessPresent()
138198
{
139199
$siteAccess = new SiteAccess();

eZ/Publish/Core/MVC/Symfony/SiteAccess/Matcher/HostText.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,13 @@ class HostText extends Regex implements VersatileMatcher
1717

1818
private $suffix;
1919

20+
/**
21+
* The property needed to allow correct deserialization with Symfony serializer.
22+
*
23+
* @var array
24+
*/
25+
private $siteAccessesConfiguration;
26+
2027
/**
2128
* Constructor.
2229
*
@@ -30,6 +37,7 @@ public function __construct(array $siteAccessesConfiguration)
3037
'^' . preg_quote($this->prefix, '@') . "(\w+)" . preg_quote($this->suffix, '@') . '$',
3138
1
3239
);
40+
$this->siteAccessesConfiguration = $siteAccessesConfiguration;
3341
}
3442

3543
public function getName()

0 commit comments

Comments
 (0)