HTTP::augmentState()   F
last analyzed

Complexity

Conditions 16
Paths 553

Size

Total Lines 74
Code Lines 39

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 16
eloc 39
nc 553
nop 2
dl 0
loc 74
rs 2.0208
c 0
b 0
f 0

How to fix   Long Method    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.0:5.0.0 Use HTTPCacheControlMiddleware::singleton()->setMaxAge($age) instead
25
     * @var int
26
     */
27
    protected static $cache_age = 0;
28
29
    /**
30
     * @deprecated 4.2.0:5.0.0 Handled by HTTPCacheControlMiddleware
31
     * @var int
32
     */
33
    protected static $modification_date = null;
34
35
    /**
36
     * @deprecated 4.2.0:5.0.0 Handled by ChangeDetectionMiddleware
37
     * @var string
38
     */
39
    protected static $etag = null;
40
41
    /**
42
     * @config
43
     * @var bool
44
     * @deprecated 4.2.0:5.0.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.0:5.0.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
     * @deprecated 4.2.0:5.0.0 Handled by HTTPCacheControlMiddleware instead
75
     * @see HTTPCacheControlMiddleware::__construct()
76
     * @config
77
     * @var array Keys are cache control names, values are boolean flags
78
     */
79
    private static $cache_control = [];
0 ignored issues
show
introduced by
The private property $cache_control is not used, and could be removed.
Loading history...
80
81
    /**
82
     * Vary string; A comma separated list of var header names
83
     *
84
     * @deprecated 4.2.0:5.0.0 Handled by HTTPCacheControlMiddleware instead
85
     * @config
86
     * @var string|null
87
     */
88
    private static $vary = null;
0 ignored issues
show
introduced by
The private property $vary is not used, and could be removed.
Loading history...
89
90
    /**
91
     * Turns a local system filename into a URL by comparing it to the script filename.
92
     *
93
     * @param string $filename
94
     * @return string
95
     */
96
    public static function filename2url($filename)
97
    {
98
        $filename = realpath($filename);
99
        if (!$filename) {
100
            return null;
101
        }
102
103
        // Filter files outside of the webroot
104
        $base = realpath(BASE_PATH);
105
        $baseLength = strlen($base);
106
        if (substr($filename, 0, $baseLength) !== $base) {
107
            return null;
108
        }
109
110
        $relativePath = ltrim(substr($filename, $baseLength), '/\\');
111
        return Director::absoluteURL($relativePath);
112
    }
113
114
    /**
115
     * Turn all relative URLs in the content to absolute URLs.
116
     *
117
     * @param string $html
118
     *
119
     * @return string
120
     */
121
    public static function absoluteURLs($html)
122
    {
123
        $html = str_replace('$CurrentPageURL', Controller::curr()->getRequest()->getURL(), $html);
124
        return HTTP::urlRewriter($html, function ($url) {
125
            //no need to rewrite, if uri has a protocol (determined here by existence of reserved URI character ":")
126
            if (preg_match('/^\w+:/', $url)) {
127
                return $url;
128
            }
129
            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

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

193
            return $matches[1] . /** @scrutinizer ignore-type */ Convert::raw2xml($rewritten) . $matches[3];
Loading history...
194
        };
195
196
        // Execute each expression
197
        foreach ($regExps as $regExp) {
198
            $content = preg_replace_callback($regExp, $callback, $content);
199
        }
200
201
        return $content;
202
    }
203
204
    /**
205
     * Will try to include a GET parameter for an existing URL, preserving existing parameters and
206
     * fragments. If no URL is given, falls back to $_SERVER['REQUEST_URI']. Uses parse_url() to
207
     * dissect the URL, and http_build_query() to reconstruct it with the additional parameter.
208
     * Converts any '&' (ampersand) URL parameter separators to the more XHTML compliant '&amp;'.
209
     *
210
     * CAUTION: If the URL is determined to be relative, it is prepended with Director::absoluteBaseURL().
211
     * This method will always return an absolute URL because Director::makeRelative() can lead to
212
     * inconsistent results.
213
     *
214
     * @param string $varname
215
     * @param string $varvalue
216
     * @param string|null $currentURL Relative or absolute URL, or HTTPRequest to get url from
217
     * @param string $separator Separator for http_build_query().
218
     * @return string
219
     */
220
    public static function setGetVar($varname, $varvalue, $currentURL = null, $separator = '&')
221
    {
222
        if (!isset($currentURL)) {
223
            $request = Controller::curr()->getRequest();
224
            $currentURL = $request->getURL(true);
225
        }
226
        $uri = $currentURL;
227
228
        $isRelative = false;
229
        // We need absolute URLs for parse_url()
230
        if (Director::is_relative_url($uri)) {
231
            $uri = Director::absoluteBaseURL() . $uri;
232
            $isRelative = true;
233
        }
234
235
        // try to parse uri
236
        $parts = parse_url($uri);
237
        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...
238
            throw new InvalidArgumentException("Can't parse URL: " . $uri);
239
        }
240
241
        // Parse params and add new variable
242
        $params = [];
243
        if (isset($parts['query'])) {
244
            parse_str($parts['query'], $params);
245
        }
246
        $params[$varname] = $varvalue;
247
248
        // Generate URI segments and formatting
249
        $scheme = (isset($parts['scheme'])) ? $parts['scheme'] : 'http';
250
        $user = (isset($parts['user']) && $parts['user'] != '') ? $parts['user'] : '';
251
252
        if ($user != '') {
253
            // format in either user:[email protected] or [email protected]
254
            $user .= (isset($parts['pass']) && $parts['pass'] != '') ? ':' . $parts['pass'] . '@' : '@';
255
        }
256
257
        $host = (isset($parts['host'])) ? $parts['host'] : '';
258
        $port = (isset($parts['port']) && $parts['port'] != '') ? ':' . $parts['port'] : '';
259
        $path = (isset($parts['path']) && $parts['path'] != '') ? $parts['path'] : '';
260
261
        // handle URL params which are existing / new
262
        $params = ($params) ? '?' . http_build_query($params, null, $separator) : '';
263
264
        // keep fragments (anchors) intact.
265
        $fragment = (isset($parts['fragment']) && $parts['fragment'] != '') ? '#' . $parts['fragment'] : '';
266
267
        // Recompile URI segments
268
        $newUri = $scheme . '://' . $user . $host . $port . $path . $params . $fragment;
269
270
        if ($isRelative) {
271
            return Director::baseURL() . Director::makeRelative($newUri);
272
        }
273
274
        return $newUri;
275
    }
