Completed
Branch master (939199)
by
unknown
39:35
created

includes/cache/ResourceFileCache.php (1 issue)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
/**
3
 * ResourceLoader request result caching in the file system.
4
 *
5
 * This program is free software; you can redistribute it and/or modify
6
 * it under the terms of the GNU General Public License as published by
7
 * the Free Software Foundation; either version 2 of the License, or
8
 * (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License along
16
 * with this program; if not, write to the Free Software Foundation, Inc.,
17
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18
 * http://www.gnu.org/copyleft/gpl.html
19
 *
20
 * @file
21
 * @ingroup Cache
22
 */
23
24
/**
25
 * ResourceLoader request result caching in the file system.
26
 *
27
 * @ingroup Cache
28
 */
29
class ResourceFileCache extends FileCacheBase {
30
	protected $mCacheWorthy;
31
32
	/* @todo configurable? */
33
	const MISS_THRESHOLD = 360; // 6/min * 60 min
34
35
	/**
36
	 * Construct an ResourceFileCache from a context
37
	 * @param ResourceLoaderContext $context
38
	 * @return ResourceFileCache
39
	 */
40
	public static function newFromContext( ResourceLoaderContext $context ) {
41
		$cache = new self();
42
43
		if ( $context->getImage() ) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $context->getImage() of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
44
			$cache->mType = 'image';
45
		} elseif ( $context->getOnly() === 'styles' ) {
46
			$cache->mType = 'css';
47
		} else {
48
			$cache->mType = 'js';
49
		}
50
		$modules = array_unique( $context->getModules() ); // remove duplicates
51
		sort( $modules ); // normalize the order (permutation => combination)
52
		$cache->mKey = sha1( $context->getHash() . implode( '|', $modules ) );
53
		if ( count( $modules ) == 1 ) {
54
			$cache->mCacheWorthy = true; // won't take up much space
55
		}
56
57
		return $cache;
58
	}
59
60
	/**
61
	 * Check if an RL request can be cached.
62
	 * Caller is responsible for checking if any modules are private.
63
	 * @param ResourceLoaderContext $context
64
	 * @return bool
65
	 */
66
	public static function useFileCache( ResourceLoaderContext $context ) {
67
		global $wgUseFileCache, $wgDefaultSkin, $wgLanguageCode;
68
		if ( !$wgUseFileCache ) {
69
			return false;
70
		}
71
		// Get all query values
72
		$queryVals = $context->getRequest()->getValues();
73
		foreach ( $queryVals as $query => $val ) {
74
			if ( in_array( $query, [ 'modules', 'image', 'variant', 'version', '*' ] ) ) {
75
				// Use file cache regardless of the value of this parameter
76
				continue; // note: &* added as IE fix
77
			} elseif ( $query === 'skin' && $val === $wgDefaultSkin ) {
78
				continue;
79
			} elseif ( $query === 'lang' && $val === $wgLanguageCode ) {
80
				continue;
81
			} elseif ( $query === 'only' && in_array( $val, [ 'styles', 'scripts' ] ) ) {
82
				continue;
83
			} elseif ( $query === 'debug' && $val === 'false' ) {
84
				continue;
85
			} elseif ( $query === 'format' && $val === 'rasterized' ) {
86
				continue;
87
			}
88
89
			return false;
90
		}
91
92
		return true; // cacheable
93
	}
94
95
	/**
96
	 * Get the base file cache directory
97
	 * @return string
98
	 */
99
	protected function cacheDirectory() {
100
		return $this->baseCacheDirectory() . '/resources';
101
	}
102
103
	/**
104
	 * Item has many recent cache misses
105
	 * @return bool
106
	 */
107
	public function isCacheWorthy() {
108
		if ( $this->mCacheWorthy === null ) {
109
			$this->mCacheWorthy = (
110
				$this->isCached() || // even stale cache indicates it was cache worthy
111
				$this->getMissesRecent() >= self::MISS_THRESHOLD // many misses
112
			);
113
		}
114
115
		return $this->mCacheWorthy;
116
	}
117
}
118