Skip to content

Commit

Permalink
[TASK] Move GuzzleClientFactory into the container
Browse files Browse the repository at this point in the history
This is just a small clean up to make more things injectable.
Enables further work.

Resolves: #96742
Releases: main
Change-Id: I3db2a1e26638a866bebc8404bc4419e15dcd5ba6
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/73271
Tested-by: core-ci <typo3@b13.com>
Tested-by: Christian Kuhn <lolli@schwarzbu.ch>
Tested-by: Benjamin Franzke <bfr@qbus.de>
Reviewed-by: crell <larry@garfieldtech.com>
Reviewed-by: Christian Kuhn <lolli@schwarzbu.ch>
Reviewed-by: Benjamin Franzke <bfr@qbus.de>
  • Loading branch information
Crell authored and bnf committed Feb 4, 2022
1 parent 02ffdb9 commit 5e47529
Show file tree
Hide file tree
Showing 9 changed files with 37 additions and 25 deletions.
5 changes: 2 additions & 3 deletions typo3/sysext/core/Classes/Http/Client/GuzzleClientFactory.php
Expand Up @@ -20,7 +20,6 @@
use GuzzleHttp\Client;
use GuzzleHttp\ClientInterface;
use GuzzleHttp\HandlerStack;
use TYPO3\CMS\Core\Utility\GeneralUtility;

/**
* @internal
Expand All @@ -31,7 +30,7 @@ class GuzzleClientFactory
* Creates the client to do requests
* @return ClientInterface
*/
public static function getClient(): ClientInterface
public function getClient(): ClientInterface
{
$httpOptions = $GLOBALS['TYPO3_CONF_VARS']['HTTP'];
$httpOptions['verify'] = filter_var($httpOptions['verify'], FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE) ?? $httpOptions['verify'];
Expand All @@ -44,6 +43,6 @@ public static function getClient(): ClientInterface
$httpOptions['handler'] = $stack;
}

return GeneralUtility::makeInstance(Client::class, $httpOptions);
return new Client($httpOptions);
}
}
13 changes: 8 additions & 5 deletions typo3/sysext/core/Classes/Http/RequestFactory.php
Expand Up @@ -24,11 +24,15 @@
use TYPO3\CMS\Core\Http\Client\GuzzleClientFactory;

/**
* Class RequestFactory to create Request objects
* Returns PSR-7 Request objects
* Front-end for sending requests, using PSR-7.
*/
class RequestFactory implements RequestFactoryInterface
{
public function __construct(
private readonly GuzzleClientFactory $guzzleFactory,
) {
}

/**
* Create a new request.
*
Expand All @@ -42,7 +46,7 @@ public function createRequest(string $method, $uri): RequestInterface
}

/**
* Create a guzzle request object with our custom implementation
* Create a Guzzle request object with our custom implementation
*
* @param string $uri the URI to request
* @param string $method the HTTP method (defaults to GET)
Expand All @@ -51,7 +55,6 @@ public function createRequest(string $method, $uri): RequestInterface
*/
public function request(string $uri, string $method = 'GET', array $options = []): ResponseInterface
{
$client = GuzzleClientFactory::getClient();
return $client->request($method, $uri, $options);
return $this->guzzleFactory->getClient()->request($method, $uri, $options);
}
}
10 changes: 9 additions & 1 deletion typo3/sysext/core/Classes/ServiceProvider.php
Expand Up @@ -60,6 +60,7 @@ public function getFactories(): array
Crypto\PasswordHashing\PasswordHashFactory::class => [ static::class, 'getPasswordHashFactory' ],
EventDispatcher\EventDispatcher::class => [ static::class, 'getEventDispatcher' ],
EventDispatcher\ListenerProvider::class => [ static::class, 'getEventListenerProvider' ],
Http\Client\GuzzleClientFactory::class => [ static::class, 'getGuzzleClientFactory' ],
Http\MiddlewareStackResolver::class => [ static::class, 'getMiddlewareStackResolver' ],
Http\RequestFactory::class => [ static::class, 'getRequestFactory' ],
Imaging\IconFactory::class => [ static::class, 'getIconFactory' ],
Expand Down Expand Up @@ -484,9 +485,16 @@ public static function getTypoScriptService(ContainerInterface $container): Typo
return self::new($container, TypoScript\TypoScriptService::class);
}

public static function getGuzzleClientFactory(ContainerInterface $container): Http\Client\GuzzleClientFactory
{
return new Http\Client\GuzzleClientFactory();
}

public static function getRequestFactory(ContainerInterface $container): Http\RequestFactory
{
return new Http\RequestFactory();
return new Http\RequestFactory(
$container->get(Http\Client\GuzzleClientFactory::class)
);
}

public static function getMiddlewareStackResolver(ContainerInterface $container): Http\MiddlewareStackResolver
Expand Down
3 changes: 2 additions & 1 deletion typo3/sysext/core/Configuration/Services.yaml
Expand Up @@ -351,8 +351,9 @@ services:
public: true

# External dependencies

GuzzleHttp\Client:
factory: ['TYPO3\CMS\Core\Http\Client\GuzzleClientFactory', 'getClient']
factory: ['@TYPO3\CMS\Core\Http\Client\GuzzleClientFactory', 'getClient']
Masterminds\HTML5:
public: true
factory: ['TYPO3\CMS\Core\DependencyInjection\CommonFactory', 'createHtml5Parser']
11 changes: 6 additions & 5 deletions typo3/sysext/core/Tests/Unit/Http/RequestFactoryTest.php
Expand Up @@ -19,6 +19,7 @@