276
277
    /**
278
     * @param string $varname
279
     * @param string $varvalue
280
     * @param null|string $currentURL
281
     *
282
     * @return string
283
     */
284
    public static function RAW_setGetVar($varname, $varvalue, $currentURL = null)
285
    {
286
        $url = self::setGetVar($varname, $varvalue, $currentURL);
287
        return Convert::xml2raw($url);
288
    }
289
290
    /**
291
     * Search for all tags with a specific attribute, then return the value of that attribute in a
292
     * flat array.
293
     *
294
     * @param string $content
295
     * @param array $attributes An array of tags to attributes, for example "[a] => 'href', [div] => 'id'"
296
     *
297
     * @return array
298
     */
299
    public static function findByTagAndAttribute($content, $attributes)
300
    {
301
        $regexes = [];
302
303
        foreach ($attributes as $tag => $attribute) {
304
            $regexes[] = "/<{$tag} [^>]*$attribute *= *([\"'])(.*?)\\1[^>]*>/i";
305
            $regexes[] = "/<{$tag} [^>]*$attribute *= *([^ \"'>]+)/i";
306
        }
307
308
        $result = [];
309
310
        if ($regexes) {
311
            foreach ($regexes as $regex) {
312
                if (preg_match_all($regex, $content, $matches)) {
313
                    $result = array_merge_recursive($result, (isset($matches[2]) ? $matches[2] : $matches[1]));
314
                }
315
            }
316
        }
317
318
        return count($result) ? $result : null;
319
    }
320
321
    /**
322
     * @param string $content
323
     *
324
     * @return array
325
     */
326
    public static function getLinksIn($content)
327
    {
328
        return self::findByTagAndAttribute($content, ["a" => "href"]);
329
    }
330
331
    /**
332
     * @param string $content
333
     *
334
     * @return array
335
     */
336
    public static function getImagesIn($content)
337
    {
338
        return self::findByTagAndAttribute($content, ["img" => "src"]);
339
    }
340
341
    /**
342
     * Get the MIME type based on a file's extension. If the finfo class exists in PHP, and the file
343
     * exists relative to the project root, then use that extension, otherwise fallback to a list of
344
     * commonly known MIME types.
345
     *
346
     * @param string $filename
347
     * @return string
348
     */
349
    public static function get_mime_type($filename)
350
    {
351
        // If the finfo module is compiled into PHP, use it.
352
        $path = BASE_PATH . DIRECTORY_SEPARATOR . $filename;
353
        if (class_exists('finfo') && file_exists($path)) {
354
            $finfo = new finfo(FILEINFO_MIME_TYPE);
355
            return $finfo->file($path);
356
        }
357
358
        // Fallback to use the list from the HTTP.yml configuration and rely on the file extension
359
        // to get the file mime-type
360
        $ext = strtolower(File::get_file_extension($filename));
361
        // Get the mime-types
362
        $mimeTypes = HTTP::config()->uninherited('MimeTypes');
363
364
        // The mime type doesn't exist
365
        if (!isset($mimeTypes[$ext])) {
366
            return 'application/unknown';
367
        }
368
369
        return $mimeTypes[$ext];
370
    }
