From 0eac20d93e2cc2a5f9024d4de96ebd42689859c2 Mon Sep 17 00:00:00 2001 From: Chuck Hagenbuch Date: Thu, 29 Oct 2009 18:41:14 -0400 Subject: [PATCH] Get rid of some random stuff in the Http response class, and add more from the Mad version. --- .../lib/Horde/Controller/Response/Http.php | 368 +++++++++++++-------- 1 file changed, 225 insertions(+), 143 deletions(-) diff --git a/framework/Controller/lib/Horde/Controller/Response/Http.php b/framework/Controller/lib/Horde/Controller/Response/Http.php index abd4f11fb..2a9930190 100644 --- a/framework/Controller/lib/Horde/Controller/Response/Http.php +++ b/framework/Controller/lib/Horde/Controller/Response/Http.php @@ -24,200 +24,282 @@ class Horde_Controller_Response_Http extends Horde_Controller_Response_Base { /** - * Adds the specified cookie to the response. - * - * This method can be called multiple times to set more than one cookie or - * to modify an already set one. Returns true if the adding was successful, - * false otherwise. + * Cookies sent with response + * @var array + */ + protected $_cookie = array(); + + /** + * Stored session data + * @var array + */ + protected $_session = array(); + + /** + * The url to redirect the request to + * @var string + */ + protected $_redirectUrl = null; + + /** + * The http status code. Default to OK + * @var string + */ + protected $_status = '200 OK'; + + /** + * HTTP headers to send + * @var array + */ + protected $_headers = array(); + + /** + * prevent cached content (ie) + * @var array + */ + protected $_preventCache = true; + + /** + * Body of the rendered page + * @var string + */ + protected $_body = null; + + + /*########################################################################## + # Construct + ##########################################################################*/ + + /** + * Construct response + */ + public function __construct(){} + + + /*########################################################################## + # Instance methods + ##########################################################################*/ + + /** + * Set the url for redirection * - * @param Ismo_Core_Cookie $cookie the cookie object to add - * @return boolean true if the adding was successful, - * false otherwise - * @access public + * @param string $toUrl */ - function addCookie($cookie) + public function redirect($toUrl) { - if (get_class($cookie) == 'ismo_core_cookie' || - get_parent_class($cookie) == 'ismo_core_cookie') { - $secure = 0; - if ($cookie->isSecure()) { - $secure = 1; - } + /* Alternate 301 branch - should allow choosing status: + $this->_status = '301 Moved Permanently'; + $this->_redirectUrl = $toUrl; + $this->_headers["Location: $toUrl"] = true; + $this->_headers["Connection: close"] = true; + */ - setcookie( $cookie->getName(), - $cookie->getValue(), - $cookie->getExpire(), - $cookie->getPath(), - $cookie->getDomain(), - $secure ); - - return true; - } + $this->_status = '302 Found'; + $this->_redirectUrl = $toUrl; + $this->_headers["Location: $toUrl"] = true; + } - return false; + /** + * Page was not found + */ + public function pageNotFound() + { + $this->_status = '404 Page Not Found'; } /** - * Deletes the specified cookie from the response. + * Send content to the browser. * - * @param IsmoCookie $cookie the cookie object to delete - * @access public + * After the body content has been sent, terminates the execution of the + * PHP script. */ - function deleteCookie($cookie) + public function send() { - if (get_class($cookie) == 'ismo_core_cookie' || - get_parent_class($cookie) == 'ismo_core_cookie') { - $secure = 0; - if ($cookie->isSecure()) { - $secure = 1; - } + // send all headers + foreach ($this->getHeaders() as $header => $replace) { + header($header, $replace); + } - // set the expiration date to one hour ago - $cookie->setExpire(time() - 3600); + // set cookies + foreach ($this->_cookie as $name => $options) { + setcookie($name, $options['value'], $options['expiration'], $options['path']); + } - setcookie( $cookie->getName(), - $cookie->getValue(), - $cookie->getExpire(), - $cookie->getPath(), - $cookie->getDomain(), - $secure ); + // set session data + foreach ($this->_session as $name => $value) { + $_SESSION[$name] = $value; } + + // send body + print $this->getBody(); } + + /*########################################################################## + # Accessors + ##########################################################################*/ + /** - * Adds a response header with the given name and value. + * Set a cookie * - * This method allows response headers to have multiple values. Returns true - * if the header could be added, false otherwise. False will be returned - * f.g. when the headers have already been sent. The replace parameter - * indicates if an already existing header with the same name should be - * replaced or not. - * - * @param string $name the name of the header - * @param string $value the value of the header - * @param boolean $replace should the header be replaced or not - * @return boolean true if the header could be set, false - * otherwise - * @access public + * @param string $name + * @param string $value + * @param int $expiration + * @param string $path */ - function addHeader($name, $value, $replace) + public function setCookie($name, $value, $expiration=0, $path=null) { - if (headers_sent()) { - return false; - } - - header("$name: $value", $replace); - return true; + // only set cookies for this matter by default + $this->_cookie[$name] = array('value' => $value, + 'expiration' => $expiration, + 'path' => isset($path) ? $path : '/'); } /** - * Sends an error response to the client using the specified status code. + * Set a session variable OR all session variables (by array). * - * Sends an error response to the client using the specified status code. - * This will create a page that looks like an HTML-formatted server error - * page containing the specifed message (if any), setting the content type - * to "text/html", leaving cookies and other headers unmodified. + * + * // set single session var + * $this->setSession('NAME', 'my session'); * - * If the headers have already been sent this method returns false - * otherwise true. After this method the response should be - * considered commited, i.e. both headers and data have been sent to the - * client. + * // set all session vars (overwrites previous single sessions set) + * $this->setSession(array('NAME 1' => 'my session 1', + * 'NAME 2' => 'my session 2')); + * * - * @todo decide what the error page should look like - * @param string $code the status code to use - * @param string $msg the message to show - * @return boolean true if the error response could be - * send, false otherwise (if the headers - * have already been sent) - * @access public + * @param mixed $name + * @param mixed $value */ - function sendError($code, $msg = NULL) + public function setSession($name, $value=null) { - if (headers_sent()) { - return false; + // Set by name or all at once + if (is_string($name)) { + $this->_session[$name] = $value; + } elseif (is_array($name)) { + $this->_session = $name; } + } - header('HTTP/1.0 '.$code); - - // @todo what kind of HTML page should it be? - ?> - - -<?php echo $code ?> - -

-_headers[$header] = $replace; } -?> -
- -_body = $body; } /** - * Sends a temporary redirect respones to the client using the specifed - * redirect URL. + * Set the HTTP status code * - * If the headers have already been sent this method returns false - * otherwise true. After this method the response should be - * considered commited. + * @param string $status + */ + public function setStatus($status) + { + $this->_status = $status; + } + + /** + * Get the headers of the response * - * Examples: - * - * $u = new Ismo_Core_Url("http://a.b.c"); - * $response->sendRedirect($u); - * - * Redirects the browser to http://a.b.c using an Ismo_Core_Url instance. + * @return array + */ + public function getHeaders() + { + $headers["HTTP/1.1 $this->_status"] = true; + + if ($this->_status == '200 OK') { + $headers["Connection: close"] = true; + $headers["Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"] = true; + + // Try to keep browser from caching any screen to ensure current data. + if ($this->_preventCache && !isset($this->_headers["Expires: 0"])) { + $headers["Expires: Mon, 26 Jul 1997 05:00:00 GMT"] = true; + $headers["Cache-Control: no-store, no-cache, must-revalidate"] = true; + $headers["Pragma: no-cache"] = true; + } + } + return array_merge($this->_headers, $headers); + } + + /** + * Get the body of the response * - * - * $response->sendRedirect("http://d.e.f"); - * - * Redirects the browser to http://d.e.f using a string. + * @return string + */ + public function getBody() + { + return $this->_body; + } + + /** + * Get the HTTP status of the response * - * @param mixed $location url to redirect to, this can either be an - * Ismo_Core_Url instance or a string - * @return boolean false if the headers have already - * been sent, true otherwise - * @access public + * @return string */ - function sendRedirect($location) + public function getStatus() { - if (headers_sent()) { - return false; - } + return $this->_status; + } - if (get_class($location) == 'ismo_core_url') { - $location = $location->toString(false); - } + /** + * Get 3 digit http code from the status + * + * @return int + */ + public function getStatusCode() + { + preg_match("/(\d\d\d)/", $this->_status, $matches); + return isset($matches[1]) ? (int) $matches[1] : 0; + } - /* so that it works correctly for IE */ - header('HTTP/1.1 301 Moved Permanently'); - header('Location: ' . $location); - header('Connection: close'); + /** + * @todo charset + */ + public function setContentType($mimeType) + { + $this->setHeader("Content-Type: $mimeType", $replace=true); + } - return true; + /** + * Get if the response is a 200 OK + * + * @return boolean + */ + public function isOk() + { + return substr($this->_status, 0, 1) == '2'; } /** - * Sets the status code for this request. + * Get if the response is a redirection * - * Sets the status code for this response. This method is used to set the - * return status code when there is no error (for example, for the status - * codes SC_OK or SC_MOVED_TEMPORARILY). If there is an error, and the - * caller wishes to provide a message for the response, the sendError() - * method should be used instead. + * @return boolean + */ + public function isRedirect() + { + return substr($this->_status, 0, 1) == '3'; + } + + /** + * Get where the page is redirecting to * - * @param string $code the status code to set - * @access public - * @see sendError() + * @return string */ - function setStatus($code) + public function getRedirectUrl() { - header('HTTP/1.0 ' . $code); + return $this->_redirectUrl; } } -- 2.11.0