Passed
Push — master ( 16e851...25995c )
by Daniel
09:34
created

HTTP::augmentState()   B

Complexity

Conditions 10
Paths 33

Size

Total Lines 43
Code Lines 22

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 10
eloc 22
nc 33
nop 2
dl 0
loc 43
rs 7.6666
c 0
b 0
f 0

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace SilverStripe\Control;
4
5
use SilverStripe\Assets\File;
6
use SilverStripe\Control\Middleware\ChangeDetectionMiddleware;
7
use SilverStripe\Control\Middleware\HTTPCacheControlMiddleware;
8
use SilverStripe\Core\Config\Config;
9
use SilverStripe\Core\Config\Configurable;
10
use SilverStripe\Core\Convert;
11
use InvalidArgumentException;
12
use finfo;
13
use SilverStripe\Core\Injector\Injector;
14
use SilverStripe\Dev\Deprecation;
15
16
/**
17
 * A class with HTTP-related helpers. Like Debug, this is more a bundle of methods than a class.
18
 */
19
class HTTP
20
{
21
    use Configurable;
22
23
    /**
24
     * @deprecated 4.2..5.0 Use HTTPCacheControlMiddleware::singleton()->setMaxAge($age) instead
25
     * @var int
26
     */
27
    protected static $cache_age = 0;
28
29
    /**
30
     * @deprecated 4.2..5.0 Handled by HTTPCacheControlMiddleware
31
     * @var int
32
     */
33
    protected static $modification_date = null;
34
35
    /**
36
     * @deprecated 4.2..5.0 Handled by ChangeDetectionMiddleware
37
     * @var string
38
     */
39
    protected static $etag = null;
40
41
    /**
42
     * @config
43
     * @var bool
44
     * @deprecated 4.2..5.0 'HTTP.cache_ajax_requests config is deprecated.
45
     * Use HTTPCacheControlMiddleware::disableCache() instead'
46
     */
47
    private static $cache_ajax_requests = false;
0 ignored issues
show
introduced by
The private property $cache_ajax_requests is not used, and could be removed.
Loading history...
48
49
    /**
50
     * @config
51
     * @var bool
52
     * @deprecated 4.2..5.0 Use HTTPCacheControlMiddleware.defaultState/.defaultForcingLevel instead
53
     */
54
    private static $disable_http_cache = false;
0 ignored issues
show
introduced by
The private property $disable_http_cache is not used, and could be removed.
Loading history...
55
56
    /**
57
     * Set to true to disable all deprecated HTTP Cache settings
58
     *
59
     * @var bool
60
     */
61
    private static $ignoreDeprecatedCaching = false;
0 ignored issues
show
introduced by
The private property $ignoreDeprecatedCaching is not used, and could be removed.
Loading history...
62
63
    /**
64
     * Mapping of extension to mime types
65
     *
66
     * @var array
67
     * @config
68
     */
69
    private static $MimeTypes = [];
0 ignored issues
show
introduced by
The private property $MimeTypes is not used, and could be removed.
Loading history...
70
71
    /**
72
     * List of names to add to the Cache-Control header.
73
     *
74
     * @see HTTPCacheControlMiddleware::__construct()
75
     * @config
76
     * @var array Keys are cache control names, values are boolean flags
77
     */
78
    private static $cache_control = [];
0 ignored issues
show
introduced by
The private property $cache_control is not used, and could be removed.
Loading history...
79
80
    /**
81
     * Vary string; A comma separated list of var header names
82
     *
83
     * @deprecated 4.2..5.0 Handled by HTTPCacheMiddleware instead
84
     * @config
85
     * @var string|null
86
     */
87
    private static $vary = null;
0 ignored issues
show
introduced by
The private property $vary is not used, and could be removed.
Loading history...
88
89
    /**
90
     * Turns a local system filename into a URL by comparing it to the script filename.
91
     *
92
     * @param string $filename
93
     * @return string
94
     */
95
    public static function filename2url($filename)
96
    {
97
        $filename = realpath($filename);
98
        if (!$filename) {
99
            return null;
100
        }
101
102
        // Filter files outside of the webroot
103
        $base = realpath(BASE_PATH);
104
        $baseLength = strlen($base);
105
        if (substr($filename, 0, $baseLength) !== $base) {
106
            return null;
107
        }
108
109
        $relativePath = ltrim(substr($filename, $baseLength), '/\\');
110
        return Director::absoluteURL($relativePath);
111
    }
112
113
    /**
114
     * Turn all relative URLs in the content to absolute URLs.
115
     *
116
     * @param string $html
117
     *
118
     * @return string
119
     */
120
    public static function absoluteURLs($html)
121
    {
122
        $html = str_replace('$CurrentPageURL', Controller::curr()->getRequest()->getURL(), $html);
123
        return HTTP::urlRewriter($html, function ($url) {
0 ignored issues
show
Coding Style introduced by
As per coding style, self should be used for accessing local static members.

This check looks for accesses to local static members using the fully qualified name instead of self::.

<?php

class Certificate {
    const TRIPLEDES_CBC = 'ASDFGHJKL';

    private $key;

    public function __construct()
    {
        $this->key = Certificate::TRIPLEDES_CBC;
    }
}

While this is perfectly valid, the fully qualified name of Certificate::TRIPLEDES_CBC could just as well be replaced by self::TRIPLEDES_CBC. Referencing local members with self:: assured the access will still work when the class is renamed, makes it perfectly clear that the member is in fact local and will usually be shorter.

Loading history...
124
            //no need to rewrite, if uri has a protocol (determined here by existence of reserved URI character ":")
125
            if (preg_match('/^\w+:/', $url)) {
126
                return $url;
127
            }
128
            return Director::absoluteURL($url, true);
0 ignored issues
show
Bug introduced by
true of type true is incompatible with the type string expected by parameter $relativeParent of SilverStripe\Control\Director::absoluteURL(). ( Ignorable by Annotation )

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

128
            return Director::absoluteURL($url, /** @scrutinizer ignore-type */ true);
Loading history...
129
        });
130
    }
131
132
    /**
133
     * Rewrite all the URLs in the given content, evaluating the given string as PHP code.
134
     *
135
     * Put $URL where you want the URL to appear, however, you can't embed $URL in strings, for example:
136
     * <ul>
137
     * <li><code>'"../../" . $URL'</code></li>
138
     * <li><code>'myRewriter($URL)'</code></li>
139
     * <li><code>'(substr($URL, 0, 1)=="/") ? "../" . substr($URL, 1) : $URL'</code></li>
140
     * </ul>
141
     *
142
     * As of 3.2 $code should be a callable which takes a single parameter and returns the rewritten,
143
     * for example:
144
     * <code>
145
     * function($url) {
146
     *      return Director::absoluteURL($url, true);
147
     * }
148
     * </code>
149
     *
150
     * @param string $content The HTML to search for links to rewrite.
151
     * @param callable $code Either a string that can evaluate to an expression to rewrite links
152
     * (depreciated), or a callable that takes a single parameter and returns the rewritten URL.
153
     *
154
     * @return string The content with all links rewritten as per the logic specified in $code.
155
     */
156
    public static function urlRewriter($content, $code)
157
    {
158
        if (!is_callable($code)) {
159
            throw new InvalidArgumentException(
160
                'HTTP::urlRewriter expects a callable as the second parameter'
161
            );
162
        }
163
164
        // Replace attributes
165
        $attribs = ["src", "background", "a" => "href", "link" => "href", "base" => "href"];
166
        $regExps = [];
167
        foreach ($attribs as $tag => $attrib) {
168
            if (!is_numeric($tag)) {
169
                $tagPrefix = "$tag ";
170
            } else {
171
                $tagPrefix = "";
172
            }
173
174
            $regExps[] = "/(<{$tagPrefix}[^>]*$attrib *= *\")([^\"]*)(\")/i";
175
            $regExps[] = "/(<{$tagPrefix}[^>]*$attrib *= *')([^']*)(')/i";
176
            $regExps[] = "/(<{$tagPrefix}[^>]*$attrib *= *)([^\"' ]*)( )/i";
177
        }
178
        // Replace css styles
179
        // @todo - http://www.css3.info/preview/multiple-backgrounds/
180
        $styles = ['background-image', 'background', 'list-style-image', 'list-style', 'content'];
181
        foreach ($styles as $style) {
182
            $regExps[] = "/($style:[^;]*url *\\(\")([^\"]+)(\"\\))/i";
183
            $regExps[] = "/($style:[^;]*url *\\(')([^']+)('\\))/i";
184
            $regExps[] = "/($style:[^;]*url *\\()([^\"\\)')]+)(\\))/i";
185
        }
186
187
        // Callback for regexp replacement
188
        $callback = function ($matches) use ($code) {
189
            // Decode HTML attribute
190
            $URL = Convert::xml2raw($matches[2]);
191
            $rewritten = $code($URL);
192
            return $matches[1] . Convert::raw2xml($rewritten) . $matches[3];
0 ignored issues
show
Bug introduced by
Are you sure SilverStripe\Core\Convert::raw2xml($rewritten) of type string|array can be used in concatenation? ( Ignorable by Annotation )

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

192
            return $matches[1] . /** @scrutinizer ignore-type */ Convert::raw2xml($rewritten) . $matches[3];
Loading history...
193
        };
194
195
        // Execute each expression
196
        foreach ($regExps as $regExp) {
197
            $content = preg_replace_callback($regExp, $callback, $content);
198
        }
199
200
        return $content;
201
    }
202
203
    /**
204
     * Will try to include a GET parameter for an existing URL, preserving existing parameters and
205
     * fragments. If no URL is given, falls back to $_SERVER['REQUEST_URI']. Uses parse_url() to
206
     * dissect the URL, and http_build_query() to reconstruct it with the additional parameter.
207
     * Converts any '&' (ampersand) URL parameter separators to the more XHTML compliant '&amp;'.
208
     *
209
     * CAUTION: If the URL is determined to be relative, it is prepended with Director::absoluteBaseURL().
210
     * This method will always return an absolute URL because Director::makeRelative() can lead to
211
     * inconsistent results.
212
     *
213
     * @param string $varname
214
     * @param string $varvalue
215
     * @param string|null $currentURL Relative or absolute URL, or HTTPRequest to get url from
216
     * @param string $separator Separator for http_build_query().
217
     * @return string
218
     */
219
    public static function setGetVar($varname, $varvalue, $currentURL = null, $separator = '&')
220
    {
221
        if (!isset($currentURL)) {
222
            $request = Controller::curr()->getRequest();
223
            $currentURL = $request->getURL(true);
224
        }
225
        $uri = $currentURL;
226
227
        $isRelative = false;
228
        // We need absolute URLs for parse_url()
229
        if (Director::is_relative_url($uri)) {
230
            $uri = Director::absoluteBaseURL() . $uri;
231
            $isRelative = true;
232
        }
233
234
        // try to parse uri
235
        $parts = parse_url($uri);
236
        if (!$parts) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $parts of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
237
            throw new InvalidArgumentException("Can't parse URL: " . $uri);
238
        }
239
240
        // Parse params and add new variable
241
        $params = [];
242
        if (isset($parts['query'])) {
243
            parse_str($parts['query'], $params);
244
        }
245
        $params[$varname] = $varvalue;
246
247
        // Generate URI segments and formatting
248
        $scheme = (isset($parts['scheme'])) ? $parts['scheme'] : 'http';
249
        $user = (isset($parts['user']) && $parts['user'] != '') ? $parts['user'] : '';
250
251
        if ($user != '') {
252
            // format in either user:[email protected] or [email protected]
253
            $user .= (isset($parts['pass']) && $parts['pass'] != '') ? ':' . $parts['pass'] . '@' : '@';
254
        }
255
256
        $host = (isset($parts['host'])) ? $parts['host'] : '';
257
        $port = (isset($parts['port']) && $parts['port'] != '') ? ':' . $parts['port'] : '';
258
        $path = (isset($parts['path']) && $parts['path'] != '') ? $parts['path'] : '';
259
260
        // handle URL params which are existing / new
261
        $params = ($params) ? '?' . http_build_query($params, null, $separator) : '';
262
263
        // keep fragments (anchors) intact.
264
        $fragment = (isset($parts['fragment']) && $parts['fragment'] != '') ? '#' . $parts['fragment'] : '';
265
266
        // Recompile URI segments
267
        $newUri = $scheme . '://' . $user . $host . $port . $path . $params . $fragment;
268
269
        if ($isRelative) {
270
            return Director::makeRelative($newUri);
271
        }
272
273
        return $newUri;
274
    }
