Skip to content

Commit 7532496

Browse files
Big-SharkJean85
authored andcommitted
Add support for Symfony 5 (#266)
* Add support for Symfony 5 * Update CHANGELOG.md * Remove Symfony < 3.3 compat code * Do not mock event in test * Remove more instances of %kernel.root_dir% * Fix tests and add alias for deprecated GetResponseEvent class * Fix tests and add alias for deprecated FilterControllerEvent class * Fix tests and add alias for deprecated events in SubrequestListener * Fix mistake about ResponseEvent -> RequestEvent * Fix deprecation of client in E2E tests * Try to fix routing config loading in E2E tests * Avoid deprecation in E2E config * Fix class aliases * Revert wrong fix * Fix event names * Allow PHPUnit 8 * Avoid using trait for test compat * Ignore deprecations coming from Symfony 3.4 * Disable deprecations completely under Symfony 3.4
1 parent 0e12fee commit 7532496

21 files changed

+195
-229
lines changed

.travis.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,9 @@ jobs:
3131
include:
3232
- stage: Test
3333
php: 7.1
34-
env: SYMFONY_VERSION=3.4.*
34+
env:
35+
- SYMFONY_VERSION: 3.4.*
36+
- SYMFONY_DEPRECATIONS_HELPER: disabled
3537
- php: 7.3
3638
env: SYMFONY_VERSION=4.4.*
3739
- php: 7.4

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
55
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
66

77
## Unreleased
8+
- Add support for Symfony 5.0 (#266, thanks to @Big-Shark)
89
- Drop support for Symfony < 3.4 (#277)
910
- Fix handling of command with no name on `ConsoleListener` (#261)
1011
- Remove check by AuthorizationChecker in `RequestListener` (#264)

composer.json

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,12 @@
2222
"php": "^7.1",
2323
"jean85/pretty-package-versions": "^1.0",
2424
"sentry/sdk": "^2.0",
25-
"symfony/config": "^3.4||^4.0",
26-
"symfony/console": "^3.4||^4.0",
27-
"symfony/dependency-injection": "^3.4||^4.0",
28-
"symfony/event-dispatcher": "^3.4||^4.0",
29-
"symfony/http-kernel": "^3.4||^4.0",
30-
"symfony/security-core": "^3.4||^4.0"
25+
"symfony/config": "^3.4||^4.0||^5.0",
26+
"symfony/console": "^3.4||^4.0||^5.0",
27+
"symfony/dependency-injection": "^3.4||^4.0||^5.0",
28+
"symfony/event-dispatcher": "^3.4||^4.0||^5.0",
29+
"symfony/http-kernel": "^3.4||^4.0||^5.0",
30+
"symfony/security-core": "^3.4||^4.0||^5.0"
3131
},
3232
"require-dev": {
3333
"friendsofphp/php-cs-fixer": "^2.8",
@@ -36,13 +36,13 @@
3636
"php-http/mock-client": "^1.0",
3737
"phpstan/phpstan-shim": "^0.11",
3838
"phpstan/phpstan-phpunit": "^0.11",
39-
"phpunit/phpunit": "^7.5",
40-
"symfony/browser-kit": "^3.4||^4.0",
41-
"symfony/expression-language": "^3.4||^4.0",
42-
"symfony/framework-bundle": "^3.4||^4.0",
39+
"phpunit/phpunit": "^7.5||^8.5",
40+
"symfony/browser-kit": "^3.4||^4.0||^5.0",
41+
"symfony/expression-language": "^3.4||^4.0||^5.0",
42+
"symfony/framework-bundle": "^3.4||^4.0||^5.0",
4343
"symfony/monolog-bundle": "^3.4",
4444
"symfony/phpunit-bridge": "^5.0",
45-
"symfony/yaml": "^3.4||^4.0"
45+
"symfony/yaml": "^3.4||^4.0||^5.0"
4646
},
4747
"suggest": {
4848
"monolog/monolog": "Required to use the Monolog handler"

phpunit.xml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<phpunit
33
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4-
xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/7.5/phpunit.xsd"
4+
xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/8.5/phpunit.xsd"
55
colors="true"
66
backupGlobals="false"
77
bootstrap="vendor/autoload.php"
8+
cacheResult="false"
89
processIsolation="true"
910
>
1011

src/DependencyInjection/Configuration.php

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
88
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
99
use Symfony\Component\Config\Definition\ConfigurationInterface;
10-
use Symfony\Component\HttpKernel\Kernel;
1110

1211
/**
1312
* This is the class that validates and merges configuration from your app/config files
@@ -78,7 +77,7 @@ public function getConfigTreeBuilder(): TreeBuilder
7877
$optionsChildNodes->arrayNode('in_app_exclude')
7978
->defaultValue([
8079
'%kernel.cache_dir%',
81-
$this->getProjectRoot() . '/vendor',
80+
'%kernel.project_dir%/vendor',
8281
])
8382
->prototype('scalar');
8483
$optionsChildNodes->arrayNode('excluded_exceptions')
@@ -88,7 +87,7 @@ public function getConfigTreeBuilder(): TreeBuilder
8887
$optionsChildNodes->arrayNode('integrations')
8988
->prototype('scalar')
9089
->validate()
91-
->ifTrue(function ($value): bool {
90+
->ifTrue(static function ($value): bool {
9291
if (! is_string($value) && '' != $value) {
9392
return true;
9493
}
@@ -114,7 +113,7 @@ public function getConfigTreeBuilder(): TreeBuilder
114113
->defaultValue($defaultValues->getPrefixes())
115114
->prototype('scalar');
116115
$optionsChildNodes->scalarNode('project_root')
117-
->defaultValue($this->getProjectRoot());
116+
->defaultValue('%kernel.project_dir%');
118117
$optionsChildNodes->scalarNode('release');
119118
$optionsChildNodes->floatNode('sample_rate')
120119
->min(0.0)
@@ -166,7 +165,7 @@ public function getConfigTreeBuilder(): TreeBuilder
166165

167166
private function getTrimClosure(): \Closure
168167
{
169-
return function ($str): ?string {
168+
return static function ($str): ?string {
170169
$value = trim($str);
171170
if ($value === '') {
172171
return null;
@@ -176,18 +175,9 @@ private function getTrimClosure(): \Closure
176175
};
177176
}
178177

179-
private function getProjectRoot(): string
180-
{
181-
if (method_exists(Kernel::class, 'getProjectDir')) {
182-
return '%kernel.project_dir%';
183-
}
184-
185-
return '%kernel.root_dir%/..';
186-
}
187-
188178
private function isNotAValidCallback(): \Closure
189179
{
190-
return function ($value): bool {
180+
return static function ($value): bool {
191181
if (is_callable($value)) {
192182
return false;
193183
}

src/DependencyInjection/SentryExtension.php

Lines changed: 0 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -6,23 +6,16 @@
66
use Sentry\ClientBuilderInterface;
77
use Sentry\Monolog\Handler;
88
use Sentry\Options;
9-
use Sentry\SentryBundle\Command\SentryTestCommand;
109
use Sentry\SentryBundle\ErrorTypesParser;
11-
use Sentry\SentryBundle\EventListener\ConsoleListener;
1210
use Sentry\SentryBundle\EventListener\ErrorListener;
13-
use Sentry\SentryBundle\EventListener\RequestListener;
14-
use Sentry\SentryBundle\EventListener\SubRequestListener;
1511
use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException;
1612
use Symfony\Component\Config\FileLocator;
17-
use Symfony\Component\Console\ConsoleEvents;
18-
use Symfony\Component\Console\Event\ConsoleErrorEvent;
1913
use Symfony\Component\DependencyInjection\ContainerBuilder;
2014
use Symfony\Component\DependencyInjection\Exception\LogicException;
2115
use Symfony\Component\DependencyInjection\Loader;
2216
use Symfony\Component\DependencyInjection\Reference;
2317
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
2418
use Symfony\Component\HttpKernel\Event\ExceptionEvent;
25-
use Symfony\Component\HttpKernel\Kernel;
2619
use Symfony\Component\HttpKernel\KernelEvents;
2720

2821
/**
@@ -54,7 +47,6 @@ public function load(array $configs, ContainerBuilder $container): void
5447
}
5548

5649
$this->configureErrorListener($container, $processedConfiguration);
57-
$this->setLegacyVisibilities($container);
5850
$this->configureMonologHandler($container, $processedConfiguration['monolog']);
5951
}
6052

@@ -150,7 +142,6 @@ private function configureErrorListener(ContainerBuilder $container, array $proc
150142
}
151143

152144
$this->tagExceptionListener($container);
153-
$this->tagConsoleErrorListener($container);
154145
}
155146

156147
/**
@@ -172,47 +163,6 @@ private function tagExceptionListener(ContainerBuilder $container): void
172163
$listener->addTag('kernel.event_listener', $tagAttributes);
173164
}
174165

175-
/**
176-
* BC layer for Symfony < 3.3; see https://symfony.com/blog/new-in-symfony-3-3-better-handling-of-command-exceptions
177-
*/
178-
private function tagConsoleErrorListener(ContainerBuilder $container): void
179-
{
180-
$listener = $container->getDefinition(ErrorListener::class);
181-
182-
if (class_exists(ConsoleErrorEvent::class)) {
183-
$tagAttributes = [
184-
'event' => ConsoleEvents::ERROR,
185-
'method' => 'onConsoleError',
186-
'priority' => '%sentry.listener_priorities.console_error%',
187-
];
188-
} else {
189-
$tagAttributes = [
190-
'event' => ConsoleEvents::EXCEPTION,
191-
'method' => 'onConsoleException',
192-
'priority' => '%sentry.listener_priorities.console_error%',
193-
];
194-
}
195-
196-
$listener->addTag('kernel.event_listener', $tagAttributes);
197-
}
198-
199-
/**
200-
* BC layer for symfony < 3.3, listeners and commands must be public
201-
*/
202-
private function setLegacyVisibilities(ContainerBuilder $container): void
203-
{
204-
if (Kernel::VERSION_ID < 30300) {
205-
$container->getDefinition(SentryTestCommand::class)->setPublic(true);
206-
$container->getDefinition(ConsoleListener::class)->setPublic(true);
207-
$container->getDefinition(RequestListener::class)->setPublic(true);
208-
$container->getDefinition(SubRequestListener::class)->setPublic(true);
209-
210-
if ($container->hasDefinition(ErrorListener::class)) {
211-
$container->getDefinition(ErrorListener::class)->setPublic(true);
212-
}
213-
}
214-
}
215-
216166
private function configureMonologHandler(ContainerBuilder $container, array $monologConfiguration): void
217167
{
218168
$errorHandler = $monologConfiguration['error_handler'];

src/EventListener/ErrorListener.php

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44

55
use Sentry\State\HubInterface;
66
use Symfony\Component\Console\Event\ConsoleErrorEvent;
7-
use Symfony\Component\Console\Event\ConsoleExceptionEvent;
87
use Symfony\Component\HttpKernel\Event\ExceptionEvent;
98
use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
109

@@ -39,12 +38,4 @@ public function onConsoleError(ConsoleErrorEvent $event): void
3938
{
4039
\Sentry\captureException($event->getError());
4140
}
42-
43-
/**
44-
* BC layer for Symfony < 3.3; see https://symfony.com/blog/new-in-symfony-3-3-better-handling-of-command-exceptions
45-
*/
46-
public function onConsoleException(ConsoleExceptionEvent $event): void
47-
{
48-
\Sentry\captureException($event->getException());
49-
}
5041
}

src/EventListener/RequestListener.php

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,21 @@
55
use Sentry\SentryBundle\SentryBundle;
66
use Sentry\State\HubInterface;
77
use Sentry\State\Scope;
8+
use Symfony\Component\HttpKernel\Event\ControllerEvent;
89
use Symfony\Component\HttpKernel\Event\FilterControllerEvent;
910
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
11+
use Symfony\Component\HttpKernel\Event\RequestEvent;
1012
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
1113
use Symfony\Component\Security\Core\User\UserInterface;
1214

15+
if (! class_exists(RequestEvent::class)) {
16+
class_alias(GetResponseEvent::class, RequestEvent::class);
17+
}
18+
19+
if (! class_exists(ControllerEvent::class)) {
20+
class_alias(FilterControllerEvent::class, ControllerEvent::class);
21+
}
22+
1323
/**
1424
* Class RequestListener
1525
* @package Sentry\SentryBundle\EventListener
@@ -38,9 +48,9 @@ public function __construct(
3848
/**
3949
* Set the username from the security context by listening on core.request
4050
*
41-
* @param GetResponseEvent $event
51+
* @param RequestEvent $event
4252
*/
43-
public function onKernelRequest(GetResponseEvent $event): void
53+
public function onKernelRequest(RequestEvent $event): void
4454
{
4555
if (! $event->isMasterRequest()) {
4656
return;
@@ -75,7 +85,7 @@ public function onKernelRequest(GetResponseEvent $event): void
7585
});
7686
}
7787

78-
public function onKernelController(FilterControllerEvent $event): void
88+
public function onKernelController(ControllerEvent $event): void
7989
{
8090
if (! $event->isMasterRequest()) {
8191
return;

src/EventListener/SubRequestListener.php

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,20 @@
55
use Sentry\SentryBundle\SentryBundle;
66
use Symfony\Component\HttpKernel\Event\FinishRequestEvent;
77
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
8+
use Symfony\Component\HttpKernel\Event\RequestEvent;
9+
10+
if (! class_exists(RequestEvent::class)) {
11+
class_alias(GetResponseEvent::class, RequestEvent::class);
12+
}
813

914
final class SubRequestListener
1015
{
1116
/**
1217
* Pushes a new {@see Scope} for each SubRequest
1318
*
14-
* @param GetResponseEvent $event
19+
* @param RequestEvent $event
1520
*/
16-
public function onKernelRequest(GetResponseEvent $event): void
21+
public function onKernelRequest(RequestEvent $event): void
1722
{
1823
if ($event->isMasterRequest()) {
1924
return;

src/Resources/config/services.xml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,7 @@
3434
<argument type="service" id="Sentry\State\HubInterface" />
3535
<!-- The following tag is done manually in PHP for BC with Symfony < 4.3, -->
3636
<!-- <tag name="kernel.event_listener" event="kernel.exception" method="onException" priority="%sentry.listener_priorities.request_error%" />-->
37-
<!-- The following tag is done manually in PHP for BC with Symfony < 3.3 -->
38-
<!-- <tag name="kernel.event_listener" event="console.error" method="onConsoleError" priority="%sentry.listener_priorities.console_error%" />-->
37+
<tag name="kernel.event_listener" event="console.error" method="onConsoleError" priority="%sentry.listener_priorities.console_error%" />
3938
</service>
4039

4140
<service id="Sentry\SentryBundle\EventListener\RequestListener" class="Sentry\SentryBundle\EventListener\RequestListener" public="false">

test/BaseTestCase.php

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@
77
use Sentry\SentrySdk;
88
use Sentry\State\Hub;
99
use Sentry\State\HubInterface;
10+
use Symfony\Component\HttpFoundation\Request;
11+
use Symfony\Component\HttpFoundation\Response;
12+
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
13+
use Symfony\Component\HttpKernel\Event\RequestEvent;
14+
use Symfony\Component\HttpKernel\KernelInterface;
1015

1116
abstract class BaseTestCase extends TestCase
1217
{
@@ -43,4 +48,32 @@ protected function setCurrentHub(HubInterface $hub): void
4348
Hub::setCurrent($hub);
4449
}
4550
}
51+
52+
/**
53+
* @return GetResponseEvent|RequestEvent
54+
*/
55+
protected function createRequestEvent(Request $request = null, int $type = KernelInterface::MASTER_REQUEST)
56+
{
57+
if ($request === null) {
58+
$request = $this->prophesize(Request::class)->reveal();
59+
}
60+
61+
if (class_exists(RequestEvent::class)) {
62+
$event = new RequestEvent(
63+
$this->prophesize(KernelInterface::class)->reveal(),
64+
$request,
65+
$type,
66+
$this->prophesize(Response::class)->reveal()
67+
);
68+
} else {
69+
$event = new GetResponseEvent(
70+
$this->prophesize(KernelInterface::class)->reveal(),
71+
$request,
72+
$type,
73+
$this->prophesize(Response::class)->reveal()
74+
);
75+
}
76+
77+
return $event;
78+
}
4679
}

test/DependencyInjection/ConfigurationTest.php

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
use Sentry\SentryBundle\Test\BaseTestCase;
99
use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException;
1010
use Symfony\Component\Config\Definition\Processor;
11-
use Symfony\Component\HttpKernel\Kernel;
1211

1312
class ConfigurationTest extends BaseTestCase
1413
{
@@ -60,12 +59,12 @@ public function testConfigurationDefaults(): void
6059
'environment' => '%kernel.environment%',
6160
'in_app_exclude' => [
6261
'%kernel.cache_dir%',
63-
'%kernel.root_dir%/../vendor',
62+
'%kernel.project_dir%/vendor',
6463
],
6564
'integrations' => $defaultSdkValues->getIntegrations(),
6665
'excluded_exceptions' => $defaultSdkValues->getExcludedExceptions(),
6766
'prefixes' => $defaultSdkValues->getPrefixes(),
68-
'project_root' => '%kernel.root_dir%/..',
67+
'project_root' => '%kernel.project_dir%',
6968
'tags' => [],
7069
],
7170
'monolog' => [
@@ -77,11 +76,6 @@ public function testConfigurationDefaults(): void
7776
],
7877
];
7978

80-
if (method_exists(Kernel::class, 'getProjectDir')) {
81-
$expectedDefaults['options']['project_root'] = '%kernel.project_dir%';
82-
$expectedDefaults['options']['in_app_exclude'][1] = '%kernel.project_dir%/vendor';
83-
}
84-
8579
if ($this->classSerializersAreSupported()) {
8680
$expectedDefaults['options']['class_serializers'] = [];
8781
}

0 commit comments

Comments
 (0)