371
372
    /**
373
     * Set the maximum age of this page in web caches, in seconds.
374
     *
375
     * @deprecated 4.2.0:5.0.0 Use HTTPCacheControlMiddleware::singleton()->setMaxAge($age) instead
376
     * @param int $age
377
     */
378
    public static function set_cache_age($age)
379
    {
380
        Deprecation::notice('5.0', 'Use HTTPCacheControlMiddleware::singleton()->setMaxAge($age) instead');
381
        self::$cache_age = $age;
382
        HTTPCacheControlMiddleware::singleton()->setMaxAge($age);
383
    }
384
385
    /**
386
     * @param string $dateString
387
     * @deprecated 4.2.0:5.0.0 Use HTTPCacheControlMiddleware::registerModificationDate() instead
388
     */
389
    public static function register_modification_date($dateString)
390
    {
391
        Deprecation::notice('5.0', 'Use HTTPCacheControlMiddleware::registerModificationDate() instead');
392
        HTTPCacheControlMiddleware::singleton()->registerModificationDate($dateString);
393
    }
394
395
    /**
396
     * @param int $timestamp
397
     * @deprecated 4.2.0:5.0.0 Use HTTPCacheControlMiddleware::registerModificationDate() instead
398
     */
399
    public static function register_modification_timestamp($timestamp)
400
    {
401
        Deprecation::notice('5.0', 'Use HTTPCacheControlMiddleware::registerModificationDate() instead');
402
        HTTPCacheControlMiddleware::singleton()->registerModificationDate($timestamp);
403
    }
404
405
    /**
406
     * @deprecated 4.2.0:5.0.0 Use ChangeDetectionMiddleware instead
407
     * @param string $etag
408
     */
409
    public static function register_etag($etag)
410
    {
411
        Deprecation::notice('5.0', 'Use ChangeDetectionMiddleware instead');
412
        if (strpos($etag, '"') !== 0) {
413
            $etag =  "\"{$etag}\"";
414
        }
415
        self::$etag = $etag;
416
    }
417
418
    /**
419
     * Add the appropriate caching headers to the response, including If-Modified-Since / 304 handling.
420
     * Note that setting HTTP::$cache_age will overrule any cache headers set by PHP's
421
     * session_cache_limiter functionality. It is your responsibility to ensure only cacheable data
422
     * is in fact cached, and HTTP::$cache_age isn't set when the HTTP body contains session-specific
423
     * content.
424
     *
425
     * Omitting the $body argument or passing a string is deprecated; in these cases, the headers are
426
     * output directly.
427
     *
428
     * @param HTTPResponse $response
429
     * @deprecated 4.2.0:5.0.0 Headers are added automatically by HTTPCacheControlMiddleware instead.
430
     */
431
    public static function add_cache_headers($response = null)
432
    {
433
        Deprecation::notice('5.0', 'Headers are added automatically by HTTPCacheControlMiddleware instead.');
434
435
        // Skip if deprecated API is disabled
436
        if (Config::inst()->get(HTTP::class, 'ignoreDeprecatedCaching')) {
437
            return;
438
        }
439
440
        // Ensure a valid response object is provided
441
        if (!$response instanceof HTTPResponse) {
442
            user_error("HTTP::add_cache_headers() must be passed an HTTPResponse object", E_USER_WARNING);
443
            return;
444
        }
445
446
        // Warn if already assigned cache-control headers
447
        if ($response->getHeader('Cache-Control')) {
448
            trigger_error(
449
                'Cache-Control header has already been set. '
450
                . 'Please use HTTPCacheControlMiddleware API to set caching options instead.',
451
                E_USER_WARNING
452
            );
453
            return;
454
        }
455
456
        // Ensure a valid request object exists in the current context
457
        if (!Injector::inst()->has(HTTPRequest::class)) {
458
            user_error("HTTP::add_cache_headers() cannot work without a current HTTPRequest object", E_USER_WARNING);
459
            return;
460
        }
461
462
        /** @var HTTPRequest $request */
463
        $request = Injector::inst()->get(HTTPRequest::class);
464
465
        // Run middleware
466
        ChangeDetectionMiddleware::singleton()->process($request, function (HTTPRequest $request) use ($response) {
467
            return HTTPCacheControlMiddleware::singleton()
468
                ->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

468
                ->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...
469
                    return $response;
470
                });
471
        });