275
276
    /**
277
     * @param string $varname
278
     * @param string $varvalue
279
     * @param null|string $currentURL
280
     *
281
     * @return string
282
     */
283
    public static function RAW_setGetVar($varname, $varvalue, $currentURL = null)
284
    {
285
        $url = self::setGetVar($varname, $varvalue, $currentURL);
286
        return Convert::xml2raw($url);
287
    }
288
289
    /**
290
     * Search for all tags with a specific attribute, then return the value of that attribute in a
291
     * flat array.
292
     *
293
     * @param string $content
294
     * @param array $attributes An array of tags to attributes, for example "[a] => 'href', [div] => 'id'"
295
     *
296
     * @return array
297
     */
298
    public static function findByTagAndAttribute($content, $attributes)
299
    {
300
        $regexes = [];
301
302
        foreach ($attributes as $tag => $attribute) {
303
            $regexes[] = "/<{$tag} [^>]*$attribute *= *([\"'])(.*?)\\1[^>]*>/i";
304
            $regexes[] = "/<{$tag} [^>]*$attribute *= *([^ \"'>]+)/i";
305
        }
306
307
        $result = [];
308
309
        if ($regexes) {
310
            foreach ($regexes as $regex) {
311
                if (preg_match_all($regex, $content, $matches)) {
312
                    $result = array_merge_recursive($result, (isset($matches[2]) ? $matches[2] : $matches[1]));
313
                }
314
            }
315
        }
316
317
        return count($result) ? $result : null;
318
    }
