Passed
Push — main ( ced7fb...8c5693 )
by Dimitri
13:03 queued 42s
created

ResponseCache::make()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 16
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 9
c 1
b 0
f 0
nc 3
nop 2
dl 0
loc 16
rs 9.9666
1
<?php
2
3
/**
4
 * This file is part of Blitz PHP framework.
5
 *
6
 * (c) 2022 Dimitri Sitchet Tomkeu <[email protected]>
7
 *
8
 * For the full copyright and license information, please view
9
 * the LICENSE file that was distributed with this source code.
10
 */
11
12
namespace BlitzPHP\Cache;
13
14
use Exception;
15
use Psr\Http\Message\RequestInterface;
0 ignored issues
show
Bug introduced by
The type Psr\Http\Message\RequestInterface was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
16
use Psr\Http\Message\ResponseInterface;
0 ignored issues
show
Bug introduced by
The type Psr\Http\Message\ResponseInterface was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
17
use Psr\Http\Message\ServerRequestInterface;
0 ignored issues
show
Bug introduced by
The type Psr\Http\Message\ServerRequestInterface was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
18
use Psr\SimpleCache\CacheInterface;
0 ignored issues
show
Bug introduced by
This use statement conflicts with another class in this namespace, BlitzPHP\Cache\CacheInterface. Consider defining an alias.

Let?s assume that you have a directory layout like this:

.
|-- OtherDir
|   |-- Bar.php
|   `-- Foo.php
`-- SomeDir
    `-- Foo.php

and let?s assume the following content of Bar.php:

// Bar.php
namespace OtherDir;

use SomeDir\Foo; // This now conflicts the class OtherDir\Foo

If both files OtherDir/Foo.php and SomeDir/Foo.php are loaded in the same runtime, you will see a PHP error such as the following:

PHP Fatal error:  Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.php

However, as OtherDir/Foo.php does not necessarily have to be loaded and the error is only triggered if it is loaded before OtherDir/Bar.php, this problem might go unnoticed for a while. In order to prevent this error from surfacing, you must import the namespace with a different alias:

// Bar.php
namespace OtherDir;

use SomeDir\Foo as SomeDirFoo; // There is no conflict anymore.
Loading history...
19
20
/**
21
 * Web Page Caching
22
 */
23
final class ResponseCache
24
{
25
    /**
26
     * Cache time to live.
27
     *
28
     * @var int seconds
29
     */
30
    private int $ttl = 0;
31
32
    /**
33
     * @param bool|string[] $cacheQueryString Whether to take the URL query string into consideration when generating output cache files. 
34
	 * 		Valid options are:
35
     *			false      = Disabled
36
     *    		true       = Enabled, take all query parameters into account.
37
	 *          		        Please be aware that this may result in numerous cache
38
     *                 			files generated for the same page over and over again.
39
     *    		array('q') = Enabled, but only take into account the specified list of query parameters.
40
     */
41
    public function __construct(private CacheInterface $cache, private bool|array $cacheQueryString = false)
42
    {
43
    }
44
45
    public function setTtl(int $ttl): self
46
    {
47
        $this->ttl = $ttl;
48
49
        return $this;
50
    }
51
52
    /**
53
     * Generates the cache key to use from the current request.
54
     *
55
     * @internal for testing purposes only
56
     */
57
    public function generateCacheKey(RequestInterface $request): string
58
    {
59
        $uri = clone $request->getUri();
60
61
		// @todo implementation de la recuperation des queriestring
62
        /* $query = $this->cacheQueryString
63
            ? $uri->getQuery(is_array($this->cacheQueryString) ? ['only' => $this->cacheQueryString] : [])
64
            : ''; */
65
66
		$query = '';
67
68
        return md5($uri->withFragment('')->withQuery($query));
69
    }
70
71
    /**
72
     * Caches the response.
73
     */
74
    public function make(ServerRequestInterface $request, ResponseInterface $response): bool
75
    {
76
        if ($this->ttl === 0) {
77
            return true;
78
        }
79
80
		$headers = [];
81
82
        foreach (array_keys($response->getHeaders()) as $header) {
83
            $headers[$header] = $response->getHeaderLine($header);
84
        }
85
86
        return $this->cache->set(
87
            $this->generateCacheKey($request),
88
            serialize(['headers' => $headers, 'output' => $response->getBody()->getContents()]),
89
            $this->ttl
90
        );
91
    }
92
93
    /**
94
     * Gets the cached response for the request.
95
     */
96
    public function get(ServerRequestInterface $request, ResponseInterface $response): ?ResponseInterface
97
    {
98
		if ($cachedResponse = $this->cache->get($this->generateCacheKey($request))) {
99
            $cachedResponse = unserialize($cachedResponse);
100
101
			if (! is_array($cachedResponse) || ! isset($cachedResponse['output']) || ! isset($cachedResponse['headers'])) {
102
                throw new Exception('Erreur lors de la désérialisation du cache de page');
103
            }
104
105
            $headers = $cachedResponse['headers'];
106
            $output  = $cachedResponse['output'];
107
108
			// Effacer tous les en-têtes par défaut
109
            foreach (array_keys($response->getHeaders()) as $key) {
110
                $response = $response->withoutHeader($key);
111
            }
112
113
            // Définir les en-têtes mis en cache
114
            foreach ($headers as $name => $value) {
115
                $response = $response->withHeader($name, $value);
116
            }
117
			
118
			return $response->withBody(to_stream($output));
0 ignored issues
show
Bug introduced by
The function to_stream was not found. Maybe you did not declare it correctly or list all dependencies? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

118
			return $response->withBody(/** @scrutinizer ignore-call */ to_stream($output));
Loading history...
119
        }
120
121
        return null;
122
    }
123
}
124