472
    }
473
474
    /**
475
     * Ensure that all deprecated HTTP cache settings are respected
476
     *
477
     * @deprecated 4.2.0:5.0.0 Use HTTPCacheControlMiddleware instead
478
     * @throws \LogicException
479
     * @param HTTPRequest $request
480
     * @param HTTPResponse $response
481
     */
482
    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

482
    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...
483
    {
484
        // Skip if deprecated API is disabled
485
        $config = Config::forClass(HTTP::class);
486
        if ($config->get('ignoreDeprecatedCaching')) {
487
            return;
488
        }
489
490
        $cacheControlMiddleware = HTTPCacheControlMiddleware::singleton();
491
492
        // if http caching is disabled by config, disable it - used on dev environments due to frequently changing
493
        // templates and other data. will be overridden by forced publicCache(true) or privateCache(true) calls
494
        if ($config->get('disable_http_cache')) {
495
            Deprecation::notice('5.0', 'Use HTTPCacheControlMiddleware.defaultState/.defaultForcingLevel instead');
496
            $cacheControlMiddleware->disableCache();
497
        }
498
499
        // if no caching ajax requests, disable ajax if is ajax request
500
        if (!$config->get('cache_ajax_requests') && Director::is_ajax()) {
501
            Deprecation::notice(
502
                '5.0',
503
                'HTTP.cache_ajax_requests config is deprecated. Use HTTPCacheControlMiddleware::disableCache() instead'
504
            );
505
            $cacheControlMiddleware->disableCache();
506
        }
507
508
        // Pass vary to middleware
509
        $configVary = $config->get('vary');
510
        if ($configVary) {
511
            Deprecation::notice('5.0', 'Use HTTPCacheControlMiddleware.defaultVary instead');
512
            $cacheControlMiddleware->addVary($configVary);
513
        }
514
515
        // Pass cache_control to middleware
516
        $configCacheControl = $config->get('cache_control');
517
        if ($configCacheControl) {
518
            Deprecation::notice('5.0', 'Use HTTPCacheControlMiddleware API instead');
519
520
            $supportedDirectives = ['max-age', 'no-cache', 'no-store', 'must-revalidate'];
521
            if ($foundUnsupported = array_diff(array_keys($configCacheControl), $supportedDirectives)) {
522
                throw new \LogicException(
523
                    'Found unsupported legacy directives in HTTP.cache_control: ' .
524
                    implode(', ', $foundUnsupported) .
525
                    '. Please use HTTPCacheControlMiddleware API instead'
526
                );
527
            }
528
529
            if (isset($configCacheControl['max-age'])) {
530
                $cacheControlMiddleware->setMaxAge($configCacheControl['max-age']);
531
            }
532
533
            if (isset($configCacheControl['no-cache'])) {
534
                $cacheControlMiddleware->setNoCache((bool)$configCacheControl['no-cache']);
535
            }
536
537
            if (isset($configCacheControl['no-store'])) {
538
                $cacheControlMiddleware->setNoStore((bool)$configCacheControl['no-store']);
539
            }
540
541
            if (isset($configCacheControl['must-revalidate'])) {
542
                $cacheControlMiddleware->setMustRevalidate((bool)$configCacheControl['must-revalidate']);
543
            }
544
        }
545
546
        // Set modification date
547
        if (self::$modification_date) {
548
            Deprecation::notice('5.0', 'Use HTTPCacheControlMiddleware::registerModificationDate() instead');
549
            $cacheControlMiddleware->registerModificationDate(self::$modification_date);
550
        }
551
552
        // Ensure deprecated $etag property is assigned
553
        if (self::$etag && !$cacheControlMiddleware->hasDirective('no-store') && !$response->getHeader('ETag')) {
554
            Deprecation::notice('5.0', 'Etag should not be set explicitly');
555
            $response->addHeader('ETag', self::$etag);
556
        }
557
    }
558
559
    /**
560
     * Return an {@link http://www.faqs.org/rfcs/rfc2822 RFC 2822} date in the GMT timezone (a timestamp
561
     * is always in GMT: the number of seconds since January 1 1970 00:00:00 GMT)
562
     *
563
     * @param int $timestamp
564
     * @deprecated 4.2.0:5.0.0 Inline if you need this
565
     * @return string
566
     */
567
    public static function gmt_date($timestamp)
568
    {
569
        return gmdate('D, d M Y H:i:s', $timestamp) . ' GMT';
570
    }
571
572
    /**
573
     * Return static variable cache_age in second
574
     *
575
     * @return int
576
     */
577
    public static function get_cache_age()
578
    {
579
        return self::$cache_age;
580
    }
581
}
582