319
320
    /**
321
     * @param string $content
322
     *
323
     * @return array
324
     */
325
    public static function getLinksIn($content)
326
    {
327
        return self::findByTagAndAttribute($content, ["a" => "href"]);
328
    }
329
330
    /**
331
     * @param string $content
332
     *
333
     * @return array
334
     */
335
    public static function getImagesIn($content)
336
    {
337
        return self::findByTagAndAttribute($content, ["img" => "src"]);
338
    }
339
340
    /**
341
     * Get the MIME type based on a file's extension. If the finfo class exists in PHP, and the file
342
     * exists relative to the project root, then use that extension, otherwise fallback to a list of
343
     * commonly known MIME types.
344
     *
345
     * @param string $filename
346
     * @return string
347
     */
348
    public static function get_mime_type($filename)
349
    {
350
        // If the finfo module is compiled into PHP, use it.
351
        $path = BASE_PATH . DIRECTORY_SEPARATOR . $filename;
352
        if (class_exists('finfo') && file_exists($path)) {
353
            $finfo = new finfo(FILEINFO_MIME_TYPE);
354
            return $finfo->file($path);
355
        }
356
357
        // Fallback to use the list from the HTTP.yml configuration and rely on the file extension
358
        // to get the file mime-type
359
        $ext = strtolower(File::get_file_extension($filename));
360
        // Get the mime-types
361
        $mimeTypes = HTTP::config()->uninherited('MimeTypes');
0 ignored issues
show
Coding Style introduced by
As per coding style, self should be used for accessing local static members.

This check looks for accesses to local static members using the fully qualified name instead of self::.

<?php

class Certificate {
    const TRIPLEDES_CBC = 'ASDFGHJKL';

    private $key;

    public function __construct()
    {
        $this->key = Certificate::TRIPLEDES_CBC;
    }
}

While this is perfectly valid, the fully qualified name of Certificate::TRIPLEDES_CBC could just as well be replaced by self::TRIPLEDES_CBC. Referencing local members with self:: assured the access will still work when the class is renamed, makes it perfectly clear that the member is in fact local and will usually be shorter.

Loading history...
362
363
        // The mime type doesn't exist
364
        if (!isset($mimeTypes[$ext])) {
365
            return 'application/unknown';
366
        }
367
368
        return $mimeTypes[$ext];
369
    }
