Source for file jResponse.class.php

Documentation is available at jResponse.class.php

  1. <?php
  2. /**
  3. @package     jelix
  4. @subpackage  core
  5. @author      Laurent Jouanneau
  6. @contributor Julien Issler, Brice Tence
  7. @contributor Florian Lonqueu-Brochard
  8. @copyright   2005-2012 Laurent Jouanneau
  9. @copyright   2010 Julien Issler, 2011 Brice Tence
  10. @copyright   2011 Florian Lonqueu-Brochard
  11. @link        http://www.jelix.org
  12. @licence     GNU Lesser General Public Licence see LICENCE file or http://www.gnu.org/licenses/lgpl.html
  13. */
  14.  
  15. /**
  16. * base class for response object
  17. * A response object is responsible to generate a content in a specific format.
  18. @package  jelix
  19. @subpackage core
  20. */
  21. abstract class jResponse {
  22.  
  23.     /**
  24.     * @var string ident of the response type
  25.     */
  26.     protected  $_type = null;
  27.  
  28.     /**
  29.      * @var array list of http headers that will be send to the client
  30.      */
  31.     protected $_httpHeaders = array();
  32.  
  33.     /**
  34.      * @var boolean indicates if http headers have already been sent to the client
  35.      */
  36.     protected $_httpHeadersSent = false;
  37.  
  38.     /**
  39.      * @var string  the http status code to send
  40.      */
  41.     protected $_httpStatusCode ='200';
  42.     /**
  43.      * @var string  the http status message to send
  44.      */
  45.     protected $_httpStatusMsg ='OK';
  46.  
  47.     /**
  48.      * @var boolean Should we output only the headers or the entire response
  49.      */ 
  50.     protected $_outputOnlyHeaders = false;
  51.     
  52.     
  53.     public $httpVersion = '1.1';
  54.     public $forcedHttpVersion = false;
  55.  
  56.     /**
  57.     * constructor
  58.     */
  59.     function __construct({
  60.  
  61.         ifjApp::config()->httpVersion != "" {
  62.             $this->httpVersion = jApp::config()->httpVersion;
  63.             $this->forcedHttpVersion = true;
  64.         }
  65.     }
  66.  
  67.     /**
  68.      * Send the response in the correct format. If errors or exceptions appears
  69.      * during this method, outputErrors will be called. So the
  70.      * the content should be generated using the output buffer if errors can
  71.      * be appeared during this generation. Be care of http headers.
  72.      *
  73.      * @return boolean    true if the output is ok
  74.      * @internal should take care about errors
  75.      */
  76.     abstract public function output();
  77.  
  78.     /**
  79.      * Send a response with a generic error message.
  80.      */
  81.     public function outputErrors({
  82.         // if accept text/html
  83.         if (isset($_SERVER['HTTP_ACCEPT']&& strstr($_SERVER['HTTP_ACCEPT'],'text/html')) {
  84.             require_once(JELIX_LIB_CORE_PATH.'responses/jResponseBasicHtml.class.php');
  85.             $response new jResponseBasicHtml();
  86.             $response->outputErrors();
  87.         }
  88.         else {
  89.             // output text response
  90.             header("HTTP/{$this->httpVersion} 500 Internal jelix error");
  91.             header('Content-type: text/plain');
  92.             echo jApp::coord()->getGenericErrorMessage();
  93.         }
  94.     }
  95.  
  96.     /**
  97.      * return the response type name
  98.      * @return string the name
  99.      */
  100.     public final function getType(){ return $this->_type;}
  101.  
  102.     /**
  103.      * return the format type name (eg the family type name)
  104.      * @return string the name
  105.      */
  106.     public function getFormatType(){ return $this->_type;}
  107.  
  108.     /**
  109.      * add an http header to the response.
  110.      * will be send during the output of the response
  111.      * @param string $htype the header type ("Content-Type", "Date-modified"...)
  112.      * @param string $hcontent value of the header type
  113.      * @param integer $overwrite false or 0 if the value should be set only if it doesn't still exist
  114.      *                           -1 to add the header with the existing values
  115.      *                           true or 1 to replace the existing header
  116.      */
  117.     public function addHttpHeader($htype, $hcontent, $overwrite=true){
  118.         if (isset($this->_httpHeaders[$htype])) {
  119.             $val = $this->_httpHeaders[$htype];
  120.             if ($overwrite === -1) {
  121.                 if (!is_array($val))
  122.                     $this->_httpHeaders[$htype] = array($val, $hcontent);
  123.                 else
  124.                     $this->_httpHeaders[$htype][] = $hcontent;
  125.                 return;
  126.             }
  127.             else if (!$overwrite) {
  128.                 return;
  129.             }
  130.         }
  131.         $this->_httpHeaders[$htype]=$hcontent;
  132.     }
  133.  
  134.     /**
  135.      * delete all http headers
  136.      */
  137.     public function clearHttpHeaders(){
  138.         $this->_httpHeaders = array();
  139.         $this->_httpStatusCode ='200';
  140.         $this->_httpStatusMsg ='OK';
  141.     }
  142.  
  143.     /**
  144.      * set the http status code for the http header
  145.      * @param string $code  the status code (200, 404...)
  146.      * @param string $msg the message following the status code ("OK", "Not Found"..)
  147.      */
  148.     public function setHttpStatus($code, $msg){ $this->_httpStatusCode=$code; $this->_httpStatusMsg=$msg;}
  149.  
  150.     /**
  151.      * send http headers
  152.      */
  153.     protected function sendHttpHeaders(){
  154.         header( ( isset($_SERVER['SERVER_PROTOCOL']) && !$this->forcedHttpVersion ?
  155.                         $_SERVER['SERVER_PROTOCOL'] :
  156.                         'HTTP/'.$this->httpVersion ) .
  157.                 ' '.$this->_httpStatusCode.' '.$this->_httpStatusMsg );
  158.         foreach($this->_httpHeaders as $ht=>$hc) {
  159.             if (is_array($hc)) {
  160.                 foreach ($hc as $val) {
  161.                     header($ht.': '.$val);
  162.                 }
  163.             }
  164.             else
  165.                 header($ht.': '.$hc);
  166.         }
  167.         $this->_httpHeadersSent=true;
  168.     }
  169.     
  170.     
  171.     /**
  172.      * Normalize a date into GMT format
  173.      * @param mixed $date Can be a jDateTime object, a DateTime object or a string understandable by strtotime
  174.      * @return string    a date in GMT format
  175.      */
  176.     protected function _normalizeDate($date){
  177.         if($date instanceof <a href="../jelix/utils/jDateTime.html">jDateTime</a>){
  178.             return gmdate('D, d M Y H:i:s \G\M\T', $date->toString(<a href="../jelix/utils/jDateTime.html">jDateTime</a>::TIMESTAMP_FORMAT));
  179.         }
  180.         elseif($date instanceof DateTime){
  181.             return gmdate('D, d M Y H:i:s \G\M\T', $date->getTimestamp());
  182.         }
  183.         else{
  184.             return gmdate('D, d M Y H:i:s \G\M\T', strtotime($date));
  185.         }
  186.     } 
  187.     
  188.     /**
  189.      * check if the request is of type GET or HEAD
  190.      */
  191.     protected function _checkRequestType(){
  192.         
  193.         $allowedTypes = array('GET', 'HEAD');
  194.         
  195.         if(in_array($_SERVER['REQUEST_METHOD'], $allowedTypes)){
  196.             return true;
  197.         }
  198.         else {
  199.             trigger_error(<a href="../jelix/core/jLocale.html">jLocale</a>::get('jelix~errors.rep.bad.request.method'), E_USER_WARNING);
  200.             return false;
  201.         }
  202.     }
  203.     
  204.     
  205.     
  206.     /**
  207.     * Clean the differents caches headers
  208.     */  
  209.     public function cleanCacheHeaders(){
  210.         $toClean = array('Cache-Control', 'Expires', 'Pragma' );
  211.         foreach($toClean as $h){
  212.             unset($this->_httpHeaders[$h]);
  213.             $this->addHttpHeader($h, '');
  214.         }
  215.     }
  216.     
  217.     
  218.     /**
  219.      * Set an expires header to the page/ressource.
  220.      * 
  221.      * @param mixed $dateLastModified Can be a jDateTime object, a DateTime object or a string understandable by strtotime
  222.      * @param boolean $cleanCacheHeaderTrue for clean/delete other cache headers. Default : true. 
  223.      *
  224.      * @see _normalizeDate
  225.      */
  226.     public function setExpires($date, $cleanCacheHeader = true) {
  227.         
  228.         if(!$this->_checkRequestType())
  229.             return;
  230.         
  231.         if($cleanCacheHeader)
  232.             $this->cleanCacheHeaders();
  233.  
  234.         $date = $this->_normalizeDate($date);
  235.         $this->addHttpHeader('Expires', $date);
  236.     }
  237.     
  238.  
  239.  
  240.     /**
  241.      * Set a life time for the page/ressource.
  242.      * 
  243.      * @param int $time             Time during which the page will be cached. Express in seconds.
  244.      * @param boolean $sharedCache      True if the lifetime concern a public/shared cache. Default : false.
  245.      * @param boolean $cleanCacheHeaderTrue for clean/delete other cache headers. Default : true. 
  246.      */
  247.     public function setLifetime($time, $sharedCache = false, $cleanCacheHeader = true) {
  248.         
  249.         if(!$this->_checkRequestType())
  250.             return;
  251.            
  252.         if($cleanCacheHeader)
  253.             $this->cleanCacheHeaders();
  254.         
  255.         $type = $sharedCache ? 'public' : 'private';
  256.  
  257.         $this->addHttpHeader('Cache-Control', $type.', '.($sharedCache ? 's-' : '').'maxage='.$time);
  258.     }
  259.     
  260.     /**
  261.      * Use the HTPP headers Last-Modified to see if the ressource in client cache is fresh
  262.      * 
  263.      * @param mixed $dateLastModified Can be a jDateTime object, a DateTime object or a string understandable by strtotime
  264.      * @param boolean $cleanCacheHeader True for clean/delete other cache headers. Default : true. 
  265.      * 
  266.      * @return boolean    True if the client ressource version is fresh, false otherwise
  267.      */
  268.     public function isValidCache($dateLastModified = null, $etag = null, $cleanCacheHeader = true){
  269.         
  270.         if(!$this->_checkRequestType())
  271.             return false;
  272.         
  273.         $notModified = false;
  274.         
  275.         if($cleanCacheHeader)
  276.             $this->cleanCacheHeaders();
  277.          
  278.         if($dateLastModified != null){
  279.             $dateLastModified = $this->_normalizeDate($dateLastModified);
  280.             $lastModified = <a href="../jelix/core/jApp.html">jApp</a>::coord()->request->header('If-Modified-Since');
  281.             if ($lastModified !== null && $lastModified == $dateLastModified) {
  282.                 $notModified = true;
  283.             }
  284.             else {
  285.                 $this->addHttpHeader('Last-Modified', $dateLastModified);
  286.             }
  287.         }
  288.         
  289.         if($etag != null){
  290.             $headerEtag = <a href="../jelix/core/jApp.html">jApp</a>::coord()->request->header('If-None-Match');
  291.             if ($headerEtag !== null && $etag == $headerEtag) {
  292.                 $notModified = true;
  293.             }
  294.             else {
  295.                 $this->addHttpHeader('Etag', $etag);
  296.             }
  297.             
  298.         }
  299.  
  300.        if($notModified) {
  301.             $this->_outputOnlyHeaders = true;
  302.             $this->setHttpStatus(304, 'Not Modified');
  303.             
  304.             $toClean = array('Allow', 'Content-Encoding', 'Content-Language', 'Content-Length', 'Content-MD5', 'Content-Type', 'Last-Modified', 'Etag');
  305.             foreach($toClean as $h)
  306.                 unset($this->_httpHeaders[$h]);
  307.         }
  308.  
  309.         return $notModified;
  310.     }
  311.  
  312.     
  313.     

Documentation generated on Wed, 04 Jan 2017 22:56:04 +0100 by phpDocumentor 1.4.3