ResponseHeaderBag.php 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. <?php
  2. /*
  3. * This file is part of the Symfony package.
  4. *
  5. * (c) Fabien Potencier <fabien@symfony.com>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace Symfony\Component\HttpFoundation;
  11. /**
  12. * ResponseHeaderBag is a container for Response HTTP headers.
  13. *
  14. * @author Fabien Potencier <fabien@symfony.com>
  15. */
  16. class ResponseHeaderBag extends HeaderBag
  17. {
  18. protected $computedCacheControl = array();
  19. /**
  20. * Constructor.
  21. *
  22. * @param array $headers An array of HTTP headers
  23. */
  24. public function __construct(array $headers = array())
  25. {
  26. parent::__construct($headers);
  27. if (!isset($this->headers['cache-control'])) {
  28. $this->set('cache-control', '');
  29. }
  30. }
  31. /**
  32. * {@inheritdoc}
  33. */
  34. public function __toString()
  35. {
  36. $cookies = '';
  37. foreach ($this->cookies as $cookie) {
  38. $cookies .= 'Set-Cookie: '.$cookie."\r\n";
  39. }
  40. return
  41. parent::__toString().
  42. $cookies;
  43. }
  44. /**
  45. * {@inheritdoc}
  46. */
  47. public function replace(array $headers = array())
  48. {
  49. parent::replace($headers);
  50. if (!isset($this->headers['cache-control'])) {
  51. $this->set('cache-control', '');
  52. }
  53. }
  54. /**
  55. * {@inheritdoc}
  56. */
  57. public function set($key, $values, $replace = true)
  58. {
  59. parent::set($key, $values, $replace);
  60. // ensure the cache-control header has sensible defaults
  61. if (in_array(strtr(strtolower($key), '_', '-'), array('cache-control', 'etag', 'last-modified', 'expires'))) {
  62. $computed = $this->computeCacheControlValue();
  63. $this->headers['cache-control'] = array($computed);
  64. $this->computedCacheControl = $this->parseCacheControl($computed);
  65. }
  66. }
  67. /**
  68. * {@inheritdoc}
  69. */
  70. public function remove($key)
  71. {
  72. parent::remove($key);
  73. if ('cache-control' === strtr(strtolower($key), '_', '-')) {
  74. $this->computedCacheControl = array();
  75. }
  76. }
  77. /**
  78. * {@inheritdoc}
  79. */
  80. public function hasCacheControlDirective($key)
  81. {
  82. return array_key_exists($key, $this->computedCacheControl);
  83. }
  84. /**
  85. * {@inheritdoc}
  86. */
  87. public function getCacheControlDirective($key)
  88. {
  89. return array_key_exists($key, $this->computedCacheControl) ? $this->computedCacheControl[$key] : null;
  90. }
  91. /**
  92. * Clears a cookie in the browser
  93. *
  94. * @param string $name
  95. * @param string $path
  96. * @param string $domain
  97. * @return void
  98. */
  99. public function clearCookie($name, $path = null, $domain = null)
  100. {
  101. $this->setCookie(new Cookie($name, null, 1, $path, $domain));
  102. }
  103. /**
  104. * Returns the calculated value of the cache-control header.
  105. *
  106. * This considers several other headers and calculates or modifies the
  107. * cache-control header to a sensible, conservative value.
  108. *
  109. * @return string
  110. */
  111. protected function computeCacheControlValue()
  112. {
  113. if (!$this->cacheControl && !$this->has('ETag') && !$this->has('Last-Modified') && !$this->has('Expires')) {
  114. return 'no-cache';
  115. }
  116. if (!$this->cacheControl) {
  117. // conservative by default
  118. return 'private, must-revalidate';
  119. }
  120. $header = $this->getCacheControlHeader();
  121. if (isset($this->cacheControl['public']) || isset($this->cacheControl['private'])) {
  122. return $header;
  123. }
  124. // public if s-maxage is defined, private otherwise
  125. if (!isset($this->cacheControl['s-maxage'])) {
  126. return $header.', private';
  127. }
  128. return $header;
  129. }
  130. }