370
371
    /**
372
     * Set the maximum age of this page in web caches, in seconds.
373
     *
374
     * @deprecated 4.2..5.0 Use HTTPCacheControlMiddleware::singleton()->setMaxAge($age) instead
375
     * @param int $age
376
     */
377
    public static function set_cache_age($age)
378
    {
379
        Deprecation::notice('5.0', 'Use HTTPCacheControlMiddleware::singleton()->setMaxAge($age) instead');
380
        self::$cache_age = $age;
381
        HTTPCacheControlMiddleware::singleton()->setMaxAge($age);
382
    }
383
384
    /**
385
     * @param string $dateString
386
     * @deprecated 4.2..5.0 Use HTTPCacheControlMiddleware::registerModificationDate() instead
387
     */
388
    public static function register_modification_date($dateString)
389
    {
390
        Deprecation::notice('5.0', 'Use HTTPCacheControlMiddleware::registerModificationDate() instead');
391
        HTTPCacheControlMiddleware::singleton()->registerModificationDate($dateString);
392
    }
393
394
    /**
395
     * @param int $timestamp
396
     * @deprecated 4.2..5.0 Use HTTPCacheControlMiddleware::registerModificationDate() instead
397
     */
398
    public static function register_modification_timestamp($timestamp)
399
    {
400
        Deprecation::notice('5.0', 'Use HTTPCacheControlMiddleware::registerModificationDate() instead');
401
        HTTPCacheControlMiddleware::singleton()->registerModificationDate($timestamp);
402
    }
