Namespaces

  • Nette
    • Application
      • Diagnostics
      • Responses
      • Routers
      • UI
    • Caching
      • Storages
    • ComponentModel
    • Config
    • Database
      • Diagnostics
      • Drivers
      • Reflection
      • Table
    • DI
    • Diagnostics
    • Forms
      • Controls
      • Rendering
    • Http
    • Iterators
    • Latte
      • Macros
    • Loaders
    • Localization
    • Mail
    • Reflection
    • Security
    • Templating
    • Utils
  • NetteModule
  • None
  • PHP

Classes

  • Context
  • FileUpload
  • Request
  • RequestFactory
  • Response
  • Session
  • SessionSection
  • Url
  • UrlScript
  • User

Interfaces

  • IRequest
  • IResponse
  • ISessionStorage
  • IUser
  • Overview
  • Namespace
  • Class
  • Tree
  1: <?php
  2: 
  3: /**
  4:  * This file is part of the Nette Framework (http://nette.org)
  5:  *
  6:  * Copyright (c) 2004, 2011 David Grudl (http://davidgrudl.com)
  7:  *
  8:  * For the full copyright and license information, please view
  9:  * the file license.txt that was distributed with this source code.
 10:  */
 11: 
 12: namespace Nette\Http;
 13: 
 14: use Nette;
 15: 
 16: 
 17: 
 18: /**
 19:  * HttpResponse class.
 20:  *
 21:  * @author     David Grudl
 22:  *
 23:  * @property   int $code
 24:  * @property-read array $headers
 25:  * @property-read mixed $sent
 26:  */
 27: final class Response extends Nette\Object implements IResponse
 28: {
 29:     /** @var bool  Send invisible garbage for IE 6? */
 30:     private static $fixIE = TRUE;
 31: 
 32:     /** @var string The domain in which the cookie will be available */
 33:     public $cookieDomain = '';
 34: 
 35:     /** @var string The path in which the cookie will be available */
 36:     public $cookiePath = '/';
 37: 
 38:     /** @var string Whether the cookie is available only through HTTPS */
 39:     public $cookieSecure = FALSE;
 40: 
 41:     /** @var string Whether the cookie is hidden from client-side */
 42:     public $cookieHttpOnly = TRUE;
 43: 
 44:     /** @var int HTTP response code */
 45:     private $code = self::S200_OK;
 46: 
 47: 
 48: 
 49:     /**
 50:      * Sets HTTP response code.
 51:      * @param  int
 52:      * @return Response  provides a fluent interface
 53:      * @throws Nette\InvalidArgumentException  if code is invalid
 54:      * @throws Nette\InvalidStateException  if HTTP headers have been sent
 55:      */
 56:     public function setCode($code)
 57:     {
 58:         $code = (int) $code;
 59: 
 60:         static $allowed = array(
 61:             200=>1, 201=>1, 202=>1, 203=>1, 204=>1, 205=>1, 206=>1,
 62:             300=>1, 301=>1, 302=>1, 303=>1, 304=>1, 307=>1,
 63:             400=>1, 401=>1, 403=>1, 404=>1, 405=>1, 406=>1, 408=>1, 410=>1, 412=>1, 415=>1, 416=>1,
 64:             500=>1, 501=>1, 503=>1, 505=>1
 65:         );
 66: 
 67:         if (!isset($allowed[$code])) {
 68:             throw new Nette\InvalidArgumentException("Bad HTTP response '$code'.");
 69: 
 70:         } elseif (headers_sent($file, $line)) {
 71:             throw new Nette\InvalidStateException("Cannot set HTTP code after HTTP headers have been sent" . ($file ? " (output started at $file:$line)." : "."));
 72: 
 73:         } else {
 74:             $this->code = $code;
 75:             $protocol = isset($_SERVER['SERVER_PROTOCOL']) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.1';
 76:             header($protocol . ' ' . $code, TRUE, $code);
 77:         }
 78:         return $this;
 79:     }
 80: 
 81: 
 82: 
 83:     /**
 84:      * Returns HTTP response code.
 85:      * @return int
 86:      */
 87:     public function getCode()
 88:     {
 89:         return $this->code;
 90:     }
 91: 
 92: 
 93: 
 94:     /**
 95:      * Sends a HTTP header and replaces a previous one.
 96:      * @param  string  header name
 97:      * @param  string  header value
 98:      * @return Response  provides a fluent interface
 99:      * @throws Nette\InvalidStateException  if HTTP headers have been sent
100:      */
101:     public function setHeader($name, $value)
102:     {
103:         if (headers_sent($file, $line)) {
104:             throw new Nette\InvalidStateException("Cannot send header after HTTP headers have been sent" . ($file ? " (output started at $file:$line)." : "."));
105:         }
106: 
107:         if ($value === NULL && function_exists('header_remove')) {
108:             header_remove($name);
109:         } else {
110:             header($name . ': ' . $value, TRUE, $this->code);
111:         }
112:         return $this;
113:     }
114: 
115: 
116: 
117:     /**
118:      * Adds HTTP header.
119:      * @param  string  header name
120:      * @param  string  header value
121:      * @return void
122:      * @throws Nette\InvalidStateException  if HTTP headers have been sent
123:      */
124:     public function addHeader($name, $value)
125:     {
126:         if (headers_sent($file, $line)) {
127:             throw new Nette\InvalidStateException("Cannot send header after HTTP headers have been sent" . ($file ? " (output started at $file:$line)." : "."));
128:         }
129: 
130:         header($name . ': ' . $value, FALSE, $this->code);
131:     }
132: 
133: 
134: 
135:     /**
136:      * Sends a Content-type HTTP header.
137:      * @param  string  mime-type
138:      * @param  string  charset
139:      * @return Response  provides a fluent interface
140:      * @throws Nette\InvalidStateException  if HTTP headers have been sent
141:      */
142:     public function setContentType($type, $charset = NULL)
143:     {
144:         $this->setHeader('Content-Type', $type . ($charset ? '; charset=' . $charset : ''));
145:         return $this;
146:     }
147: 
148: 
149: 
150:     /**
151:      * Redirects to a new URL. Note: call exit() after it.
152:      * @param  string  URL
153:      * @param  int     HTTP code
154:      * @return void
155:      * @throws Nette\InvalidStateException  if HTTP headers have been sent
156:      */
157:     public function redirect($url, $code = self::S302_FOUND)
158:     {
159:         if (isset($_SERVER['SERVER_SOFTWARE']) && preg_match('#^Microsoft-IIS/[1-5]#', $_SERVER['SERVER_SOFTWARE'])
160:             && $this->getHeader('Set-Cookie') !== NULL
161:         ) {
162:             $this->setHeader('Refresh', "0;url=$url");
163:             return;
164:         }
165: 
166:         $this->setCode($code);
167:         $this->setHeader('Location', $url);
168:         echo "<h1>Redirect</h1>\n\n<p><a href=\"" . htmlSpecialChars($url) . "\">Please click here to continue</a>.</p>";
169:     }
170: 
171: 
172: 
173:     /**
174:      * Sets the number of seconds before a page cached on a browser expires.
175:      * @param  string|int|DateTime  time, value 0 means "until the browser is closed"
176:      * @return Response  provides a fluent interface
177:      * @throws Nette\InvalidStateException  if HTTP headers have been sent
178:      */
179:     public function setExpiration($time)
180:     {
181:         if (!$time) { // no cache
182:             $this->setHeader('Cache-Control', 's-maxage=0, max-age=0, must-revalidate');
183:             $this->setHeader('Expires', 'Mon, 23 Jan 1978 10:00:00 GMT');
184:             return $this;
185:         }
186: 
187:         $time = Nette\DateTime::from($time);
188:         $this->setHeader('Cache-Control', 'max-age=' . ($time->format('U') - time()));
189:         $this->setHeader('Expires', self::date($time));
190:         return $this;
191:     }
192: 
193: 
194: 
195:     /**
196:      * Checks if headers have been sent.
197:      * @return bool
198:      */
199:     public function isSent()
200:     {
201:         return headers_sent();
202:     }
203: 
204: 
205: 
206:     /**
207:      * Return the value of the HTTP header.
208:      * @param  string
209:      * @param  mixed
210:      * @return mixed
211:      */
212:     public function getHeader($header, $default = NULL)
213:     {
214:         $header .= ':';
215:         $len = strlen($header);
216:         foreach (headers_list() as $item) {
217:             if (strncasecmp($item, $header, $len) === 0) {
218:                 return ltrim(substr($item, $len));
219:             }
220:         }
221:         return $default;
222:     }
223: 
224: 
225: 
226:     /**
227:      * Returns a list of headers to sent.
228:      * @return array
229:      */
230:     public function getHeaders()
231:     {
232:         $headers = array();
233:         foreach (headers_list() as $header) {
234:             $a = strpos($header, ':');
235:             $headers[substr($header, 0, $a)] = (string) substr($header, $a + 2);
236:         }
237:         return $headers;
238:     }
239: 
240: 
241: 
242:     /**
243:      * Returns HTTP valid date format.
244:      * @param  string|int|DateTime
245:      * @return string
246:      */
247:     public static function date($time = NULL)
248:     {
249:         $time = Nette\DateTime::from($time);
250:         $time->setTimezone(new \DateTimeZone('GMT'));
251:         return $time->format('D, d M Y H:i:s \G\M\T');
252:     }
253: 
254: 
255: 
256:     /**
257:      * @return void
258:      */
259:     public function __destruct()
260:     {
261:         if (self::$fixIE && isset($_SERVER['HTTP_USER_AGENT']) && strpos($_SERVER['HTTP_USER_AGENT'], 'MSIE ') !== FALSE
262:             && in_array($this->code, array(400, 403, 404, 405, 406, 408, 409, 410, 500, 501, 505), TRUE)
263:             && $this->getHeader('Content-Type', 'text/html') === 'text/html'
264:         ) {
265:             echo Nette\Utils\Strings::random(2e3, " \t\r\n"); // sends invisible garbage for IE
266:             self::$fixIE = FALSE;
267:         }
268:     }
269: 
270: 
271: 
272:     /**
273:      * Sends a cookie.
274:      * @param  string name of the cookie
275:      * @param  string value
276:      * @param  string|int|DateTime  expiration time, value 0 means "until the browser is closed"
277:      * @param  string
278:      * @param  string
279:      * @param  bool
280:      * @param  bool
281:      * @return Response  provides a fluent interface
282:      * @throws Nette\InvalidStateException  if HTTP headers have been sent
283:      */
284:     public function setCookie($name, $value, $time, $path = NULL, $domain = NULL, $secure = NULL, $httpOnly = NULL)
285:     {
286:         if (headers_sent($file, $line)) {
287:             throw new Nette\InvalidStateException("Cannot set cookie after HTTP headers have been sent" . ($file ? " (output started at $file:$line)." : "."));
288:         }
289: 
290:         setcookie(
291:             $name,
292:             $value,
293:             $time ? Nette\DateTime::from($time)->format('U') : 0,
294:             $path === NULL ? $this->cookiePath : (string) $path,
295:             $domain === NULL ? $this->cookieDomain : (string) $domain,
296:             $secure === NULL ? $this->cookieSecure : (bool) $secure,
297:             $httpOnly === NULL ? $this->cookieHttpOnly : (bool) $httpOnly
298:         );
299:         return $this;
300:     }
301: 
302: 
303: 
304:     /**
305:      * Deletes a cookie.
306:      * @param  string name of the cookie.
307:      * @param  string
308:      * @param  string
309:      * @param  bool
310:      * @return void
311:      * @throws Nette\InvalidStateException  if HTTP headers have been sent
312:      */
313:     public function deleteCookie($name, $path = NULL, $domain = NULL, $secure = NULL)
314:     {
315:         if (headers_sent($file, $line)) {
316:             throw new Nette\InvalidStateException("Cannot delete cookie after HTTP headers have been sent" . ($file ? " (output started at $file:$line)." : "."));
317:         }
318: 
319:         setcookie(
320:             $name,
321:             FALSE,
322:             254400000,
323:             $path === NULL ? $this->cookiePath : (string) $path,
324:             $domain === NULL ? $this->cookieDomain : (string) $domain,
325:             $secure === NULL ? $this->cookieSecure : (bool) $secure,
326:             TRUE // doesn't matter with delete
327:         );
328:     }
329: 
330: }
331: 
Nette Framework 2.0beta1 API API documentation generated by ApiGen 2.3.0