diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml
index 9437bd41..09a5c2f8 100644
--- a/.github/workflows/continuous-integration.yml
+++ b/.github/workflows/continuous-integration.yml
@@ -55,10 +55,6 @@ jobs:
symfony-deprecations-helper: "weak"
# Test maintained versions of Symfony
- - dependencies: "php-http/guzzle6-adapter"
- symfony-require: "3.4.*"
- php-version: "7.3"
- symfony-deprecations-helper: "weak"
- dependencies: "php-http/guzzle7-adapter symfony/http-client:^4.4"
symfony-require: "4.4.*"
php-version: "7.3"
diff --git a/CHANGELOG.md b/CHANGELOG.md
index badb86bc..9ff0a57a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -2,9 +2,11 @@
The change log describes what is "Added", "Removed", "Changed" or "Fixed" between each release.
-# 1.24.1 - TBD
-- Fixed deprecation notice in PHP 8.1 by adding `= null` to `\Http\HttplugBundle\Collector\Twig\HttpMessageMarkupExtension`
--
+# 1.25.0 - TBD
+- Added PHP 8.1 support
+- Added Symfony 6 support
+- Removed Symfony 3.x support
+
# 1.24.0 - 2021-10-23
- Changed stopwatch category from default to "httplug", so it's more prominent on Execution timeline view
- Changed tab texts inside profiler so that it shows ports in URL in case it's non-standard
diff --git a/composer.json b/composer.json
index f02f6edc..339e63ce 100644
--- a/composer.json
+++ b/composer.json
@@ -28,18 +28,18 @@
"php": "^7.3 || ^8.0",
"php-http/client-common": "^1.9 || ^2.0",
"php-http/client-implementation": "^1.0",
- "php-http/discovery": "^1.0",
+ "php-http/discovery": "^1.14",
"php-http/httplug": "^1.0 || ^2.0",
"php-http/logger-plugin": "^1.1",
"php-http/message": "^1.4",
"php-http/message-factory": "^1.0.2",
"php-http/stopwatch-plugin": "^1.2",
"psr/http-message": "^1.0",
- "symfony/config": "^3.4.34 || ^4.2.12 || ^5.0",
- "symfony/dependency-injection": "^3.4.34 || ^4.2.12 || ^5.0",
- "symfony/event-dispatcher": "^3.4.34 || ^4.2.12 || ^5.0",
- "symfony/http-kernel": "^3.4.34 || ^4.2.12 || ^5.0",
- "symfony/options-resolver": "^3.4.34 || ^4.2.12 || ^5.0"
+ "symfony/config": "^4.4 || ^5.0 || ^6.0",
+ "symfony/dependency-injection": "^4.4 || ^5.0 || ^6.0",
+ "symfony/event-dispatcher": "^4.4 || ^5.0 || ^6.0",
+ "symfony/http-kernel": "^4.4 || ^5.0 || ^6.0",
+ "symfony/options-resolver": "^4.4 || ^5.0 || ^6.0"
},
"conflict": {
"php-http/guzzle6-adapter": "<1.1",
@@ -53,16 +53,15 @@
"php-http/cache-plugin": "^1.7",
"php-http/mock-client": "^1.2",
"php-http/promise": "^1.0",
- "polishsymfonycommunity/symfony-mocker-container": "^1.0",
- "symfony/browser-kit": "^3.4.34 || ^4.2.12 || ^5.0",
- "symfony/cache": "^3.4.35 || ~4.2.12 || ^4.3.8 || ^5.0",
- "symfony/dom-crawler": "^3.4.34 || ^4.2.12 || ^5.0",
- "symfony/framework-bundle": "^3.4.34 || ^4.2.12 || ^5.0",
- "symfony/http-foundation": "^3.4.35 || ~4.2.12 || ^4.3.8 || ^5.0",
+ "symfony/browser-kit": "^4.4 || ^5.0 || ^6.0",
+ "symfony/cache": "^4.4 || ^5.0 || ^6.0",
+ "symfony/dom-crawler": "^4.4 || ^5.0 || ^6.0",
+ "symfony/framework-bundle": "^4.4 || ^5.0 || ^6.0",
+ "symfony/http-foundation": "^4.4.19 || ^5.0 || ^6.0",
"symfony/phpunit-bridge": "^5.3",
- "symfony/stopwatch": "^3.4.34 || ^4.2.12 || ^5.0",
- "symfony/twig-bundle": "^3.4.34 || ^4.2.12 || ^5.0",
- "symfony/web-profiler-bundle": "^3.4.34 || ^4.2.12 || ^5.0",
+ "symfony/stopwatch": "^4.4 || ^5.0 || ^6.0",
+ "symfony/twig-bundle": "^4.4 || ^5.0 || ^6.0",
+ "symfony/web-profiler-bundle": "^4.4.19 || ^5.0 || ^6.0",
"twig/twig": "^1.41 || ^2.10 || ^3.0"
},
"suggest": {
@@ -95,7 +94,7 @@
]
},
"minimum-stability": "dev",
- "prefer-stable": true,
+ "prefer-stable": false,
"scripts": {
"test": "vendor/bin/simple-phpunit",
"test-ci": "vendor/bin/simple-phpunit --coverage-text --coverage-clover=build/coverage.xml"
diff --git a/src/Collector/Collector.php b/src/Collector/Collector.php
index 71c16b6d..cc4fb23e 100644
--- a/src/Collector/Collector.php
+++ b/src/Collector/Collector.php
@@ -43,7 +43,7 @@ public function reset()
/**
* {@inheritdoc}
*/
- public function getName()
+ public function getName(): string
{
return 'httplug';
}
diff --git a/src/Collector/PluginClientFactoryListener.php b/src/Collector/PluginClientFactoryListener.php
index 44e0b4e0..4f11f482 100644
--- a/src/Collector/PluginClientFactoryListener.php
+++ b/src/Collector/PluginClientFactoryListener.php
@@ -48,7 +48,7 @@ public function onEvent(PluginClientFactoryListenerEventClass $e)
/**
* {@inheritdoc}
*/
- public static function getSubscribedEvents()
+ public static function getSubscribedEvents(): array
{
return [
'kernel.request' => ['onEvent', 1024],
diff --git a/src/DependencyInjection/Configuration.php b/src/DependencyInjection/Configuration.php
index 76a60016..00a9ac54 100644
--- a/src/DependencyInjection/Configuration.php
+++ b/src/DependencyInjection/Configuration.php
@@ -54,15 +54,10 @@ public function __construct($debug)
/**
* {@inheritdoc}
*/
- public function getConfigTreeBuilder()
+ public function getConfigTreeBuilder(): TreeBuilder
{
$treeBuilder = new TreeBuilder('httplug');
- // Keep compatibility with symfony/config < 4.2
- if (!method_exists($treeBuilder, 'getRootNode')) {
- $rootNode = $treeBuilder->root('httplug');
- } else {
- $rootNode = $treeBuilder->getRootNode();
- }
+ $rootNode = $treeBuilder->getRootNode();
$this->configureClients($rootNode);
$this->configureSharedPlugins($rootNode);
@@ -274,12 +269,7 @@ private function configureSharedPlugins(ArrayNodeDefinition $root)
private function createClientPluginNode()
{
$treeBuilder = new TreeBuilder('plugins');
- // Keep compatibility with symfony/config < 4.2
- if (!method_exists($treeBuilder, 'getRootNode')) {
- $node = $treeBuilder->root('plugins');
- } else {
- $node = $treeBuilder->getRootNode();
- }
+ $node = $treeBuilder->getRootNode();
/** @var ArrayNodeDefinition $pluginList */
$pluginList = $node
@@ -610,12 +600,7 @@ private function addSharedPluginNodes(ArrayNodeDefinition $pluginNode, $disableA
private function createAuthenticationPluginNode()
{
$treeBuilder = new TreeBuilder('authentication');
- // Keep compatibility with symfony/config < 4.2
- if (!method_exists($treeBuilder, 'getRootNode')) {
- $node = $treeBuilder->root('authentication');
- } else {
- $node = $treeBuilder->getRootNode();
- }
+ $node = $treeBuilder->getRootNode();
$node
->useAttributeAsKey('name')
@@ -707,12 +692,7 @@ private function validateAuthenticationType(array $expected, array $actual, $aut
private function createCachePluginNode()
{
$builder = new TreeBuilder('config');
- // Keep compatibility with symfony/config < 4.2
- if (!method_exists($builder, 'getRootNode')) {
- $config = $builder->root('config');
- } else {
- $config = $builder->getRootNode();
- }
+ $config = $builder->getRootNode();
$config
->fixXmlConfig('method')
@@ -805,12 +785,7 @@ private function createCachePluginNode()
;
$treeBuilder = new TreeBuilder('cache');
- // Keep compatibility with symfony/config < 4.2
- if (!method_exists($treeBuilder, 'getRootNode')) {
- $cache = $treeBuilder->root('cache');
- } else {
- $cache = $treeBuilder->getRootNode();
- }
+ $cache = $treeBuilder->getRootNode();
$cache
->canBeEnabled()
diff --git a/src/DependencyInjection/HttplugExtension.php b/src/DependencyInjection/HttplugExtension.php
index d9d0d49f..1a8aa0cf 100644
--- a/src/DependencyInjection/HttplugExtension.php
+++ b/src/DependencyInjection/HttplugExtension.php
@@ -23,12 +23,12 @@
use Http\Mock\Client as MockClient;
use Psr\Http\Client\ClientInterface;
use Psr\Http\Message\UriInterface;
+use Symfony\Component\Config\Definition\ConfigurationInterface;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\DependencyInjection\Alias;
use Symfony\Component\DependencyInjection\ChildDefinition;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Definition;
-use Symfony\Component\DependencyInjection\DefinitionDecorator;
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
@@ -382,14 +382,8 @@ private function configureClient(ContainerBuilder $container, $clientName, array
{
$serviceId = 'httplug.client.'.$clientName;
- if (method_exists($container, 'registerAliasForArgument')) {
- $alias = $container->registerAliasForArgument($serviceId, HttpClient::class, $clientName);
-
- $interfaces = class_implements(HttpClient::class) ?? [];
- if (isset($interfaces[ClientInterface::class])) {
- $container->registerAliasForArgument($serviceId, ClientInterface::class, $clientName);
- }
- }
+ $container->registerAliasForArgument($serviceId, HttpClient::class, $clientName);
+ $container->registerAliasForArgument($serviceId, ClientInterface::class, $clientName);
$plugins = [];
foreach ($arguments['plugins'] as $plugin) {
@@ -530,7 +524,7 @@ private function configureAutoDiscoveryClients(ContainerBuilder $container, arra
/**
* {@inheritdoc}
*/
- public function getConfiguration(array $config, ContainerBuilder $container)
+ public function getConfiguration(array $config, ContainerBuilder $container): ?ConfigurationInterface
{
return new Configuration($container->getParameter('kernel.debug'));
}
@@ -547,7 +541,7 @@ private function configurePlugin(ContainerBuilder $container, $serviceId, $plugi
{
$pluginServiceId = $serviceId.'.plugin.'.$pluginName;
- $definition = $this->createChildDefinition('httplug.plugin.'.$pluginName);
+ $definition = new ChildDefinition('httplug.plugin.'.$pluginName);
$this->configurePluginByName($pluginName, $definition, $pluginConfig, $container, $pluginServiceId);
$container->setDefinition($pluginServiceId, $definition);
@@ -564,7 +558,7 @@ private function configureVcrPlugin(ContainerBuilder $container, array $config,
$recordId = $prefix.'.record';
if ('filesystem' === $recorder) {
- $recorderDefinition = $this->createChildDefinition('httplug.plugin.vcr.recorder.filesystem');
+ $recorderDefinition = new ChildDefinition('httplug.plugin.vcr.recorder.filesystem');
$recorderDefinition->replaceArgument(0, $config['fixtures_directory']);
$recorderId = $prefix.'.recorder';
@@ -573,7 +567,7 @@ private function configureVcrPlugin(ContainerBuilder $container, array $config,
if ('default' === $config['naming_strategy']) {
$namingStrategyId = $prefix.'.naming_strategy';
- $namingStrategy = $this->createChildDefinition('httplug.plugin.vcr.naming_strategy.path');
+ $namingStrategy = new ChildDefinition('httplug.plugin.vcr.naming_strategy.path');
if (!empty($config['naming_strategy_options'])) {
$namingStrategy->setArguments([$config['naming_strategy_options']]);
@@ -610,18 +604,4 @@ private function configureVcrPlugin(ContainerBuilder $container, array $config,
return $plugins;
}
-
- /**
- * BC for old Symfony versions. Remove this method and use new ChildDefinition directly when we drop support for Symfony 2.
- *
- * @param string $parent the parent service id
- *
- * @return ChildDefinition|DefinitionDecorator
- */
- private function createChildDefinition($parent)
- {
- $definitionClass = class_exists(ChildDefinition::class) ? ChildDefinition::class : DefinitionDecorator::class;
-
- return new $definitionClass($parent);
- }
}
diff --git a/src/Discovery/ConfiguredClientsStrategyListener.php b/src/Discovery/ConfiguredClientsStrategyListener.php
index 621c03c9..82cefcd8 100644
--- a/src/Discovery/ConfiguredClientsStrategyListener.php
+++ b/src/Discovery/ConfiguredClientsStrategyListener.php
@@ -25,7 +25,7 @@ public function onEvent()
*
* {@inheritdoc}
*/
- public static function getSubscribedEvents()
+ public static function getSubscribedEvents(): array
{
return [
'kernel.request' => ['onEvent', 1024],
diff --git a/src/Resources/config/services.xml b/src/Resources/config/services.xml
index 8cab29a2..a839d134 100644
--- a/src/Resources/config/services.xml
+++ b/src/Resources/config/services.xml
@@ -21,7 +21,7 @@
-
+
diff --git a/tests/Functional/ServiceInstantiationTest.php b/tests/Functional/ServiceInstantiationTest.php
index 9bb7d0f3..35dcfffa 100644
--- a/tests/Functional/ServiceInstantiationTest.php
+++ b/tests/Functional/ServiceInstantiationTest.php
@@ -24,6 +24,7 @@
use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Component\HttpKernel\Kernel;
use Symfony\Component\HttpKernel\KernelEvents;
+use Symfony\Component\HttpKernel\KernelInterface;
use Symfony\Component\HttpKernel\Profiler\Profiler;
class ServiceInstantiationTest extends WebTestCase
@@ -125,7 +126,7 @@ public function testProfilingPsr18Decoration(): void
/**
* {@inheritdoc}
*/
- protected static function bootKernel(array $options = [])
+ protected static function bootKernel(array $options = []): KernelInterface
{
parent::bootKernel($options);
@@ -135,11 +136,7 @@ protected static function bootKernel(array $options = [])
$class = (Kernel::MAJOR_VERSION >= 5) ? RequestEvent::class : GetResponseEvent::class;
$event = new $class(static::$kernel, SymfonyRequest::create('/'), HttpKernelInterface::MASTER_REQUEST);
- if (version_compare(Kernel::VERSION, '4.3.0', '>=')) {
- $dispatcher->dispatch($event, KernelEvents::REQUEST);
- } else {
- $dispatcher->dispatch(KernelEvents::REQUEST, $event);
- }
+ $dispatcher->dispatch($event, KernelEvents::REQUEST);
return static::$kernel;
}
diff --git a/tests/Resources/app/AppKernel.php b/tests/Resources/app/AppKernel.php
index 1b49d0bc..79e89bd4 100644
--- a/tests/Resources/app/AppKernel.php
+++ b/tests/Resources/app/AppKernel.php
@@ -2,18 +2,18 @@
declare(strict_types=1);
-use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait;
use Symfony\Component\Config\Loader\LoaderInterface;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Kernel;
-use Symfony\Component\Routing\RouteCollectionBuilder;
+use Symfony\Component\Routing\Loader\Configurator\RoutingConfigurator;
+use Symfony\Component\Routing\Loader\PhpFileLoader as RoutingPhpFileLoader;
+use Symfony\Component\Routing\Route;
+use Symfony\Component\Routing\RouteCollection;
class AppKernel extends Kernel
{
- use MicroKernelTrait;
-
/**
* @var string
*/
@@ -22,7 +22,7 @@ class AppKernel extends Kernel
/**
* {@inheritdoc}
*/
- public function registerBundles()
+ public function registerBundles(): iterable
{
$bundles = [
new \Symfony\Bundle\FrameworkBundle\FrameworkBundle(),
@@ -37,37 +37,52 @@ public function registerBundles()
return $bundles;
}
- /**
- * {@inheritdoc}
- */
- protected function configureContainer(ContainerBuilder $container, LoaderInterface $loader): void
+ public function registerContainerConfiguration(LoaderInterface $loader)
{
- $loader->load(__DIR__.'/config/config_'.$this->getEnvironment().'.yml');
- if ($this->isDebug()) {
- $loader->load(__DIR__.'/config/config_debug.yml');
- }
+ $loader->load(function (ContainerBuilder $container) use ($loader) {
+ $container->loadFromExtension('framework', [
+ 'router' => [
+ 'resource' => 'kernel::loadRoutes',
+ 'type' => 'service',
+ 'utf8' => true,
+ ],
+ ]);
+
+ $container->register('kernel', static::class)
+ ->addTag('routing.route_loader')
+ ->setAutoconfigured(true)
+ ->setSynthetic(true)
+ ->setPublic(true)
+ ;
+
+ $loader->load(__DIR__.'/config/config_'.$this->getEnvironment().'.yml');
+ if ($this->isDebug()) {
+ $loader->load(__DIR__.'/config/config_debug.yml');
+ }
+ });
}
- /**
- * {@inheritdoc}
- */
- protected function configureRoutes(RouteCollectionBuilder $routes): void
+ public function loadRoutes(LoaderInterface $loader): RouteCollection
{
- $routes->import('@WebProfilerBundle/Resources/config/routing/wdt.xml', '/_wdt');
- $routes->import('@WebProfilerBundle/Resources/config/routing/profiler.xml', '/_profiler');
-
- if (Kernel::MAJOR_VERSION < 4 || (Kernel::MAJOR_VERSION === 4 && Kernel::MINOR_VERSION === 0)) {
- $routes->add('/', 'kernel:indexAction');
- } else {
- // If 4.1+
- $routes->add('/', 'kernel::indexAction');
- }
+ $file = (new \ReflectionObject($this))->getFileName();
+ /* @var RoutingPhpFileLoader $kernelLoader */
+ $kernelLoader = $loader->getResolver()->resolve($file, 'php');
+ $kernelLoader->setCurrentDir(\dirname($file));
+
+ $collection = new RouteCollection();
+ $collection->add('/', new Route('/', ['_controller' => 'kernel::indexAction']));
+
+ $routes = new RoutingConfigurator($collection, $kernelLoader, $file, $file);
+ $routes->import('@WebProfilerBundle/Resources/config/routing/wdt.xml')->prefix('_wdt');
+ $routes->import('@WebProfilerBundle/Resources/config/routing/profiler.xml')->prefix('_profiler');
+
+ return $collection;
}
/**
* {@inheritdoc}
*/
- public function getCacheDir()
+ public function getCacheDir(): string
{
if (null === self::$cacheDir) {
self::$cacheDir = uniqid('cache');
@@ -79,19 +94,11 @@ public function getCacheDir()
/**
* {@inheritdoc}
*/
- public function getLogDir()
+ public function getLogDir(): string
{
return sys_get_temp_dir().'/httplug-bundle/logs';
}
- /**
- * {@inheritdoc}
- */
- protected function getContainerBaseClass()
- {
- return '\PSS\SymfonyMockerContainer\DependencyInjection\MockerContainer';
- }
-
public function indexAction()
{
return new Response();
diff --git a/tests/Unit/DependencyInjection/ConfigurationTest.php b/tests/Unit/DependencyInjection/ConfigurationTest.php
index 35f56953..30796ba8 100644
--- a/tests/Unit/DependencyInjection/ConfigurationTest.php
+++ b/tests/Unit/DependencyInjection/ConfigurationTest.php
@@ -111,21 +111,6 @@ protected function getConfiguration(): ConfigurationInterface
return new Configuration(true);
}
- public function testEmptyConfiguration(): void
- {
- $formats = array_map(function ($path) {
- return __DIR__.'/../../Resources/Fixtures/'.$path;
- }, [
- 'config/empty.yml',
- 'config/empty.xml',
- 'config/empty.php',
- ]);
-
- foreach ($formats as $format) {
- $this->assertProcessedConfigurationEquals($this->emptyConfig, [$format]);
- }
- }
-
public function testSupportsAllConfigFormats(): void
{
if (!class_exists(Client::class)) {
diff --git a/tests/Unit/DependencyInjection/HttplugExtensionTest.php b/tests/Unit/DependencyInjection/HttplugExtensionTest.php
index 3858010a..e65e977b 100644
--- a/tests/Unit/DependencyInjection/HttplugExtensionTest.php
+++ b/tests/Unit/DependencyInjection/HttplugExtensionTest.php
@@ -11,7 +11,6 @@
use Http\HttplugBundle\DependencyInjection\HttplugExtension;
use Matthias\SymfonyDependencyInjectionTest\PhpUnit\AbstractExtensionTestCase;
use Symfony\Component\DependencyInjection\Reference;
-use Symfony\Component\HttpKernel\Kernel;
/**
* @author David Buchmann
@@ -354,14 +353,6 @@ public function testClientShouldHaveDefaultVisibility(): void
]);
$this->assertContainerBuilderHasService('httplug.client.acme');
-
- if (version_compare(Kernel::VERSION, '3.4', '>=')) {
- // Symfony made services private by default starting from 3.4
- $this->assertTrue($this->container->getDefinition('httplug.client.acme')->isPrivate());
- } else {
- // Legacy Symfony
- $this->assertTrue($this->container->getDefinition('httplug.client.acme')->isPublic());
- }
}
public function testFlexibleClientShouldBePrivateByDefault(): void
@@ -418,11 +409,6 @@ public function testClientCanBePublic(): void
$this->assertContainerBuilderHasService('httplug.client.acme');
$this->assertTrue($this->container->getDefinition('httplug.client.acme')->isPublic());
-
- if (version_compare(Kernel::VERSION, '3.4', '>=')) {
- // Symfony made services private by default starting from 3.4
- $this->assertFalse($this->container->getDefinition('httplug.client.acme')->isPrivate());
- }
}
public function testFlexibleClientCanBePublic(): void
@@ -438,11 +424,6 @@ public function testFlexibleClientCanBePublic(): void
$this->assertContainerBuilderHasService('httplug.client.acme');
$this->assertTrue($this->container->getDefinition('httplug.client.acme.flexible')->isPublic());
-
- if (version_compare(Kernel::VERSION, '3.4', '>=')) {
- // Symfony made services private by default starting from 3.4
- $this->assertFalse($this->container->getDefinition('httplug.client.acme.flexible')->isPrivate());
- }
}
public function testHttpMethodsClientCanBePublic(): void
@@ -458,11 +439,6 @@ public function testHttpMethodsClientCanBePublic(): void
$this->assertContainerBuilderHasService('httplug.client.acme');
$this->assertTrue($this->container->getDefinition('httplug.client.acme.http_methods')->isPublic());
-
- if (version_compare(Kernel::VERSION, '3.4', '>=')) {
- // Symfony made services private by default starting from 3.4
- $this->assertFalse($this->container->getDefinition('httplug.client.acme.http_methods')->isPrivate());
- }
}
public function testBatchClientCanBePublic(): void
@@ -478,11 +454,6 @@ public function testBatchClientCanBePublic(): void
$this->assertContainerBuilderHasService('httplug.client.acme');
$this->assertTrue($this->container->getDefinition('httplug.client.acme.batch_client')->isPublic());
-
- if (version_compare(Kernel::VERSION, '3.4', '>=')) {
- // Symfony made services private by default starting from 3.4
- $this->assertFalse($this->container->getDefinition('httplug.client.acme.batch_client')->isPrivate());
- }
}
public function testClientIsTaggedWithHttplugClientTag(): void