2007-08-17 05:32:14 +02:00
< ? php
/**
* Represenets an HTTPResponse returned by a controller .
2008-02-25 03:10:37 +01:00
*
* @ package sapphire
* @ subpackage control
2007-08-17 05:32:14 +02:00
*/
class HTTPResponse extends Object {
protected static $status_codes = array (
100 => 'Continue' ,
101 => 'Switching Protocols' ,
200 => 'OK' ,
201 => 'Created' ,
202 => 'Accepted' ,
203 => 'Non-Authoritative Information' ,
204 => 'No Content' ,
205 => 'Reset Content' ,
206 => 'Partial Content' ,
301 => 'Moved Permanently' ,
302 => 'Found' ,
303 => 'See Other' ,
304 => 'Not Modified' ,
305 => 'Use Proxy' ,
307 => 'Temporary Redirect' ,
400 => 'Bad Request' ,
401 => 'Unauthorized' ,
403 => 'Forbidden' ,
404 => 'Not Found' ,
405 => 'Method Not Allowed' ,
406 => 'Not Acceptable' ,
407 => 'Proxy Authentication Required' ,
408 => 'Request Timeout' ,
409 => 'Conflict' ,
410 => 'Gone' ,
411 => 'Length Required' ,
412 => 'Precondition Failed' ,
413 => 'Request Entity Too Large' ,
414 => 'Request-URI Too Long' ,
415 => 'Unsupported Media Type' ,
416 => 'Request Range Not Satisfiable' ,
417 => 'Expectation Failed' ,
500 => 'Internal Server Error' ,
501 => 'Not Implemented' ,
502 => 'Bad Gateway' ,
503 => 'Service Unavailable' ,
504 => 'Gateway Timeout' ,
505 => 'HTTP Version Not Supported' ,
);
2008-04-22 03:45:55 +02:00
protected static $redirect_codes = array (
301 ,
302 ,
303 ,
304 ,
305 ,
307
);
2007-08-17 05:32:14 +02:00
protected $statusCode = 200 ;
2008-08-09 09:03:24 +02:00
/**
* HTTP Headers like " Content-Type: text/xml "
*
* @ see http :// en . wikipedia . org / wiki / List_of_HTTP_headers
* @ var array
*/
2007-08-17 05:32:14 +02:00
protected $headers = array ();
2008-08-09 09:03:24 +02:00
/**
* @ var string
*/
2007-08-17 05:32:14 +02:00
protected $body = null ;
function setStatusCode ( $code ) {
if ( isset ( self :: $status_codes [ $code ])) $this -> statusCode = $code ;
else user_error ( " Unrecognised HTTP status code ' $code ' " , E_USER_WARNING );
}
2008-08-09 09:03:24 +02:00
2007-12-02 22:29:31 +01:00
function getStatusCode () {
return $this -> statusCode ;
}
2007-08-17 05:32:14 +02:00
2008-08-11 02:03:57 +02:00
/**
* Returns true if this HTTP response is in error
*/
function isError () {
return $this -> statusCode && ( $this -> statusCode < 200 || $this -> statusCode > 399 );
}
2007-08-17 05:32:14 +02:00
function setBody ( $body ) {
$this -> body = $body ;
}
2008-08-09 09:03:24 +02:00
2007-08-17 05:32:14 +02:00
function getBody () {
return $this -> body ;
}
2007-08-27 07:09:54 +02:00
/**
2008-08-09 09:03:24 +02:00
* Add a HTTP header to the response , replacing any header of the same name .
*
* @ param string $header Example : " Content-Type "
* @ param string $value Example : " text/xml "
2007-08-27 07:09:54 +02:00
*/
2007-08-17 05:32:14 +02:00
function addHeader ( $header , $value ) {
$this -> headers [ $header ] = $value ;
}
2007-08-27 07:09:54 +02:00
/**
2008-08-09 09:03:24 +02:00
* Return the HTTP header of the given name .
*
* @ param string $header
2007-08-27 07:09:54 +02:00
* @ returns string
*/
function getHeader ( $header ) {
2007-08-31 02:26:41 +02:00
if ( isset ( $this -> headers [ $header ])) {
return $this -> headers [ $header ];
} else {
return null ;
}
2007-08-27 07:09:54 +02:00
}
2008-08-09 09:03:24 +02:00
/**
* @ return array
*/
function getHeaders () {
return $this -> headers ;
}
/**
* Remove an existing HTTP header by its name ,
* e . g . " Content-Type " .
*
* @ param unknown_type $header
*/
function removeHeader ( $header ) {
if ( isset ( $this -> headers [ $header ])) unset ( $this -> headers [ $header ]);
}
2008-04-22 03:45:55 +02:00
function redirect ( $dest , $code = 302 ) {
if ( ! in_array ( $code , self :: $redirect_codes )) $code = 302 ;
$this -> statusCode = $code ;
2007-08-17 05:32:14 +02:00
$this -> headers [ 'Location' ] = $dest ;
}
/**
* Send this HTTPReponse to the browser
*/
function output () {
2008-04-22 03:45:55 +02:00
if ( in_array ( $this -> statusCode , self :: $redirect_codes ) && headers_sent ( $file , $line )) {
2007-08-17 05:32:14 +02:00
$url = $this -> headers [ 'Location' ];
echo
" <p>Redirecting to <a href= \" $url\ " title = \ " Please click this link if your browser does not redirect you \" > $url ... (output started on $file , line $line )</a></p>
< meta http - equiv = \ " refresh \" content= \" 1; url= $url\ " />
< script type = \ " text/javascript \" >setTimeout('window.location.href = \" $url\ " ' , 50 ); </ script > " ;
} else {
if ( ! headers_sent ()) {
header ( " HTTP/1.1 $this->statusCode " . self :: $status_codes [ $this -> statusCode ]);
foreach ( $this -> headers as $header => $value ) {
header ( " $header : $value " );
}
}
echo $this -> body ;
}
}
/**
* Returns true if this response is " finished " , that is , no more script execution should be done .
* Specifically , returns true if a redirect has already been requested
*/
function isFinished () {
return $this -> statusCode == 302 || $this -> statusCode == 301 ;
}
2007-08-21 00:38:37 +02:00
/**
* Return all the links in the body as an array .
* @ returns An array of maps . Each map will contain 'id' , 'class' , and 'href' , representing the HTML attributes of the link .
*/
function getLinks () {
$attributes = array ( 'id' , 'href' , 'class' );
$links = array ();
$results = array ();
preg_match_all ( '/<a[^>]+>/i' , $this -> body , $links );
// $links[0] contains the actual matches
foreach ( $links [ 0 ] as $link ) {
$processedLink = array ();
foreach ( $attributes as $attribute ) {
$matches = array ();
if ( preg_match ( '/' . $attribute . '\s*=\s*"([^"]+)"/i' , $link , $matches )) {
$processedLink [ $attribute ] = $matches [ 1 ];
}
}
$results [] = $processedLink ;
}
return $results ;
}
2007-08-17 05:32:14 +02:00
}