403
404
    /**
405
     * @deprecated 4.2..5.0 Use ChangeDetectionMiddleware instead
406
     * @param string $etag
407
     */
408
    public static function register_etag($etag)
409
    {
410
        Deprecation::notice('5.0', 'Use ChangeDetectionMiddleware instead');
411
        if (strpos($etag, '"') !== 0) {
412
            $etag =  "\"{$etag}\"";
413
        }
414
        self::$etag = $etag;
415
    }
416
417
    /**
418
     * Add the appropriate caching headers to the response, including If-Modified-Since / 304 handling.
419
     * Note that setting HTTP::$cache_age will overrule any cache headers set by PHP's
420
     * session_cache_limiter functionality. It is your responsibility to ensure only cacheable data
421
     * is in fact cached, and HTTP::$cache_age isn't set when the HTTP body contains session-specific
422
     * content.
423
     *
424
     * Omitting the $body argument or passing a string is deprecated; in these cases, the headers are
425
     * output directly.
426
     *
427
     * @param HTTPResponse $response
428
     * @deprecated 4.2..5.0 Headers are added automatically by HTTPCacheControlMiddleware instead.
429
     */
430
    public static function add_cache_headers($response = null)
431
    {
432
        Deprecation::notice('5.0', 'Headers are added automatically by HTTPCacheControlMiddleware instead.');
433
434
        // Skip if deprecated API is disabled
435
        if (Config::inst()->get(HTTP::class, 'ignoreDeprecatedCaching')) {
0 ignored issues
show
Coding Style introduced by
As per coding style, self should be used for accessing local static members.

This check looks for accesses to local static members using the fully qualified name instead of self::.

<?php

class Certificate {
    const TRIPLEDES_CBC = 'ASDFGHJKL';

    private $key;

    public function __construct()
    {
        $this->key = Certificate::TRIPLEDES_CBC;
    }
}

While this is perfectly valid, the fully qualified name of Certificate::TRIPLEDES_CBC could just as well be replaced by self::TRIPLEDES_CBC. Referencing local members with self:: assured the access will still work when the class is renamed, makes it perfectly clear that the member is in fact local and will usually be shorter.

Loading history...
436
            return;
437
        }
438
439
        // Ensure a valid response object is provided
440
        if (!$response instanceof HTTPResponse) {
441
            user_error("HTTP::add_cache_headers() must be passed an HTTPResponse object", E_USER_WARNING);
442
            return;
443
        }
444
445
        // Warn if already assigned cache-control headers
446
        if ($response->getHeader('Cache-Control')) {
447
            trigger_error(
448
                'Cache-Control header has already been set. '
449
                . 'Please use HTTPCacheControlMiddleware API to set caching options instead.',
450
                E_USER_WARNING
451
            );
452
            return;
453
        }
454
455
        // Ensure a valid request object exists in the current context
456
        if (!Injector::inst()->has(HTTPRequest::class)) {
457
            user_error("HTTP::add_cache_headers() cannot work without a current HTTPRequest object", E_USER_WARNING);
458
            return;
459
        }
460
461
        /** @var HTTPRequest $request */
462
        $request = Injector::inst()->get(HTTPRequest::class);
463
464
        // Run middleware
465
        ChangeDetectionMiddleware::singleton()->process($request, function (HTTPRequest $request) use ($response) {
466
            return HTTPCacheControlMiddleware::singleton()->process($request, function (HTTPRequest $request) use ($response) {
0 ignored issues
show
Unused Code introduced by
The parameter $request is not used and could be removed. ( Ignorable by Annotation )

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

466
            return HTTPCacheControlMiddleware::singleton()->process($request, function (/** @scrutinizer ignore-unused */ HTTPRequest $request) use ($response) {

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
467
                return $response;
468
            });
469
        });
470
    }
471
472
    /**
473
     * Ensure that all deprecated HTTP cache settings are respected
474
     *
475
     * @deprecated 4.2..5.0 Use HTTPCacheControlMiddleware instead
476
     * @param HTTPRequest $request
477
     * @param HTTPResponse $response
478
     */
479
    public static function augmentState(HTTPRequest $request, HTTPResponse $response)
0 ignored issues
show
Unused Code introduced by
The parameter $request is not used and could be removed. ( Ignorable by Annotation )

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

479
    public static function augmentState(/** @scrutinizer ignore-unused */ HTTPRequest $request, HTTPResponse $response)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
480
    {
481
        // Skip if deprecated API is disabled
482
        $config = Config::forClass(HTTP::class);
0 ignored issues
show
Coding Style introduced by
As per coding style, self should be used for accessing local static members.

This check looks for accesses to local static members using the fully qualified name instead of self::.

<?php

class Certificate {
    const TRIPLEDES_CBC = 'ASDFGHJKL';

    private $key;

    public function __construct()
    {
        $this->key = Certificate::TRIPLEDES_CBC;
    }
}

While this is perfectly valid, the fully qualified name of Certificate::TRIPLEDES_CBC could just as well be replaced by self::TRIPLEDES_CBC. Referencing local members with self:: assured the access will still work when the class is renamed, makes it perfectly clear that the member is in fact local and will usually be shorter.

Loading history...
483
        if ($config->get('ignoreDeprecatedCaching')) {
484
            return;
485
        }
486
487
        $cacheControlMiddleware = HTTPCacheControlMiddleware::singleton();
488
489
        // if http caching is disabled by config, disable it - used on dev environments due to frequently changing
490
        // templates and other data. will be overridden by forced publicCache(true) or privateCache(true) calls
491
        if ($config->get('disable_http_cache')) {
492
            Deprecation::notice('5.0', 'Use HTTPCacheControlMiddleware.defaultState/.defaultForcingLevel instead');
493
            $cacheControlMiddleware->disableCache();
494
        }
495
496
        // if no caching ajax requests, disable ajax if is ajax request
497
        if (!$config->get('cache_ajax_requests') && Director::is_ajax()) {
498
            Deprecation::notice(
499
                '5.0',
500
                'HTTP.cache_ajax_requests config is deprecated. Use HTTPCacheControlMiddleware::disableCache() instead'
501
            );
502
            $cacheControlMiddleware->disableCache();
503
        }
504
505
        // Pass vary to middleware
506
        $configVary = $config->get('vary');
507
        if ($configVary) {
508
            Deprecation::notice('5.0', 'Use HTTPCacheControlMiddleware.defaultVary instead');
509
            $cacheControlMiddleware->addVary($configVary);
510
        }
511
512
        // Set modification date
513
        if (self::$modification_date) {
514
            Deprecation::notice('5.0', 'Use HTTPCacheControlMiddleware::registerModificationDate() instead');
515
            $cacheControlMiddleware->registerModificationDate(self::$modification_date);
516
        }
517
518
        // Ensure deprecated $etag property is assigned
519
        if (self::$etag && !$cacheControlMiddleware->hasDirective('no-store') && !$response->getHeader('ETag')) {
520
            Deprecation::notice('5.0', 'Etag should not be set explicitly');
521
            $response->addHeader('ETag', self::$etag);
522
        }
523
    }
524
525
    /**
526
     * Return an {@link http://www.faqs.org/rfcs/rfc2822 RFC 2822} date in the GMT timezone (a timestamp
527
     * is always in GMT: the number of seconds since January 1 1970 00:00:00 GMT)
528
     *
529
     * @param int $timestamp
530
     * @deprecated 4.2..5.0 Inline if you need this
531
     * @return string
532
     */
533
    public static function gmt_date($timestamp)
534
    {
535
        return gmdate('D, d M Y H:i:s', $timestamp) . ' GMT';
536
    }
537
538
    /**
539
     * Return static variable cache_age in second
540
     *
541
     * @return int
542
     */
543
    public static function get_cache_age()
544
    {
545
        return self::$cache_age;
546
    }
547
}
548