365 lines
		
	
	
		
			9.8 KiB
		
	
	
	
		
			PHP
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			365 lines
		
	
	
		
			9.8 KiB
		
	
	
	
		
			PHP
		
	
	
		
			Executable File
		
	
	
	
	
<?php 
 | 
						|
 | 
						|
/**
 | 
						|
 * Class Response
 | 
						|
 * Simplified copy of Symfony/Http-Foundation Response
 | 
						|
 * to allow compatibility with frameworks
 | 
						|
 *
 | 
						|
 * @package Filemanager
 | 
						|
 */
 | 
						|
class Response {
 | 
						|
 | 
						|
	const HTTP_CONTINUE = 100;
 | 
						|
	const HTTP_SWITCHING_PROTOCOLS = 101;
 | 
						|
	const HTTP_PROCESSING = 102;            // RFC2518
 | 
						|
	const HTTP_OK = 200;
 | 
						|
	const HTTP_CREATED = 201;
 | 
						|
	const HTTP_ACCEPTED = 202;
 | 
						|
	const HTTP_NON_AUTHORITATIVE_INFORMATION = 203;
 | 
						|
	const HTTP_NO_CONTENT = 204;
 | 
						|
	const HTTP_RESET_CONTENT = 205;
 | 
						|
	const HTTP_PARTIAL_CONTENT = 206;
 | 
						|
	const HTTP_MULTI_STATUS = 207;          // RFC4918
 | 
						|
	const HTTP_ALREADY_REPORTED = 208;      // RFC5842
 | 
						|
	const HTTP_IM_USED = 226;               // RFC3229
 | 
						|
	const HTTP_MULTIPLE_CHOICES = 300;
 | 
						|
	const HTTP_MOVED_PERMANENTLY = 301;
 | 
						|
	const HTTP_FOUND = 302;
 | 
						|
	const HTTP_SEE_OTHER = 303;
 | 
						|
	const HTTP_NOT_MODIFIED = 304;
 | 
						|
	const HTTP_USE_PROXY = 305;
 | 
						|
	const HTTP_RESERVED = 306;
 | 
						|
	const HTTP_TEMPORARY_REDIRECT = 307;
 | 
						|
	const HTTP_PERMANENTLY_REDIRECT = 308;  // RFC7238
 | 
						|
	const HTTP_BAD_REQUEST = 400;
 | 
						|
	const HTTP_UNAUTHORIZED = 401;
 | 
						|
	const HTTP_PAYMENT_REQUIRED = 402;
 | 
						|
	const HTTP_FORBIDDEN = 403;
 | 
						|
	const HTTP_NOT_FOUND = 404;
 | 
						|
	const HTTP_METHOD_NOT_ALLOWED = 405;
 | 
						|
	const HTTP_NOT_ACCEPTABLE = 406;
 | 
						|
	const HTTP_PROXY_AUTHENTICATION_REQUIRED = 407;
 | 
						|
	const HTTP_REQUEST_TIMEOUT = 408;
 | 
						|
	const HTTP_CONFLICT = 409;
 | 
						|
	const HTTP_GONE = 410;
 | 
						|
	const HTTP_LENGTH_REQUIRED = 411;
 | 
						|
	const HTTP_PRECONDITION_FAILED = 412;
 | 
						|
	const HTTP_REQUEST_ENTITY_TOO_LARGE = 413;
 | 
						|
	const HTTP_REQUEST_URI_TOO_LONG = 414;
 | 
						|
	const HTTP_UNSUPPORTED_MEDIA_TYPE = 415;
 | 
						|
	const HTTP_REQUESTED_RANGE_NOT_SATISFIABLE = 416;
 | 
						|
	const HTTP_EXPECTATION_FAILED = 417;
 | 
						|
	const HTTP_I_AM_A_TEAPOT = 418;                                               // RFC2324
 | 
						|
	const HTTP_UNPROCESSABLE_ENTITY = 422;                                        // RFC4918
 | 
						|
	const HTTP_LOCKED = 423;                                                      // RFC4918
 | 
						|
	const HTTP_FAILED_DEPENDENCY = 424;                                           // RFC4918
 | 
						|
	const HTTP_RESERVED_FOR_WEBDAV_ADVANCED_COLLECTIONS_EXPIRED_PROPOSAL = 425;   // RFC2817
 | 
						|
	const HTTP_UPGRADE_REQUIRED = 426;                                            // RFC2817
 | 
						|
	const HTTP_PRECONDITION_REQUIRED = 428;                                       // RFC6585
 | 
						|
	const HTTP_TOO_MANY_REQUESTS = 429;                                           // RFC6585
 | 
						|
	const HTTP_REQUEST_HEADER_FIELDS_TOO_LARGE = 431;                             // RFC6585
 | 
						|
	const HTTP_INTERNAL_SERVER_ERROR = 500;
 | 
						|
	const HTTP_NOT_IMPLEMENTED = 501;
 | 
						|
	const HTTP_BAD_GATEWAY = 502;
 | 
						|
	const HTTP_SERVICE_UNAVAILABLE = 503;
 | 
						|
	const HTTP_GATEWAY_TIMEOUT = 504;
 | 
						|
	const HTTP_VERSION_NOT_SUPPORTED = 505;
 | 
						|
	const HTTP_VARIANT_ALSO_NEGOTIATES_EXPERIMENTAL = 506;                        // RFC2295
 | 
						|
	const HTTP_INSUFFICIENT_STORAGE = 507;                                        // RFC4918
 | 
						|
	const HTTP_LOOP_DETECTED = 508;                                               // RFC5842
 | 
						|
	const HTTP_NOT_EXTENDED = 510;                                                // RFC2774
 | 
						|
	const HTTP_NETWORK_AUTHENTICATION_REQUIRED = 511;                             // RFC6585
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Status codes translation table.
 | 
						|
	 *
 | 
						|
	 * The list of codes is complete according to the
 | 
						|
	 * {@link http://www.iana.org/assignments/http-status-codes/ Hypertext Transfer Protocol (HTTP) Status Code Registry}
 | 
						|
	 * (last updated 2012-02-13).
 | 
						|
	 *
 | 
						|
	 * Unless otherwise noted, the status code is defined in RFC2616.
 | 
						|
	 *
 | 
						|
	 * @var array
 | 
						|
	 */
 | 
						|
	public static $statusTexts = array(
 | 
						|
		100 => 'Continue',
 | 
						|
		101 => 'Switching Protocols',
 | 
						|
		102 => 'Processing',            // RFC2518
 | 
						|
		200 => 'OK',
 | 
						|
		201 => 'Created',
 | 
						|
		202 => 'Accepted',
 | 
						|
		203 => 'Non-Authoritative Information',
 | 
						|
		204 => 'No Content',
 | 
						|
		205 => 'Reset Content',
 | 
						|
		206 => 'Partial Content',
 | 
						|
		207 => 'Multi-Status',          // RFC4918
 | 
						|
		208 => 'Already Reported',      // RFC5842
 | 
						|
		226 => 'IM Used',               // RFC3229
 | 
						|
		300 => 'Multiple Choices',
 | 
						|
		301 => 'Moved Permanently',
 | 
						|
		302 => 'Found',
 | 
						|
		303 => 'See Other',
 | 
						|
		304 => 'Not Modified',
 | 
						|
		305 => 'Use Proxy',
 | 
						|
		306 => 'Reserved',
 | 
						|
		307 => 'Temporary Redirect',
 | 
						|
		308 => 'Permanent Redirect',    // RFC7238
 | 
						|
		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 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 => 'Requested Range Not Satisfiable',
 | 
						|
		417 => 'Expectation Failed',
 | 
						|
		418 => 'I\'m a teapot',                                               // RFC2324
 | 
						|
		422 => 'Unprocessable Entity',                                        // RFC4918
 | 
						|
		423 => 'Locked',                                                      // RFC4918
 | 
						|
		424 => 'Failed Dependency',                                           // RFC4918
 | 
						|
		425 => 'Reserved for WebDAV advanced collections expired proposal',   // RFC2817
 | 
						|
		426 => 'Upgrade Required',                                            // RFC2817
 | 
						|
		428 => 'Precondition Required',                                       // RFC6585
 | 
						|
		429 => 'Too Many Requests',                                           // RFC6585
 | 
						|
		431 => 'Request Header Fields Too Large',                             // RFC6585
 | 
						|
		500 => 'Internal Server Error',
 | 
						|
		501 => 'Not Implemented',
 | 
						|
		502 => 'Bad Gateway',
 | 
						|
		503 => 'Service Unavailable',
 | 
						|
		504 => 'Gateway Timeout',
 | 
						|
		505 => 'HTTP Version Not Supported',
 | 
						|
		506 => 'Variant Also Negotiates (Experimental)',                      // RFC2295
 | 
						|
		507 => 'Insufficient Storage',                                        // RFC4918
 | 
						|
		508 => 'Loop Detected',                                               // RFC5842
 | 
						|
		510 => 'Not Extended',                                                // RFC2774
 | 
						|
		511 => 'Network Authentication Required',                             // RFC6585
 | 
						|
	);
 | 
						|
 | 
						|
	/**
 | 
						|
	 * @var  string
 | 
						|
	 */
 | 
						|
	protected $content;
 | 
						|
 | 
						|
	/**
 | 
						|
	 * @var  int
 | 
						|
	 */
 | 
						|
	protected $statusCode;
 | 
						|
 | 
						|
	/**
 | 
						|
	 * @var  string
 | 
						|
	 */
 | 
						|
	protected $statusText;
 | 
						|
 | 
						|
	/**
 | 
						|
	 * @var  array
 | 
						|
	 */
 | 
						|
	public $headers;
 | 
						|
 | 
						|
	/**
 | 
						|
	 * @var string
 | 
						|
	 */
 | 
						|
	protected $version;
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Construct the response
 | 
						|
	 *
 | 
						|
	 * @param  mixed  $content
 | 
						|
	 * @param  int    $statusCode
 | 
						|
	 * @param  array  $headers
 | 
						|
	 */
 | 
						|
	public function __construct($content = '', $statusCode = 200, $headers = array())
 | 
						|
	{
 | 
						|
		$this->setContent($content);
 | 
						|
		$this->setStatusCode($statusCode);
 | 
						|
		$this->headers = $headers;
 | 
						|
		$this->version = '1.1';
 | 
						|
	}
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Set the content on the response.
 | 
						|
	 *
 | 
						|
	 * @param  mixed  $content
 | 
						|
	 * @return $this
 | 
						|
	 */
 | 
						|
	public function setContent($content)
 | 
						|
	{
 | 
						|
		if ($content instanceof ArrayObject || is_array($content))
 | 
						|
		{
 | 
						|
			$this->headers['Content-Type'] = array('application/json');
 | 
						|
 | 
						|
			$content = json_encode($content);
 | 
						|
		}
 | 
						|
 | 
						|
		$this->content = $content;
 | 
						|
	}
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Returns the Response as an HTTP string.
 | 
						|
	 *
 | 
						|
	 * The string representation of the Response is the same as the
 | 
						|
	 * one that will be sent to the client only if the prepare() method
 | 
						|
	 * has been called before.
 | 
						|
	 *
 | 
						|
	 * @return string The Response as an HTTP string
 | 
						|
	 *
 | 
						|
	 * @see prepare()
 | 
						|
	 */
 | 
						|
	public function __toString()
 | 
						|
	{
 | 
						|
		return
 | 
						|
			sprintf('HTTP/%s %s %s', $this->version, $this->statusCode, $this->statusText)."\r\n".
 | 
						|
			$this->headers."\r\n".
 | 
						|
			$this->getContent();
 | 
						|
	}
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Sets the response status code.
 | 
						|
	 *
 | 
						|
	 * @param int   $code HTTP status code
 | 
						|
	 * @param mixed $text HTTP status text
 | 
						|
	 *
 | 
						|
	 * If the status text is null it will be automatically populated for the known
 | 
						|
	 * status codes and left empty otherwise.
 | 
						|
	 *
 | 
						|
	 * @return Response
 | 
						|
	 *
 | 
						|
	 * @throws \InvalidArgumentException When the HTTP status code is not valid
 | 
						|
	 *
 | 
						|
	 * @api
 | 
						|
	 */
 | 
						|
	public function setStatusCode($code, $text = null)
 | 
						|
	{
 | 
						|
		$this->statusCode = $code = (int) $code;
 | 
						|
		if ($this->isInvalid()) {
 | 
						|
			throw new InvalidArgumentException(sprintf('The HTTP status code "%s" is not valid.', $code));
 | 
						|
		}
 | 
						|
 | 
						|
		if (null === $text) {
 | 
						|
			$this->statusText = isset(self::$statusTexts[$code]) ? self::$statusTexts[$code] : '';
 | 
						|
 | 
						|
			return $this;
 | 
						|
		}
 | 
						|
 | 
						|
		if (false === $text) {
 | 
						|
			$this->statusText = '';
 | 
						|
 | 
						|
			return $this;
 | 
						|
		}
 | 
						|
 | 
						|
		$this->statusText = $text;
 | 
						|
 | 
						|
		return $this;
 | 
						|
	}
 | 
						|
 | 
						|
	// http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
 | 
						|
	/**
 | 
						|
	 * Is response invalid?
 | 
						|
	 *
 | 
						|
	 * @return bool
 | 
						|
	 *
 | 
						|
	 * @api
 | 
						|
	 */
 | 
						|
	public function isInvalid()
 | 
						|
	{
 | 
						|
		return $this->statusCode < 100 || $this->statusCode >= 600;
 | 
						|
	}
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Set a header on the Response.
 | 
						|
	 *
 | 
						|
	 * @param string $key
 | 
						|
	 * @param string $value
 | 
						|
	 * @param bool $replace
 | 
						|
	 * @return $this
 | 
						|
	 */
 | 
						|
	public function header($key, $value, $replace = true)
 | 
						|
	{
 | 
						|
		if (empty($this->headers[$key]))
 | 
						|
		{
 | 
						|
			$this->headers[$key] = array();
 | 
						|
		}
 | 
						|
		if ($replace)
 | 
						|
		{
 | 
						|
			$this->headers[$key] = array($value);
 | 
						|
		}
 | 
						|
		else
 | 
						|
		{
 | 
						|
			$this->headers[$key][] = $value;
 | 
						|
		}
 | 
						|
 | 
						|
		return $this;
 | 
						|
	}
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Sends HTTP headers and content.
 | 
						|
	 *
 | 
						|
	 * @return Response
 | 
						|
	 *
 | 
						|
	 * @api
 | 
						|
	 */
 | 
						|
	public function send()
 | 
						|
	{
 | 
						|
		$this->sendHeaders();
 | 
						|
		$this->sendContent();
 | 
						|
 | 
						|
		if (function_exists('fastcgi_finish_request')) {
 | 
						|
			fastcgi_finish_request();
 | 
						|
		}
 | 
						|
 | 
						|
		return $this;
 | 
						|
	}
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Sends content for the current web response.
 | 
						|
	 *
 | 
						|
	 * @return Response
 | 
						|
	 */
 | 
						|
	public function sendContent()
 | 
						|
	{
 | 
						|
		echo $this->content;
 | 
						|
 | 
						|
		return $this;
 | 
						|
	}
 | 
						|
 | 
						|
	/**
 | 
						|
	 * Sends HTTP headers.
 | 
						|
	 *
 | 
						|
	 * @return Response
 | 
						|
	 */
 | 
						|
	public function sendHeaders()
 | 
						|
	{
 | 
						|
		// headers have already been sent by the developer
 | 
						|
		if (headers_sent()) {
 | 
						|
			return $this;
 | 
						|
		}
 | 
						|
 | 
						|
		// status
 | 
						|
		header(sprintf('HTTP/%s %s %s', $this->version, $this->statusCode, $this->statusText), true, $this->statusCode);
 | 
						|
 | 
						|
		// headers
 | 
						|
		foreach ($this->headers as $name => $values) {
 | 
						|
			if (is_array($values))
 | 
						|
			{
 | 
						|
				foreach ($values as $value)
 | 
						|
				{
 | 
						|
					header($name . ': ' . $value, false, $this->statusCode);
 | 
						|
				}
 | 
						|
			}
 | 
						|
			else
 | 
						|
			{
 | 
						|
				header($name . ': ' . $values, false, $this->statusCode);
 | 
						|
			}
 | 
						|
		}
 | 
						|
 | 
						|
		return $this;
 | 
						|
	}
 | 
						|
} |