| Conditions | 31 |
| Paths | > 20000 |
| Total Lines | 129 |
| Code Lines | 62 |
| Lines | 0 |
| Ratio | 0 % |
| Changes | 0 | ||
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:
If many parameters/temporary variables are present:
| 1 | <?php |
||
| 99 | public function applyToResponse($originator, HTTPRequest $request, HTTPResponse $response) |
||
| 100 | { |
||
| 101 | $cacheAge = $this->getCacheAge(); |
||
| 102 | $vary = $this->getVary(); |
||
| 103 | |||
| 104 | // Allow overriding max-age from the object hooked up to the policed controller. |
||
| 105 | if ($originator->hasMethod('getCacheAge')) { |
||
| 106 | $extendedCacheAge = $originator->getCacheAge($cacheAge); |
||
| 107 | if ($extendedCacheAge !== null) { |
||
| 108 | $cacheAge = $extendedCacheAge; |
||
| 109 | } |
||
| 110 | } |
||
| 111 | |||
| 112 | // Same for vary, but probably less useful. |
||
| 113 | if ($originator->hasMethod('getVary')) { |
||
| 114 | $extendedVary = $originator->getVary($vary); |
||
| 115 | if ($extendedVary !== null) { |
||
| 116 | $vary = $extendedVary; |
||
| 117 | } |
||
| 118 | } |
||
| 119 | |||
| 120 | // Development sites have frequently changing templates; this can get stuffed up by the code |
||
| 121 | // below. |
||
| 122 | if (Director::isDev() && $this->config()->get('disable_cache_age_in_dev')) { |
||
| 123 | $cacheAge = 0; |
||
| 124 | } |
||
| 125 | |||
| 126 | // The headers have been sent and we don't have an HTTPResponse object to attach things to; no point in |
||
| 127 | // us trying. |
||
| 128 | if (headers_sent() && !$response->getBody()) { |
||
| 129 | return; |
||
| 130 | } |
||
| 131 | |||
| 132 | // Populate $responseHeaders with all the headers that we want to build |
||
| 133 | $responseHeaders = []; |
||
| 134 | |||
| 135 | $cacheControlHeaders = HTTP::config()->uninherited('cache_control'); |
||
| 136 | |||
| 137 | if ($cacheAge > 0) { |
||
| 138 | // Note: must-revalidate means that the cache must revalidate AFTER the entry has gone stale. |
||
| 139 | $cacheControlHeaders['must-revalidate'] = 'true'; |
||
| 140 | |||
| 141 | $cacheControlHeaders['max-age'] = $cacheAge; |
||
| 142 | |||
| 143 | // Set empty pragma to avoid PHP's session_cache_limiter adding conflicting caching information, |
||
| 144 | // defaulting to "nocache" on most PHP configurations (see http://php.net/session_cache_limiter). |
||
| 145 | // Since it's a deprecated HTTP 1.0 option, all modern HTTP clients and proxies should |
||
| 146 | // prefer the caching information indicated through the "Cache-Control" header. |
||
| 147 | $responseHeaders["Pragma"] = ""; |
||
| 148 | |||
| 149 | $responseHeaders['Vary'] = $vary; |
||
| 150 | } |
||
| 151 | |||
| 152 | foreach ($cacheControlHeaders as $header => $value) { |
||
| 153 | if (is_null($value)) { |
||
| 154 | unset($cacheControlHeaders[$header]); |
||
| 155 | } elseif ((is_bool($value) && $value) || $value === "true") { |
||
| 156 | $cacheControlHeaders[$header] = $header; |
||
| 157 | } else { |
||
| 158 | $cacheControlHeaders[$header] = $header . "=" . $value; |
||
| 159 | } |
||
| 160 | } |
||
| 161 | |||
| 162 | $responseHeaders['Cache-Control'] = implode(', ', $cacheControlHeaders); |
||
| 163 | unset($cacheControlHeaders, $header, $value); |
||
| 164 | |||
| 165 | // Find out when the URI was last modified. Allows customisation, but fall back HTTP timestamp collector. |
||
| 166 | if ($originator->hasMethod('getModificationTimestamp')) { |
||
| 167 | $timestamp = $originator->getModificationTimestamp(); |
||
| 168 | } elseif (self::$modification_date && $cacheAge > 0) { |
||
| 169 | $timestamp = self::$modification_date; |
||
| 170 | } |
||
| 171 | |||
| 172 | if (isset($timestamp)) { |
||
| 173 | $responseHeaders["Last-Modified"] = self::gmt_date($timestamp); |
||
| 174 | |||
| 175 | // Chrome ignores Varies when redirecting back (http://code.google.com/p/chromium/issues/detail?id=79758) |
||
| 176 | // which means that if you log out, you get redirected back to a page which Chrome then checks against |
||
| 177 | // last-modified (which passes, getting a 304) |
||
| 178 | // when it shouldn't be trying to use that page at all because it's the "logged in" version. |
||
| 179 | // By also using and etag that includes both the modification date and all the varies |
||
| 180 | // values which we also check against we can catch this and not return a 304 |
||
| 181 | $etagParts = array(self::$modification_date, serialize($_COOKIE)); |
||
| 182 | $etagParts[] = Director::is_https() ? 'https' : 'http'; |
||
| 183 | if (isset($_SERVER['HTTP_USER_AGENT'])) { |
||
| 184 | $etagParts[] = $_SERVER['HTTP_USER_AGENT']; |
||
| 185 | } |
||
| 186 | if (isset($_SERVER['HTTP_ACCEPT'])) { |
||
| 187 | $etagParts[] = $_SERVER['HTTP_ACCEPT']; |
||
| 188 | } |
||
| 189 | |||
| 190 | $etag = sha1(implode(':', $etagParts)); |
||
| 191 | $responseHeaders["ETag"] = $etag; |
||
| 192 | |||
| 193 | // 304 response detection |
||
| 194 | if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])) { |
||
| 195 | $ifModifiedSince = strtotime(stripslashes($_SERVER['HTTP_IF_MODIFIED_SINCE'])); |
||
| 196 | |||
| 197 | // As above, only 304 if the last request had all the same varies values |
||
| 198 | // (or the etag isn't passed as part of the request - but with chrome it always is) |
||
| 199 | $matchesEtag = !isset($_SERVER['HTTP_IF_NONE_MATCH']) || $_SERVER['HTTP_IF_NONE_MATCH'] == $etag; |
||
| 200 | |||
| 201 | if ($ifModifiedSince >= self::$modification_date && $matchesEtag) { |
||
| 202 | if ($body) { |
||
| 203 | $body->setStatusCode(304); |
||
| 204 | $body->setBody(''); |
||
| 205 | } else { |
||
| 206 | header('HTTP/1.0 304 Not Modified'); |
||
| 207 | die(); |
||
| 208 | } |
||
| 209 | } |
||
| 210 | } |
||
| 211 | |||
| 212 | $expires = time() + $cacheAge; |
||
| 213 | $responseHeaders["Expires"] = self::gmt_date($expires); |
||
| 214 | } |
||
| 215 | |||
| 216 | if (self::$etag) { |
||
| 217 | $responseHeaders['ETag'] = self::$etag; |
||
| 218 | } |
||
| 219 | |||
| 220 | // etag needs to be a quoted string according to HTTP spec |
||
| 221 | if (!empty($responseHeaders['ETag']) && 0 !== strpos($responseHeaders['ETag'], '"')) { |
||
| 222 | $responseHeaders['ETag'] = sprintf('"%s"', $responseHeaders['ETag']); |
||
| 223 | } |
||
| 224 | |||
| 225 | // Now that we've generated them, either output them or attach them to the HTTPResponse as appropriate |
||
| 226 | foreach ($responseHeaders as $k => $v) { |
||
| 227 | $response->addHeader($k, $v); |
||
| 228 | } |
||
| 231 |