Completed
Pull Request — master (#419)
by Yanick
14:06 queued 03:35
created

KernelClient::__construct()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 15
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
b 0
f 0
dl 0
loc 15
rs 9.2
cc 4
eloc 8
nc 4
nop 2
1
<?php
2
3
/*
4
 * This file is part of the FOSHttpCache package.
5
 *
6
 * (c) FriendsOfSymfony <http://friendsofsymfony.github.com/>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace FOS\HttpCache\SymfonyCache;
13
14
use Http\Client\HttpAsyncClient;
15
use Http\Discovery\MessageFactoryDiscovery;
16
use Http\Message\ResponseFactory;
17
use Http\Promise\FulfilledPromise;
18
use Psr\Http\Message\RequestInterface;
19
use Symfony\Bridge\PsrHttpMessage\Factory\DiactorosFactory;
20
use Symfony\Bridge\PsrHttpMessage\Factory\HttpFoundationFactory;
21
use Symfony\Component\HttpFoundation\Request;
22
use Symfony\Component\HttpKernel\HttpKernelInterface;
23
use Zend\Diactoros\ServerRequest;
24
25
/**
26
 * An implementation of HttpAsyncClient that allows direct routing through the
27
 * Symfony HttpCache kernel without executing a real HTTP request.
28
 * It uses the HttpFoundationFactory and the Zend DiactorosFactory to convert
29
 * between PSR-7 requests and responses. Both are optional dependencies of this
30
 * package thus existence of the respective classes is checked for in the
31
 * constructor of this client. It is only needed if you have a single node
32
 * setup of Symfony and serves as kind of a shortcut for easier configuration.
33
 * If you use Varnish or have a multiple node Symfony setup, this class is entirely
34
 * useless to you and you can happily ignore it.
35
 *
36
 * @author Yanick Witschi <[email protected]>
37
 */
38
class KernelClient implements HttpAsyncClient
39
{
40
    /**
41
     * @var HttpCacheAwareKernelInterface
42
     */
43
    private $kernel;
44
45
    /**
46
     * @var HttpFoundationFactory
47
     */
48
    private $httpFoundationFactory;
49
50
    /**
51
     * @var ResponseFactory
52
     */
53
    private $psr7Factory;
54
55
    /**
56
     * KernelClient constructor.
57
     *
58
     * @param HttpCacheAwareKernelInterface $kernel
59
     */
60
    public function __construct(HttpCacheAwareKernelInterface $kernel, ResponseFactory $responseFactory = null)
61
    {
62
        $this->kernel = $kernel;
63
64
        if (!class_exists(HttpFoundationFactory::class)) {
65
            throw new \RuntimeException('Install symfony/psr-http-message-bridge to use this client.');
66
        }
67
68
        if (!class_exists(ResponseFactory::class)) {
69
            throw new \RuntimeException('Install a php-http/message-factory package to use this client.');
70
        }
71
72
        $this->httpFoundationFactory = new HttpFoundationFactory();
73
        $this->psr7Factory = $responseFactory ?: MessageFactoryDiscovery::find();
74
    }
75
76
    /**
77
     * Converts a PSR-7 request to a Symfony HttpFoundation request, runs
78
     * it through the HttpCache kernel and converts the response back to a PSR-7
79
     * response.
80
     *
81
     * {@inheritdoc}
82
     */
83
    public function sendAsyncRequest(RequestInterface $request)
84
    {
85
        $symfonyRequest = Request::createFromGlobals();
86
        $symfonyRequest->server->set('REMOTE_ADDR', '127.0.0.1');
87
88
        $query = [];
89
        $parts = explode('&', $request->getUri()->getQuery());
90
        foreach ($parts as $part) {
91
            $chunks = explode('=', $part, 2);
92
            $query[$chunks[0]] = $chunks[1];
93
        }
94
95
        $serverRequest = new ServerRequest(
96
            $symfonyRequest->server->all(),
97
            [],
98
            $request->getUri(),
99
            $request->getMethod(),
100
            $request->getBody(),
101
            $request->getHeaders(),
102
            $symfonyRequest->cookies->all(),
103
            $query
104
        );
105
106
        $symfonyRequest = $this->httpFoundationFactory->createRequest($serverRequest);
107
        $symfonyResponse = $this->kernel->getHttpCache()->handle($symfonyRequest, HttpKernelInterface::MASTER_REQUEST, false);
108
        $psrResponse = $this->psr7Factory->createResponse($symfonyResponse);
0 ignored issues
show
Documentation introduced by
$symfonyResponse is of type object<Symfony\Component\HttpFoundation\Response>, but the function expects a integer.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
109
110
        return new FulfilledPromise($psrResponse);
111
    }
112
}
113