CacheWare::respondWithNoCacheCache()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 7
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 5
nc 1
nop 1
1
<?php
2
/**
3
 * CacheWare (https://github.com/juliangut/cacheware)
4
 * PSR7 cache headers management middleware
5
 *
6
 * @license BSD-3-Clause
7
 * @author Julián Gutiérrez <[email protected]>
8
 */
9
10
namespace Jgut\Middleware;
11
12
use Psr\Http\Message\ResponseInterface;
13
use Psr\Http\Message\ServerRequestInterface;
14
15
/**
16
 * PHP cache headers management middleware.
17
 */
18
class CacheWare
19
{
20
    const CACHE_PUBLIC = 'limit';
21
    const CACHE_PRIVATE = 'private';
22
    const CACHE_PRIVATE_NO_EXPIRE = 'private_no_expire';
23
    const CACHE_NOCACHE = 'nocache';
24
25
    const CACHE_EXPIRED = 'Thu, 19 Nov 1981 08:52:00 GMT';
26
27
    /**
28
     * @var array
29
     */
30
    protected $settings;
31
32
    /**
33
     * Middleware constructor.
34
     *
35
     * @param array $settings
36
     */
37
    public function __construct(array $settings = [])
38
    {
39
        $this->settings = $settings;
40
    }
41
42
    /**
43
     * Execute the middleware.
44
     *
45
     * @param ServerRequestInterface $request
46
     * @param ResponseInterface      $response
47
     * @param callable               $next
48
     *
49
     * @throws \InvalidArgumentException
50
     * @throws \RuntimeException
51
     *
52
     * @return ResponseInterface
53
     */
54
    public function __invoke(ServerRequestInterface $request, ResponseInterface $response, callable $next)
55
    {
56
        // Prevent headers from being automatically sent to client
57
        ini_set('session.use_trans_sid', false);
58
        ini_set('session.use_cookies', true);
59
        ini_set('session.use_only_cookies', true);
60
        ini_set('session.use_strict_mode', false);
61
        ini_set('session.cache_limiter', '');
62
63
        $cacheSettings = array_merge($this->getCacheSettings(), $this->settings);
64
65
        $response = $next($request, $response);
66
67
        return $this->respondWithCacheHeaders($cacheSettings, $response);
68
    }
69
70
    /**
71
     * Retrieve default cache settings.
72
     *
73
     * @return array
0 ignored issues
show
Documentation introduced by
Consider making the return type a bit more specific; maybe use array<string,string|integer>.

This check looks for the generic type array as a return type and suggests a more specific type. This type is inferred from the actual code.

Loading history...
74
     */
75
    protected function getCacheSettings()
76
    {
77
        return [
78
            'limiter' => session_cache_limiter(),
79
            'expire' => session_cache_expire() ?: 180,
80
        ];
81
    }
82
83
    /**
84
     * Add corresponding cache headers to response.
85
     *
86
     * @param array             $settings
87
     * @param ResponseInterface $response
88
     *
89
     * @throws \InvalidArgumentException
90
     *
91
     * @return ResponseInterface
92
     */
93
    protected function respondWithCacheHeaders(array $settings, ResponseInterface $response)
94
    {
95
        switch ($settings['limiter']) {
96
            case static::CACHE_PUBLIC:
97
                return $this->respondWithPublicCache($settings, $response);
98
99
            case static::CACHE_PRIVATE:
100
                return $this->respondWithPrivateCache($settings, $response);
101
102
            case static::CACHE_PRIVATE_NO_EXPIRE:
103
                return $this->respondWithPrivateNoExpireCache($settings, $response);
104
105
            case static::CACHE_NOCACHE:
106
                return $this->respondWithNoCacheCache($response);
107
        }
108
109
        return $response;
110
    }
111
112
    /**
113
     * Add public cache headers to response.
114
     *
115
     * @param array             $settings
116
     * @param ResponseInterface $response
117
     *
118
     * @throws \InvalidArgumentException
119
     *
120
     * @return ResponseInterface
121
     */
122
    protected function respondWithPublicCache(array $settings, ResponseInterface $response)
123
    {
124
        $maxAge = $settings['expire'] ? (int) $settings['expire'] * 60 : 0;
125
126
        $currentDate = new \DateTime('now', new \DateTimeZone('UTC'));
127
        $expireDate = clone $currentDate;
128
        $expireDate->modify('+' . $maxAge . ' seconds');
129
130
        return $response
131
            ->withAddedHeader(
132
                'Expires',
133
                sprintf('expires=%s; max-age=%s', $expireDate->format('D, d M Y H:i:s T'), $maxAge)
134
            )
135
            ->withAddedHeader('Cache-Control', sprintf('public, max-age=%s', $maxAge))
136
            ->withAddedHeader('Last-Modified', $currentDate->format('D, d M Y H:i:s T'));
137
    }
138
139
    /**
140
     * Add private cache headers to response.
141
     *
142
     * @param array             $settings
143
     * @param ResponseInterface $response
144
     *
145
     * @throws \InvalidArgumentException
146
     *
147
     * @return ResponseInterface
148
     */
149
    protected function respondWithPrivateCache(array $settings, ResponseInterface $response)
150
    {
151
        return $this->respondWithPrivateNoExpireCache(
152
            $settings,
153
            $response->withAddedHeader('Expires', static::CACHE_EXPIRED)
154
        );
155
    }
156
157
    /**
158
     * Add private-no-expire cache headers to response.
159
     *
160
     * @param array             $settings
161
     * @param ResponseInterface $response
162
     *
163
     * @throws \InvalidArgumentException
164
     *
165
     * @return ResponseInterface
166
     */
167
    protected function respondWithPrivateNoExpireCache(array $settings, ResponseInterface $response)
168
    {
169
        $maxAge = $settings['expire'] ? (int) $settings['expire'] * 60 : 0;
170
        $currentDate = new \DateTime('now', new \DateTimeZone('UTC'));
171
172
        return $response
173
            ->withAddedHeader('Cache-Control', sprintf('private, max-age=%1$s, pre-check=%1$s', $maxAge))
174
            ->withAddedHeader('Last-Modified', $currentDate->format('D, d M Y H:i:s T'));
175
    }
176
177
    /**
178
     * Add no-cache cache headers to response.
179
     *
180
     * @param ResponseInterface $response
181
     *
182
     * @throws \InvalidArgumentException
183
     *
184
     * @return ResponseInterface
185
     */
186
    protected function respondWithNoCacheCache(ResponseInterface $response)
187
    {
188
        return $response
189
            ->withAddedHeader('Expires', static::CACHE_EXPIRED)
190
            ->withAddedHeader('Cache-Control', 'no-store, no-cache, must-revalidate, post-check=0, pre-check=0')
191
            ->withAddedHeader('Pragma', 'no-cache');
192
    }
193
}
194