use Psr\Http\Message\RequestFactoryInterface;
use Psr\Http\Message\RequestInterface;
use TYPO3\CMS\Core\Http\Client\GuzzleClientFactory;
use TYPO3\CMS\Core\Http\RequestFactory;
use TYPO3\TestingFramework\Core\Unit\UnitTestCase;

Expand All @@ -32,7 +33,7 @@ class RequestFactoryTest extends UnitTestCase
*/
public function implementsPsr17FactoryInterface(): void
{
$factory = new RequestFactory();
$factory = new RequestFactory(new GuzzleClientFactory());
self::assertInstanceOf(RequestFactoryInterface::class, $factory);
}

Expand All @@ -41,7 +42,7 @@ public function implementsPsr17FactoryInterface(): void
*/
public function requestHasMethodSet(): void
{
$factory = new RequestFactory();
$factory = new RequestFactory(new GuzzleClientFactory());
$request = $factory->createRequest('POST', '/');
self::assertSame('POST', $request->getMethod());
}
Expand All @@ -51,7 +52,7 @@ public function requestHasMethodSet(): void
*/
public function requestFactoryHasAWritableEmptyBody(): void
{
$factory = new RequestFactory();
$factory = new RequestFactory(new GuzzleClientFactory());
$request = $factory->createRequest('GET', '/');
$body = $request->getBody();

Expand Down Expand Up @@ -89,7 +90,7 @@ public function constructorRaisesExceptionForInvalidUri($uri): void
{
$this->expectException(\InvalidArgumentException::class);
$this->expectExceptionCode(1436717272);
$factory = new RequestFactory();
$factory = new RequestFactory(new GuzzleClientFactory());
$factory->createRequest('GET', $uri);
}

Expand All @@ -100,7 +101,7 @@ public function raisesExceptionForInvalidMethod(): void
{
$this->expectException(\InvalidArgumentException::class);
$this->expectExceptionCode(1436717275);
$factory = new RequestFactory();
$factory = new RequestFactory(new GuzzleClientFactory());
$factory->createRequest('BOGUS-BODY', '/');
}
}
3 changes: 2 additions & 1 deletion typo3/sysext/core/Tests/Unit/Site/Entity/SiteTest.php
Expand Up @@ -29,6 +29,7 @@
use TYPO3\CMS\Core\Error\PageErrorHandler\PageContentErrorHandler;
use TYPO3\CMS\Core\Error\PageErrorHandler\PageErrorHandlerInterface;
use TYPO3\CMS\Core\Error\PageErrorHandler\PageErrorHandlerNotConfiguredException;
use TYPO3\CMS\Core\Http\Client\GuzzleClientFactory;
use TYPO3\CMS\Core\Http\RequestFactory;
use TYPO3\CMS\Core\Http\ResponseFactory;
use TYPO3\CMS\Core\Http\Uri;
Expand Down Expand Up @@ -204,7 +205,7 @@ public function __construct()
$container = new Container();
$container->set(Application::class, $app);
$container->set(Features::class, new Features());
$container->set(RequestFactory::class, new RequestFactory());
$container->set(RequestFactory::class, new RequestFactory(new GuzzleClientFactory()));
$container->set(ResponseFactoryInterface::class, new ResponseFactory());
$container->set(LinkService::class, $link);
$container->set(SiteFinder::class, $siteFinder);
Expand Down
11 changes: 3 additions & 8 deletions typo3/sysext/linkvalidator/Classes/Linktype/ExternalLinktype.php
Expand Up @@ -88,19 +88,14 @@ class ExternalLinktype extends AbstractLinktype
*/
protected int $timeout = 0;

/**
* @var RequestFactory
*/
protected $requestFactory;

/**
* @var array
*/
protected $errorParams = [];

public function __construct(RequestFactory $requestFactory = null)
{
$this->requestFactory = $requestFactory ?: GeneralUtility::makeInstance(RequestFactory::class);
public function __construct(
protected readonly RequestFactory $requestFactory,
) {
}

public function setAdditionalConfig(array $config): void
Expand Down
3 changes: 3 additions & 0 deletions typo3/sysext/linkvalidator/Configuration/Services.yaml
Expand Up @@ -15,6 +15,9 @@ services:
TYPO3\CMS\Linkvalidator\LinkAnalyzer:
public: true

TYPO3\CMS\Linkvalidator\Linktype\ExternalLinktype:
public: true

TYPO3\CMS\Linkvalidator\Repository\BrokenLinkRepository:
public: true

Expand Down
Expand Up @@ -23,6 +23,7 @@
use Prophecy\Argument;
use Prophecy\PhpUnit\ProphecyTrait;
use Prophecy\Prophecy\ObjectProphecy;
use TYPO3\CMS\Core\Http\Client\GuzzleClientFactory;
use TYPO3\CMS\Core\Http\RequestFactory;
use TYPO3\CMS\Core\Localization\LanguageService;
use TYPO3\CMS\Core\Utility\GeneralUtility;
Expand Down Expand Up @@ -200,7 +201,7 @@ public function preprocessUrlsDataProvider(): \Generator
*/
public function preprocessUrlReturnsCorrectString(string $inputUrl, $expectedResult): void
{
$subject = new ExternalLinktype();
$subject = new ExternalLinktype(new RequestFactory(new GuzzleClientFactory()));
$method = new \ReflectionMethod($subject, 'preprocessUrl');
$method->setAccessible(true);
$result = $method->invokeArgs($subject, [$inputUrl]);
Expand Down

0 comments on commit 5e47529

Please sign in to comment.