diff options
| -rw-r--r-- | HISTORY | 1 | ||||
| -rw-r--r-- | framework/Web/THttpResponse.php | 1076 | 
2 files changed, 571 insertions, 506 deletions
| @@ -40,6 +40,7 @@ ENH: Ticket#741 - Added CDbConnection.currentTransaction property (Qiang)  ENH: Ticket#743 - Added status code header in HTTP response when in error (Qiang)  ENH: Ticket#745 - TWizard action MoveTo - allow specify step ID's (Christophe)  ENH: Ticket#757 - TDateFormat and TNumberFormat now implement IDataRenderer (Qiang) +EHH: Ticket#770 - THttpResponse send HTTP 1.1 Status code to the client (Christophe)  ENH: Ticket#783 - Added date/time type support to soap implementation (Hongliang)  ENH: Ticket#800,#833 - Added database connection charset for MySql and PgSql (donkee)  ENH: Active Record supports multiple foreign references of the same table (Wei) diff --git a/framework/Web/THttpResponse.php b/framework/Web/THttpResponse.php index 0274ffbb..26f7d25e 100644 --- a/framework/Web/THttpResponse.php +++ b/framework/Web/THttpResponse.php @@ -1,507 +1,571 @@ -<?php
 -/**
 - * THttpResponse class
 - *
 - * @author Qiang Xue <qiang.xue@gmail.com>
 - * @link http://www.pradosoft.com/
 - * @copyright Copyright © 2005 PradoSoft
 - * @license http://www.pradosoft.com/license/
 - * @version $Id$
 - * @package System.Web
 - */
 -
 -/**
 - * Includes the THttpResponse adapter.
 - */
 -Prado::using('System.Web.THttpResponseAdapter');
 -
 -/**
 - * THttpResponse class
 - *
 - * THttpResponse implements the mechanism for sending output to client users.
 - *
 - * To output a string to client, use {@link write()}. By default, the output is
 - * buffered until {@link flush()} is called or the application ends. The output in
 - * the buffer can also be cleaned by {@link clear()}. To disable output buffering,
 - * set BufferOutput property to false.
 - *
 - * To send cookies to client, use {@link getCookies()}.
 - * To redirect client browser to a new URL, use {@link redirect()}.
 - * To send a file to client, use {@link writeFile()}.
 - *
 - * By default, THttpResponse is registered with {@link TApplication} as the
 - * response module. It can be accessed via {@link TApplication::getResponse()}.
 - *
 - * THttpResponse may be configured in application configuration file as follows
 - *
 - * <module id="response" class="System.Web.THttpResponse" CacheExpire="20" CacheControl="nocache" BufferOutput="true" />
 - *
 - * where {@link getCacheExpire CacheExpire}, {@link getCacheControl CacheControl}
 - * and {@link getBufferOutput BufferOutput} are optional properties of THttpResponse.
 - *
 - * THttpResponse sends charset header if either {@link setCharset() Charset}
 - * or {@link TGlobalization::setCharset() TGlobalization.Charset} is set.
 - *
 - * @author Qiang Xue <qiang.xue@gmail.com>
 - * @version $Id$
 - * @package System.Web
 - * @since 3.0
 - */
 -class THttpResponse extends TModule implements ITextWriter
 -{
 -	/**
 -	 * @var boolean whether to buffer output
 -	 */
 -	private $_bufferOutput=true;
 -	/**
 -	 * @var boolean if the application is initialized
 -	 */
 -	private $_initialized=false;
 -	/**
 -	 * @var THttpCookieCollection list of cookies to return
 -	 */
 -	private $_cookies=null;
 -	/**
 -	 * @var integer response status code
 -	 */
 -	private $_status=200;
 -	/**
 -	 * @var string HTML writer type
 -	 */
 -	private $_htmlWriterType='System.Web.UI.THtmlWriter';
 -	/**
 -	 * @var string content type
 -	 */
 -	private $_contentType=null;
 -	/**
 -	 * @var string character set, e.g. UTF-8
 -	 */
 -	private $_charset='';
 -	/**
 -	 * @var THttpResponseAdapter adapter.
 -	 */
 -	private $_adapter;
 -
 -	/**
 -	 * Destructor.
 -	 * Flushes any existing content in buffer.
 -	 */
 -	public function __destruct()
 -	{
 -		//if($this->_bufferOutput)
 -		//	@ob_end_flush();
 -	}
 -
 -	/**
 -	 * @param THttpResponseAdapter response adapter
 -	 */
 -	public function setAdapter(THttpResponseAdapter $adapter)
 -	{
 -		$this->_adapter=$adapter;
 -	}
 -
 -	/**
 -	 * @return THttpResponseAdapter response adapter, null if not exist.
 -	 */
 -	public function getAdapter()
 -	{
 -		return $this->_adapter;
 -	}
 -
 -	/**
 -	 * @return boolean true if adapter exists, false otherwise.
 -	 */
 -	public function getHasAdapter()
 -	{
 -		return !is_null($this->_adapter);
 -	}
 -
 -	/**
 -	 * Initializes the module.
 -	 * This method is required by IModule and is invoked by application.
 -	 * It starts output buffer if it is enabled.
 -	 * @param TXmlElement module configuration
 -	 */
 -	public function init($config)
 -	{
 -		if($this->_bufferOutput)
 -			ob_start();
 -		$this->_initialized=true;
 -		$this->getApplication()->setResponse($this);
 -	}
 -
 -	/**
 -	 * @return integer time-to-live for cached session pages in minutes, this has no effect for nocache limiter. Defaults to 180.
 -	 */
 -	public function getCacheExpire()
 -	{
 -		return session_cache_expire();
 -	}
 -
 -	/**
 -	 * @param integer time-to-live for cached session pages in minutes, this has no effect for nocache limiter.
 -	 */
 -	public function setCacheExpire($value)
 -	{
 -		session_cache_expire(TPropertyValue::ensureInteger($value));
 -	}
 -
 -	/**
 -	 * @return string cache control method to use for session pages
 -	 */
 -	public function getCacheControl()
 -	{
 -		return session_cache_limiter();
 -	}
 -
 -	/**
 -	 * @param string cache control method to use for session pages. Valid values
 -	 *               include none/nocache/private/private_no_expire/public
 -	 */
 -	public function setCacheControl($value)
 -	{
 -		session_cache_limiter(TPropertyValue::ensureEnum($value,array('none','nocache','private','private_no_expire','public')));
 -	}
 -
 -	/**
 -	 * @return string content type, default is text/html
 -	 */
 -	public function setContentType($type)
 -	{
 -		$this->_contentType = $type;
 -	}
 -
 -	/**
 -	 * @return string current content type
 -	 */
 -	public function getContentType()
 -	{
 -		return $this->_contentType;
 -	}
 -
 -	/**
 -	 * @return string output charset.
 -	 */
 -	public function getCharset()
 -	{
 -		return $this->_charset;
 -	}
 -
 -	/**
 -	 * @param string output charset.
 -	 */
 -	public function setCharset($charset)
 -	{
 -		$this->_charset = $charset;
 -	}
 -
 -	/**
 -	 * @return boolean whether to enable output buffer
 -	 */
 -	public function getBufferOutput()
 -	{
 -		return $this->_bufferOutput;
 -	}
 -
 -	/**
 -	 * @param boolean whether to enable output buffer
 -	 * @throws TInvalidOperationException if session is started already
 -	 */
 -	public function setBufferOutput($value)
 -	{
 -		if($this->_initialized)
 -			throw new TInvalidOperationException('httpresponse_bufferoutput_unchangeable');
 -		else
 -			$this->_bufferOutput=TPropertyValue::ensureBoolean($value);
 -	}
 -
 -	/**
 -	 * @return integer HTTP status code, defaults to 200
 -	 */
 -	public function getStatusCode()
 -	{
 -		return $this->_status;
 -	}
 -
 -	/**
 -	 * @param integer HTTP status code
 -	 */
 -	public function setStatusCode($status)
 -	{
 -		$this->_status=TPropertyValue::ensureInteger($status);
 -	}
 -
 -	/**
 -	 * @return THttpCookieCollection list of output cookies
 -	 */
 -	public function getCookies()
 -	{
 -		if($this->_cookies===null)
 -			$this->_cookies=new THttpCookieCollection($this);
 -		return $this->_cookies;
 -	}
 -
 -	/**
 -	 * Outputs a string.
 -	 * It may not be sent back to user immediately if output buffer is enabled.
 -	 * @param string string to be output
 -	 */
 -	public function write($str)
 -	{
 -		echo $str;
 -	}
 -
 -	/**
 -	 * Sends a file back to user.
 -	 * Make sure not to output anything else after calling this method.
 -	 * @param string file name
 -	 * @param string content to be set. If null, the content will be read from the server file pointed to by $fileName.
 -	 * @param string mime type of the content.
 -	 * @param array list of headers to be sent. Each array element represents a header string (e.g. 'Content-Type: text/plain').
 -	 * @throws TInvalidDataValueException if the file cannot be found
 -	 */
 -	public function writeFile($fileName,$content=null,$mimeType=null,$headers=null)
 -	{
 -		static $defaultMimeTypes=array(
 -			'css'=>'text/css',
 -			'gif'=>'image/gif',
 -			'jpg'=>'image/jpeg',
 -			'jpeg'=>'image/jpeg',
 -			'htm'=>'text/html',
 -			'html'=>'text/html',
 -			'js'=>'javascript/js',
 -			'pdf'=>'application/pdf',
 -			'xls'=>'application/vnd.ms-excel',
 -		);
 -
 -		if($mimeType===null)
 -		{
 -			$mimeType='text/plain';
 -			if(function_exists('mime_content_type'))
 -				$mimeType=mime_content_type($fileName);
 -			else if(($ext=strrchr($fileName,'.'))!==false)
 -			{
 -				$ext=substr($ext,1);
 -				if(isset($defaultMimeTypes[$ext]))
 -					$mimeType=$defaultMimeTypes[$ext];
 -			}
 -		}
 -		$fn=basename($fileName);
 -		if(is_array($headers))
 -		{
 -			foreach($headers as $h)
 -				header($h);
 -		}
 -		else
 -		{
 -			header('Pragma: public');
 -			header('Expires: 0');
 -			header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
 -		}
 -		header("Content-type: $mimeType");
 -		header('Content-Length: '.($content===null?filesize($fileName):strlen($content)));
 -		header("Content-Disposition: attachment; filename=\"$fn\"");
 -		header('Content-Transfer-Encoding: binary');
 -		if($content===null)
 -			readfile($fileName);
 -		else
 -			echo $content;
 -	}
 -
 -	/**
 -	 * Redirects the browser to the specified URL.
 -	 * The current application will be terminated after this method is invoked.
 -	 * @param string URL to be redirected to. If the URL is a relative one, the base URL of
 -	 * the current request will be inserted at the beginning.
 -	 */
 -	public function redirect($url)
 -	{
 -		if($this->getHasAdapter())
 -			$this->_adapter->httpRedirect($url);
 -		else
 -			$this->httpRedirect($url);
 -	}
 -
 -	/**
 -	 * Redirect the browser to another URL and exists the current application.
 -	 * This method is used internally. Please use {@link redirect} instead.
 -	 * @param string URL to be redirected to. If the URL is a relative one, the base URL of
 -	 * the current request will be inserted at the beginning.
 -	 */
 -	public function httpRedirect($url)
 -	{
 -		if(!$this->getApplication()->getRequestCompleted())
 -			$this->getApplication()->onEndRequest();
 -		if($url[0]==='/')
 -			$url=$this->getRequest()->getBaseUrl().$url;
 -		header('Location: '.str_replace('&','&',$url));
 -		exit();
 -	}
 -
 -	/**
 -	 * Reloads the current page.
 -	 * The effect of this method call is the same as user pressing the
 -	 * refresh button on his browser (without post data).
 -	 **/
 -	public function reload()
 -	{
 -		$this->redirect($this->getRequest()->getRequestUri());
 -	}
 -
 -	/**
 -	 * Flush the response contents and headers.
 -	 */
 -	public function flush()
 -	{
 -		if($this->getHasAdapter())
 -			$this->_adapter->flushContent();
 -		else
 -			$this->flushContent();
 -	}
 -
 -	/**
 -	 * Outputs the buffered content, sends content-type and charset header.
 -	 * This method is used internally. Please use {@link flush} instead.
 -	 */
 -	public function flushContent()
 -	{
 -		Prado::trace("Flushing output",'System.Web.THttpResponse');
 -		$this->sendContentTypeHeader();
 -		if($this->_bufferOutput)
 -			ob_flush();
 -	}
 -
 -	/**
 -	 * Sends content type header if charset is not empty.
 -	 */
 -	protected function sendContentTypeHeader()
 -	{
 -		$charset=$this->getCharset();
 -		if($charset==='' && ($globalization=$this->getApplication()->getGlobalization(false))!==null)
 -			$charset=$globalization->getCharset();
 -		if($charset!=='')
 -		{
 -			$contentType=$this->_contentType===null?'text/html':$this->_contentType;
 -			$this->appendHeader('Content-Type: '.$contentType.';charset='.$charset);
 -		}
 -		else if($this->_contentType!==null)
 -			$this->appendHeader('Content-Type: '.$this->_contentType.';charset=UTF-8');
 -	}
 -
 -	/**
 -	 * Returns the content in the output buffer.
 -	 * The buffer will NOT be cleared after calling this method.
 -	 * Use {@link clear()} is you want to clear the buffer.
 -	 * @return string output that is in the buffer.
 -	 */
 -	public function getContents()
 -	{
 -		Prado::trace("Retrieving output",'System.Web.THttpResponse');
 -		return $this->_bufferOutput?ob_get_contents():'';
 -	}
 -
 -	/**
 -	 * Clears any existing buffered content.
 -	 */
 -	public function clear()
 -	{
 -		if($this->_bufferOutput)
 -			ob_clean();
 -		Prado::trace("Clearing output",'System.Web.THttpResponse');
 -	}
 -
 -	/**
 -	 * Sends a header.
 -	 * @param string header
 -	 */
 -	public function appendHeader($value)
 -	{
 -		Prado::trace("Sending header '$value'",'System.Web.THttpResponse');
 -		header($value);
 -	}
 -
 -	/**
 -	 * Writes a log message into error log.
 -	 * This method is simple wrapper of PHP function error_log.
 -	 * @param string The error message that should be logged
 -	 * @param integer where the error should go
 -	 * @param string The destination. Its meaning depends on the message parameter as described above
 -	 * @param string The extra headers. It's used when the message parameter is set to 1. This message type uses the same internal function as mail() does.
 -	 * @see http://us2.php.net/manual/en/function.error-log.php
 -	 */
 -	public function appendLog($message,$messageType=0,$destination='',$extraHeaders='')
 -	{
 -		error_log($message,$messageType,$destination,$extraHeaders);
 -	}
 -
 -	/**
 -	 * Sends a cookie.
 -	 * Do not call this method directly. Operate with the result of {@link getCookies} instead.
 -	 * @param THttpCookie cook to be sent
 -	 */
 -	public function addCookie($cookie)
 -	{
 -		$request=$this->getRequest();
 -		if($request->getEnableCookieValidation())
 -		{
 -			$value=$this->getApplication()->getSecurityManager()->hashData($cookie->getValue());
 -			setcookie($cookie->getName(),$value,$cookie->getExpire(),$cookie->getPath(),$cookie->getDomain(),$cookie->getSecure());
 -		}
 -		else
 -			setcookie($cookie->getName(),$cookie->getValue(),$cookie->getExpire(),$cookie->getPath(),$cookie->getDomain(),$cookie->getSecure());
 -	}
 -
 -	/**
 -	 * Deletes a cookie.
 -	 * Do not call this method directly. Operate with the result of {@link getCookies} instead.
 -	 * @param THttpCookie cook to be deleted
 -	 */
 -	public function removeCookie($cookie)
 -	{
 -		setcookie($cookie->getName(),null,0,$cookie->getPath(),$cookie->getDomain(),$cookie->getSecure());
 -	}
 -
 -	/**
 -	 * @return string the type of HTML writer to be used, defaults to THtmlWriter
 -	 */
 -	public function getHtmlWriterType()
 -	{
 -		return $this->_htmlWriterType;
 -	}
 -
 -	/**
 -	 * @param string the type of HTML writer to be used, may be the class name or the namespace
 -	 */
 -	public function setHtmlWriterType($value)
 -	{
 -		$this->_htmlWriterType=$value;
 -	}
 -
 -	/**
 -	 * Creates a new instance of HTML writer.
 -	 * If the type of the HTML writer is not supplied, {@link getHtmlWriterType HtmlWriterType} will be assumed.
 -	 * @param string type of the HTML writer to be created. If null, {@link getHtmlWriterType HtmlWriterType} will be assumed.
 -	 */
 -	public function createHtmlWriter($type=null)
 -	{
 -		if($type===null)
 -			$type=$this->getHtmlWriterType();
 -		if($this->getHasAdapter())
 -			return $this->_adapter->createNewHtmlWriter($type, $this);
 -		else
 -		 	return $this->createNewHtmlWriter($type, $this);
 -	}
 -
 -	/**
 -	 * Create a new html writer instance.
 -	 * This method is used internally. Please use {@link createHtmlWriter} instead.
 -	 * @param string type of HTML writer to be created.
 -	 * @param ITextWriter text writer holding the contents.
 -	 */
 -	public function createNewHtmlWriter($type, $writer)
 -	{
 -		return Prado::createComponent($type, $writer);
 -	}
 -}
 -
 +<?php +/** + * THttpResponse class + * + * @author Qiang Xue <qiang.xue@gmail.com> + * @link http://www.pradosoft.com/ + * @copyright Copyright © 2005 PradoSoft + * @license http://www.pradosoft.com/license/ + * @version $Id$ + * @package System.Web + */ + +/** + * Includes the THttpResponse adapter. + */ +Prado::using('System.Web.THttpResponseAdapter'); + +/** + * THttpResponse class + * + * THttpResponse implements the mechanism for sending output to client users. + * + * To output a string to client, use {@link write()}. By default, the output is + * buffered until {@link flush()} is called or the application ends. The output in + * the buffer can also be cleaned by {@link clear()}. To disable output buffering, + * set BufferOutput property to false. + * + * To send cookies to client, use {@link getCookies()}. + * To redirect client browser to a new URL, use {@link redirect()}. + * To send a file to client, use {@link writeFile()}. + * + * By default, THttpResponse is registered with {@link TApplication} as the + * response module. It can be accessed via {@link TApplication::getResponse()}. + * + * THttpResponse may be configured in application configuration file as follows + * + * <module id="response" class="System.Web.THttpResponse" CacheExpire="20" CacheControl="nocache" BufferOutput="true" /> + * + * where {@link getCacheExpire CacheExpire}, {@link getCacheControl CacheControl} + * and {@link getBufferOutput BufferOutput} are optional properties of THttpResponse. + * + * THttpResponse sends charset header if either {@link setCharset() Charset} + * or {@link TGlobalization::setCharset() TGlobalization.Charset} is set. + * + * Since 3.1.2, HTTP status code can be set with the {@link setStatusCode StatusCode} property. + *  + * Note: Some HTTP Status codes can require additional header or body information. So, if you use {@link setStatusCode StatusCode} + * in your application, be sure to add theses informations. + * E.g : to make an http authentication : + * <code> + *  public function clickAuth ($sender, $param) + *  { + *     $response=$this->getResponse(); + *     $response->setStatusCode(401); + *     $response->appendHeader('WWW-Authenticate: Basic realm="Test"'); + *  }  + * </code> + *     + * This event handler will sent the 401 status code (Unauthorized) to the browser, with the WWW-Authenticate header field. This + * will force the browser to ask for a username and a password. + *   + * @author Qiang Xue <qiang.xue@gmail.com> + * @version $Id$ + * @package System.Web + * @since 3.0 + */ +class THttpResponse extends TModule implements ITextWriter +{ +	/** +	 * @var The differents defined status code by RFC 2616 {@link http://www.faqs.org/rfcs/rfc2616} +	 */ +	private static $HTTP_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',  +		300 => 'Multiple Choices', 301 => 'Moved Permanently', 302 => 'Found', 303 => 'See Other', 304 => 'Not Modified', 305 => 'Use Proxy', 307 => 'Temporary Redirect',  +		400 => 'Bad Request', 401 => 'Unauthorized', 402 => 'Payment Required', 403 => 'Forbidden', 404 => 'Not Found', 405 => 'Method Not Allowed', 406 => 'Not Acceptable', 407 => 'Proxy Authentication Required', 408 => 'Request Time-out', 409 => 'Conflict', 410 => 'Gone', 411 => 'Length Required', 412 => 'Precondition Failed', 413 => 'Request Entity Too Large', 414 => 'Request-URI Too Large', 415 => 'Unsupported Media Type', 416 => 'Requested range not satisfiable', 417 => 'Expectation Failed',  +		500 => 'Internal Server Error', 501 => 'Not Implemented', 502 => 'Bad Gateway', 503 => 'Service Unavailable', 504 => 'Gateway Time-out', 505 => 'HTTP Version not supported' +	); + +	/** +	 * @var boolean whether to buffer output +	 */ +	private $_bufferOutput=true; +	/** +	 * @var boolean if the application is initialized +	 */ +	private $_initialized=false; +	/** +	 * @var THttpCookieCollection list of cookies to return +	 */ +	private $_cookies=null; +	/** +	 * @var integer response status code +	 */ +	private $_status=200; +	/** +	 * @var string reason correspond to status code +	 */ +	private $_reason='OK'; +	/** +	 * @var string HTML writer type +	 */ +	private $_htmlWriterType='System.Web.UI.THtmlWriter'; +	/** +	 * @var string content type +	 */ +	private $_contentType=null; +	/** +	 * @var string character set, e.g. UTF-8 +	 */ +	private $_charset=''; +	/** +	 * @var THttpResponseAdapter adapter. +	 */ +	private $_adapter; + +	/** +	 * Destructor. +	 * Flushes any existing content in buffer. +	 */ +	public function __destruct() +	{ +		//if($this->_bufferOutput) +		//	@ob_end_flush(); +	} + +	/** +	 * @param THttpResponseAdapter response adapter +	 */ +	public function setAdapter(THttpResponseAdapter $adapter) +	{ +		$this->_adapter=$adapter; +	} + +	/** +	 * @return THttpResponseAdapter response adapter, null if not exist. +	 */ +	public function getAdapter() +	{ +		return $this->_adapter; +	} + +	/** +	 * @return boolean true if adapter exists, false otherwise. +	 */ +	public function getHasAdapter() +	{ +		return !is_null($this->_adapter); +	} + +	/** +	 * Initializes the module. +	 * This method is required by IModule and is invoked by application. +	 * It starts output buffer if it is enabled. +	 * @param TXmlElement module configuration +	 */ +	public function init($config) +	{ +		if($this->_bufferOutput) +			ob_start(); +		$this->_initialized=true; +		$this->getApplication()->setResponse($this); +	} + +	/** +	 * @return integer time-to-live for cached session pages in minutes, this has no effect for nocache limiter. Defaults to 180. +	 */ +	public function getCacheExpire() +	{ +		return session_cache_expire(); +	} + +	/** +	 * @param integer time-to-live for cached session pages in minutes, this has no effect for nocache limiter. +	 */ +	public function setCacheExpire($value) +	{ +		session_cache_expire(TPropertyValue::ensureInteger($value)); +	} + +	/** +	 * @return string cache control method to use for session pages +	 */ +	public function getCacheControl() +	{ +		return session_cache_limiter(); +	} + +	/** +	 * @param string cache control method to use for session pages. Valid values +	 *               include none/nocache/private/private_no_expire/public +	 */ +	public function setCacheControl($value) +	{ +		session_cache_limiter(TPropertyValue::ensureEnum($value,array('none','nocache','private','private_no_expire','public'))); +	} + +	/** +	 * @return string content type, default is text/html +	 */ +	public function setContentType($type) +	{ +		$this->_contentType = $type; +	} + +	/** +	 * @return string current content type +	 */ +	public function getContentType() +	{ +		return $this->_contentType; +	} + +	/** +	 * @return string output charset. +	 */ +	public function getCharset() +	{ +		return $this->_charset; +	} + +	/** +	 * @param string output charset. +	 */ +	public function setCharset($charset) +	{ +		$this->_charset = $charset; +	} + +	/** +	 * @return boolean whether to enable output buffer +	 */ +	public function getBufferOutput() +	{ +		return $this->_bufferOutput; +	} + +	/** +	 * @param boolean whether to enable output buffer +	 * @throws TInvalidOperationException if session is started already +	 */ +	public function setBufferOutput($value) +	{ +		if($this->_initialized) +			throw new TInvalidOperationException('httpresponse_bufferoutput_unchangeable'); +		else +			$this->_bufferOutput=TPropertyValue::ensureBoolean($value); +	} + +	/** +	 * @return integer HTTP status code, defaults to 200 +	 */ +	public function getStatusCode() +	{ +		return $this->_status; +	} + +	/** +	 * Set the HTTP status code for the response. +	 *  +	 * @param integer HTTP status code +	 */ +	public function setStatusCode($status, $reason=null) +	{ +		$status=TPropertyValue::ensureInteger($status); +		if(isset(self::$HTTP_STATUS_CODES[$status])) { +			$this->_reason=self::$HTTP_STATUS_CODES[$status]; +		}else{ +			if($reason===null || $reason==='') { +				throw new TInvalidDataValueException("response_status_reason_missing"); +			} +			$reason=TPropertyValue::ensureString($reason); +			if(strpos($reason, "\r")!=false || strpos($reason, "\n")!=false) { +				throw new TInvalidDataValueException("response_status_reason_barchars"); +			} +			$this->_reason=$reason; +		} +		$this->_status=$status; +	} + +	/** +	 * @param string HTTP status reason +	 */ +	public function getStatusReason() { +		return $this->_reason; +	} + +	/** +	 * @return THttpCookieCollection list of output cookies +	 */ +	public function getCookies() +	{ +		if($this->_cookies===null) +			$this->_cookies=new THttpCookieCollection($this); +		return $this->_cookies; +	} + +	/** +	 * Outputs a string. +	 * It may not be sent back to user immediately if output buffer is enabled. +	 * @param string string to be output +	 */ +	public function write($str) +	{ +		echo $str; +	} + +	/** +	 * Sends a file back to user. +	 * Make sure not to output anything else after calling this method. +	 * @param string file name +	 * @param string content to be set. If null, the content will be read from the server file pointed to by $fileName. +	 * @param string mime type of the content. +	 * @param array list of headers to be sent. Each array element represents a header string (e.g. 'Content-Type: text/plain'). +	 * @throws TInvalidDataValueException if the file cannot be found +	 */ +	public function writeFile($fileName,$content=null,$mimeType=null,$headers=null) +	{ +		static $defaultMimeTypes=array( +			'css'=>'text/css', +			'gif'=>'image/gif', +			'jpg'=>'image/jpeg', +			'jpeg'=>'image/jpeg', +			'htm'=>'text/html', +			'html'=>'text/html', +			'js'=>'javascript/js', +			'pdf'=>'application/pdf', +			'xls'=>'application/vnd.ms-excel', +		); + +		if($mimeType===null) +		{ +			$mimeType='text/plain'; +			if(function_exists('mime_content_type')) +				$mimeType=mime_content_type($fileName); +			else if(($ext=strrchr($fileName,'.'))!==false) +			{ +				$ext=substr($ext,1); +				if(isset($defaultMimeTypes[$ext])) +					$mimeType=$defaultMimeTypes[$ext]; +			} +		} +		$fn=basename($fileName); +		header("HTTP/1.1 {$this->_status} {$this->_reason}", true, $this->_status); +		if(is_array($headers)) +		{ +			foreach($headers as $h) +				header($h); +		} +		else +		{ +			header('Pragma: public'); +			header('Expires: 0'); +			header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); +		} +		header("Content-type: $mimeType"); +		header('Content-Length: '.($content===null?filesize($fileName):strlen($content))); +		header("Content-Disposition: attachment; filename=\"$fn\""); +		header('Content-Transfer-Encoding: binary'); +		if($content===null) +			readfile($fileName); +		else +			echo $content; +	} + +	/** +	 * Redirects the browser to the specified URL. +	 * The current application will be terminated after this method is invoked. +	 * @param string URL to be redirected to. If the URL is a relative one, the base URL of +	 * the current request will be inserted at the beginning. +	 */ +	public function redirect($url) +	{ +		if($this->getHasAdapter()) +			$this->_adapter->httpRedirect($url); +		else +			$this->httpRedirect($url); +	} + +	/** +	 * Redirect the browser to another URL and exists the current application. +	 * This method is used internally. Please use {@link redirect} instead. +	 * @param string URL to be redirected to. If the URL is a relative one, the base URL of +	 * the current request will be inserted at the beginning. +	 */ +	public function httpRedirect($url) +	{ +		if(!$this->getApplication()->getRequestCompleted()) +			$this->getApplication()->onEndRequest(); +		if($url[0]==='/') +			$url=$this->getRequest()->getBaseUrl().$url; +		header('Location: '.str_replace('&','&',$url)); +		exit(); +	} + +	/** +	 * Reloads the current page. +	 * The effect of this method call is the same as user pressing the +	 * refresh button on his browser (without post data). +	 **/ +	public function reload() +	{ +		$this->redirect($this->getRequest()->getRequestUri()); +	} + +	/** +	 * Flush the response contents and headers. +	 */ +	public function flush() +	{ +		if($this->getHasAdapter()) +			$this->_adapter->flushContent(); +		else +			$this->flushContent(); +	} + +	/** +	 * Outputs the buffered content, sends content-type and charset header. +	 * This method is used internally. Please use {@link flush} instead. +	 */ +	public function flushContent() +	{ +		Prado::trace("Flushing output",'System.Web.THttpResponse'); +		$this->sendHttpHeader(); +		$this->sendContentTypeHeader(); +		if($this->_bufferOutput) +			ob_flush(); +	} +	 +	/** +	 * Send the HTTP header with the status code (defaults to 200) and status reason (defaults to OK) +	 */ +	protected function sendHttpHeader () +	{ +		header("HTTP/1.1 {$this->_status} {$this->_reason}", true, $this->_status); +	} + +	/** +	 * Sends content type header if charset is not empty. +	 */ +	protected function sendContentTypeHeader() +	{ +		$charset=$this->getCharset(); +		if($charset==='' && ($globalization=$this->getApplication()->getGlobalization(false))!==null) +			$charset=$globalization->getCharset(); +		if($charset!=='') +		{ +			$contentType=$this->_contentType===null?'text/html':$this->_contentType; +			$this->appendHeader('Content-Type: '.$contentType.';charset='.$charset); +		} +		else if($this->_contentType!==null) +			$this->appendHeader('Content-Type: '.$this->_contentType.';charset=UTF-8'); +	} + +	/** +	 * Returns the content in the output buffer. +	 * The buffer will NOT be cleared after calling this method. +	 * Use {@link clear()} is you want to clear the buffer. +	 * @return string output that is in the buffer. +	 */ +	public function getContents() +	{ +		Prado::trace("Retrieving output",'System.Web.THttpResponse'); +		return $this->_bufferOutput?ob_get_contents():''; +	} + +	/** +	 * Clears any existing buffered content. +	 */ +	public function clear() +	{ +		if($this->_bufferOutput) +			ob_clean(); +		Prado::trace("Clearing output",'System.Web.THttpResponse'); +	} + +	/** +	 * Sends a header. +	 * @param string header +	 */ +	public function appendHeader($value) +	{ +		Prado::trace("Sending header '$value'",'System.Web.THttpResponse'); +		header($value); +	} + +	/** +	 * Writes a log message into error log. +	 * This method is simple wrapper of PHP function error_log. +	 * @param string The error message that should be logged +	 * @param integer where the error should go +	 * @param string The destination. Its meaning depends on the message parameter as described above +	 * @param string The extra headers. It's used when the message parameter is set to 1. This message type uses the same internal function as mail() does. +	 * @see http://us2.php.net/manual/en/function.error-log.php +	 */ +	public function appendLog($message,$messageType=0,$destination='',$extraHeaders='') +	{ +		error_log($message,$messageType,$destination,$extraHeaders); +	} + +	/** +	 * Sends a cookie. +	 * Do not call this method directly. Operate with the result of {@link getCookies} instead. +	 * @param THttpCookie cook to be sent +	 */ +	public function addCookie($cookie) +	{ +		$request=$this->getRequest(); +		if($request->getEnableCookieValidation()) +		{ +			$value=$this->getApplication()->getSecurityManager()->hashData($cookie->getValue()); +			setcookie($cookie->getName(),$value,$cookie->getExpire(),$cookie->getPath(),$cookie->getDomain(),$cookie->getSecure()); +		} +		else +			setcookie($cookie->getName(),$cookie->getValue(),$cookie->getExpire(),$cookie->getPath(),$cookie->getDomain(),$cookie->getSecure()); +	} + +	/** +	 * Deletes a cookie. +	 * Do not call this method directly. Operate with the result of {@link getCookies} instead. +	 * @param THttpCookie cook to be deleted +	 */ +	public function removeCookie($cookie) +	{ +		setcookie($cookie->getName(),null,0,$cookie->getPath(),$cookie->getDomain(),$cookie->getSecure()); +	} + +	/** +	 * @return string the type of HTML writer to be used, defaults to THtmlWriter +	 */ +	public function getHtmlWriterType() +	{ +		return $this->_htmlWriterType; +	} + +	/** +	 * @param string the type of HTML writer to be used, may be the class name or the namespace +	 */ +	public function setHtmlWriterType($value) +	{ +		$this->_htmlWriterType=$value; +	} + +	/** +	 * Creates a new instance of HTML writer. +	 * If the type of the HTML writer is not supplied, {@link getHtmlWriterType HtmlWriterType} will be assumed. +	 * @param string type of the HTML writer to be created. If null, {@link getHtmlWriterType HtmlWriterType} will be assumed. +	 */ +	public function createHtmlWriter($type=null) +	{ +		if($type===null) +			$type=$this->getHtmlWriterType(); +		if($this->getHasAdapter()) +			return $this->_adapter->createNewHtmlWriter($type, $this); +		else +		 	return $this->createNewHtmlWriter($type, $this); +	} + +	/** +	 * Create a new html writer instance. +	 * This method is used internally. Please use {@link createHtmlWriter} instead. +	 * @param string type of HTML writer to be created. +	 * @param ITextWriter text writer holding the contents. +	 */ +	public function createNewHtmlWriter($type, $writer) +	{ +		return Prado::createComponent($type, $writer); +	} +} +  ?>
\ No newline at end of file | 
