| Conditions | 42 |
| Paths | > 20000 |
| Total Lines | 160 |
| Code Lines | 78 |
| 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 |
||
| 377 | public static function add_cache_headers($body = null) |
||
| 378 | { |
||
| 379 | $cacheAge = self::$cache_age; |
||
| 380 | |||
| 381 | // Validate argument |
||
| 382 | if ($body && !($body instanceof HTTPResponse)) { |
||
| 383 | user_error("HTTP::add_cache_headers() must be passed an HTTPResponse object", E_USER_WARNING); |
||
| 384 | $body = null; |
||
| 385 | } |
||
| 386 | |||
| 387 | // Development sites have frequently changing templates; this can get stuffed up by the code |
||
| 388 | // below. |
||
| 389 | if (Director::isDev()) { |
||
| 390 | $cacheAge = 0; |
||
| 391 | } |
||
| 392 | |||
| 393 | // The headers have been sent and we don't have an HTTPResponse object to attach things to; no point in |
||
| 394 | // us trying. |
||
| 395 | if (headers_sent() && !$body) { |
||
| 396 | return; |
||
| 397 | } |
||
| 398 | |||
| 399 | // Populate $responseHeaders with all the headers that we want to build |
||
| 400 | $responseHeaders = array(); |
||
| 401 | |||
| 402 | $cacheControlHeaders = HTTP::config()->uninherited('cache_control'); |
||
| 403 | |||
| 404 | |||
| 405 | // currently using a config setting to cancel this, seems to be so that the CMS caches ajax requests |
||
| 406 | if (function_exists('apache_request_headers') && static::config()->uninherited('cache_ajax_requests')) { |
||
| 407 | $requestHeaders = array_change_key_case(apache_request_headers(), CASE_LOWER); |
||
| 408 | if (isset($requestHeaders['x-requested-with']) |
||
| 409 | && $requestHeaders['x-requested-with']=='XMLHttpRequest' |
||
| 410 | ) { |
||
| 411 | $cacheAge = 0; |
||
| 412 | } |
||
| 413 | } |
||
| 414 | |||
| 415 | if ($cacheAge > 0) { |
||
| 416 | $cacheControlHeaders['max-age'] = self::$cache_age; |
||
| 417 | |||
| 418 | // Set empty pragma to avoid PHP's session_cache_limiter adding conflicting caching information, |
||
| 419 | // defaulting to "nocache" on most PHP configurations (see http://php.net/session_cache_limiter). |
||
| 420 | // Since it's a deprecated HTTP 1.0 option, all modern HTTP clients and proxies should |
||
| 421 | // prefer the caching information indicated through the "Cache-Control" header. |
||
| 422 | $responseHeaders["Pragma"] = ""; |
||
| 423 | |||
| 424 | // To do: User-Agent should only be added in situations where you *are* actually |
||
| 425 | // varying according to user-agent. |
||
| 426 | $vary = HTTP::config()->uninherited('vary'); |
||
| 427 | if ($vary && strlen($vary)) { |
||
| 428 | $responseHeaders['Vary'] = $vary; |
||
| 429 | } |
||
| 430 | } else { |
||
| 431 | $contentDisposition = null; |
||
| 432 | if ($body) { |
||
| 433 | // Grab header for checking. Unfortunately HTTPRequest uses a mistyped variant. |
||
| 434 | $contentDisposition = $body->getHeader('Content-disposition'); |
||
| 435 | if (!$contentDisposition) { |
||
| 436 | $contentDisposition = $body->getHeader('Content-Disposition'); |
||
| 437 | } |
||
| 438 | } |
||
| 439 | |||
| 440 | if ($body && |
||
| 441 | Director::is_https() && |
||
| 442 | isset($_SERVER['HTTP_USER_AGENT']) && |
||
| 443 | strstr($_SERVER['HTTP_USER_AGENT'], 'MSIE')==true && |
||
| 444 | strstr($contentDisposition, 'attachment;')==true |
||
| 445 | ) { |
||
| 446 | // IE6-IE8 have problems saving files when https and no-cache are used |
||
| 447 | // (http://support.microsoft.com/kb/323308) |
||
| 448 | // Note: this is also fixable by ticking "Do not save encrypted pages to disk" in advanced options. |
||
| 449 | $cacheControlHeaders['max-age'] = 3; |
||
| 450 | |||
| 451 | // Set empty pragma to avoid PHP's session_cache_limiter adding conflicting caching information, |
||
| 452 | // defaulting to "nocache" on most PHP configurations (see http://php.net/session_cache_limiter). |
||
| 453 | // Since it's a deprecated HTTP 1.0 option, all modern HTTP clients and proxies should |
||
| 454 | // prefer the caching information indicated through the "Cache-Control" header. |
||
| 455 | $responseHeaders["Pragma"] = ""; |
||
| 456 | } else { |
||
| 457 | $cacheControlHeaders['no-cache'] = "true"; |
||
| 458 | $cacheControlHeaders['no-store'] = "true"; |
||
| 459 | } |
||
| 460 | } |
||
| 461 | |||
| 462 | foreach ($cacheControlHeaders as $header => $value) { |
||
| 463 | if (is_null($value)) { |
||
| 464 | unset($cacheControlHeaders[$header]); |
||
| 465 | } elseif ((is_bool($value) && $value) || $value === "true") { |
||
| 466 | $cacheControlHeaders[$header] = $header; |
||
| 467 | } else { |
||
| 468 | $cacheControlHeaders[$header] = $header . "=" . $value; |
||
| 469 | } |
||
| 470 | } |
||
| 471 | |||
| 472 | $responseHeaders['Cache-Control'] = implode(', ', $cacheControlHeaders); |
||
| 473 | unset($cacheControlHeaders, $header, $value); |
||
| 474 | |||
| 475 | if (self::$modification_date && $cacheAge > 0) { |
||
| 476 | $responseHeaders["Last-Modified"] = self::gmt_date(self::$modification_date); |
||
| 477 | |||
| 478 | // Chrome ignores Varies when redirecting back (http://code.google.com/p/chromium/issues/detail?id=79758) |
||
| 479 | // which means that if you log out, you get redirected back to a page which Chrome then checks against |
||
| 480 | // last-modified (which passes, getting a 304) |
||
| 481 | // when it shouldn't be trying to use that page at all because it's the "logged in" version. |
||
| 482 | // By also using and etag that includes both the modification date and all the varies |
||
| 483 | // values which we also check against we can catch this and not return a 304 |
||
| 484 | $etagParts = array(self::$modification_date, serialize($_COOKIE)); |
||
| 485 | $etagParts[] = Director::is_https() ? 'https' : 'http'; |
||
| 486 | if (isset($_SERVER['HTTP_USER_AGENT'])) { |
||
| 487 | $etagParts[] = $_SERVER['HTTP_USER_AGENT']; |
||
| 488 | } |
||
| 489 | if (isset($_SERVER['HTTP_ACCEPT'])) { |
||
| 490 | $etagParts[] = $_SERVER['HTTP_ACCEPT']; |
||
| 491 | } |
||
| 492 | |||
| 493 | $etag = sha1(implode(':', $etagParts)); |
||
| 494 | $responseHeaders["ETag"] = $etag; |
||
| 495 | |||
| 496 | // 304 response detection |
||
| 497 | if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])) { |
||
| 498 | $ifModifiedSince = strtotime(stripslashes($_SERVER['HTTP_IF_MODIFIED_SINCE'])); |
||
| 499 | |||
| 500 | // As above, only 304 if the last request had all the same varies values |
||
| 501 | // (or the etag isn't passed as part of the request - but with chrome it always is) |
||
| 502 | $matchesEtag = !isset($_SERVER['HTTP_IF_NONE_MATCH']) || $_SERVER['HTTP_IF_NONE_MATCH'] == $etag; |
||
| 503 | |||
| 504 | if ($ifModifiedSince >= self::$modification_date && $matchesEtag) { |
||
| 505 | if ($body) { |
||
| 506 | $body->setStatusCode(304); |
||
| 507 | $body->setBody(''); |
||
| 508 | } else { |
||
| 509 | header('HTTP/1.0 304 Not Modified'); |
||
| 510 | die(); |
||
| 511 | } |
||
| 512 | } |
||
| 513 | } |
||
| 514 | |||
| 515 | $expires = time() + $cacheAge; |
||
| 516 | $responseHeaders["Expires"] = self::gmt_date($expires); |
||
| 517 | } |
||
| 518 | |||
| 519 | if (self::$etag) { |
||
| 520 | $responseHeaders['ETag'] = self::$etag; |
||
| 521 | } |
||
| 522 | |||
| 523 | // etag needs to be a quoted string according to HTTP spec |
||
| 524 | if (!empty($responseHeaders['ETag']) && 0 !== strpos($responseHeaders['ETag'], '"')) { |
||
| 525 | $responseHeaders['ETag'] = sprintf('"%s"', $responseHeaders['ETag']); |
||
| 526 | } |
||
| 527 | |||
| 528 | // Now that we've generated them, either output them or attach them to the HTTPResponse as appropriate |
||
| 529 | foreach ($responseHeaders as $k => $v) { |
||
| 530 | if ($body) { |
||
| 531 | // Set the header now if it's not already set. |
||
| 532 | if ($body->getHeader($k) === null) { |
||
| 533 | $body->addHeader($k, $v); |
||
| 534 | } |
||
| 535 | } elseif (!headers_sent()) { |
||
| 536 | header("$k: $v"); |
||
| 537 | } |
||
| 565 |