Source for file jResponseHtml.class.php

Documentation is available at jResponseHtml.class.php

  1. <?php
  2. /**
  3. @package     jelix
  4. @subpackage  core_response
  5. @author      Laurent Jouanneau
  6. @contributor Yann (description and keywords), Dominique Papin
  7. @contributor Warren Seine, Alexis Métaireau, Julien Issler, Brice Tence
  8. @copyright   2005-2009 Laurent Jouanneau, 2006 Yann, 2007 Dominique Papin
  9. @copyright   2008 Warren Seine, Alexis Métaireau
  10. @copyright   2009 Julien Issler, Olivier Demah
  11. @copyright   2010 Brice Tence
  12. *               few lines of code are copyrighted CopixTeam http://www.copix.org
  13. @link        http://www.jelix.org
  14. @licence     GNU Lesser General Public Licence see LICENCE file or http://www.gnu.org/licenses/lgpl.html
  15. */
  16.  
  17. /**
  18. *
  19. */
  20. require_once(JELIX_LIB_PATH.'tpl/jTpl.class.php');
  21.  
  22. /**
  23. * HTML response
  24. @package  jelix
  25. @subpackage core_response
  26. */
  27. class jResponseHtml extends jResponse {
  28.     /**
  29.     * jresponse id
  30.     * @var string 
  31.     */
  32.     protected $_type = 'html';
  33.  
  34.     /**
  35.      * Title of the document
  36.      * @var string 
  37.      */
  38.     public $title = '';
  39.  
  40.     /**
  41.      * favicon url linked to the document
  42.      * @var string 
  43.      * @since 1.0b2
  44.      */
  45.     public $favicon = '';
  46.  
  47.     /**
  48.      * The template engine used to generate the body content
  49.      * @var jTpl 
  50.      */
  51.     public $body = null;
  52.  
  53.     /**
  54.      * selector of the main template file
  55.      * This template should contains the body content, and is used by the $body template engine
  56.      * @var string 
  57.      */
  58.     public $bodyTpl = '';
  59.  
  60.     /**
  61.      * Selector of the template used when there are some errors, instead of $bodyTpl
  62.      * @var string 
  63.      */
  64.     public $bodyErrorTpl = '';
  65.  
  66.     /**
  67.      * body attributes
  68.      * This attributes are written on the body tags
  69.      * @var array 
  70.      */
  71.     public $bodyTagAttributesarray();
  72.  
  73.     /**
  74.      * says what part of the html head has been send
  75.      * @var integer 
  76.      */
  77.     protected $_headSent = 0;
  78.  
  79.     /**
  80.      * the charset of the document
  81.      * @var string 
  82.      */
  83.     protected $_charset;
  84.  
  85.     /**
  86.      * the lang of the document
  87.      * @var string 
  88.      */
  89.     protected $_lang;
  90.  
  91.     /**
  92.      * properties of the head content
  93.      */
  94.  
  95.     /**#@+
  96.      * content for the head
  97.      * @var array
  98.      */
  99.     protected $_CSSLink = array ();
  100.     protected $_CSSIELink = array ();
  101.     protected $_Styles  = array ();
  102.     protected $_JSLink  = array ();
  103.     protected $_JSIELink  = array ();
  104.     protected $_JSCode  = array ();
  105.     protected $_Others  = array ();
  106.     protected $_MetaKeywords = array();
  107.     protected $_MetaDescription = array();
  108.     protected $_Link = array();
  109.     /**#@-*/
  110.  
  111.     /**#@+
  112.      * content for the body
  113.      * @var array
  114.      */
  115.     protected $_bodyTop = array();
  116.     protected $_bodyBottom = array();
  117.     /**#@-*/
  118.  
  119.     /**
  120.      * says if the document is in xhtml or html
  121.      */
  122.     protected $_isXhtml = true;
  123.     protected $_endTag="/>\n";
  124.  
  125.     /**
  126.      * says if the document uses a Strict or Transitional Doctype
  127.      * @var boolean 
  128.      * @since 1.1.3
  129.      */
  130.     protected $_strictDoctype = true;
  131.  
  132.     /**
  133.      * says if xhtml content type should be send or not.
  134.      * it true, a verification of HTTP_ACCEPT is done.
  135.      * @var boolean 
  136.      */
  137.     public $xhtmlContentType = false;
  138.  
  139.  
  140.     /**
  141.     * constructor;
  142.     * setup the charset, the lang, the template engine
  143.     */
  144.     function __construct (){
  145.         global $gJConfig;
  146.         $this->_charset = $gJConfig->charset;
  147.         $this->_lang = $gJConfig->locale;
  148.         $this->body = new jTpl();
  149.         parent::__construct();
  150.     }
  151.  
  152.     /**
  153.      * output the html content
  154.      *
  155.      * @return boolean    true if the generated content is ok
  156.      */
  157.     final public function output(){
  158.         $this->_headSent = 0;
  159.         if($this->_isXhtml && $this->xhtmlContentType && strstr($_SERVER['HTTP_ACCEPT'],'application/xhtml+xml')){
  160.             $this->_httpHeaders['Content-Type']='application/xhtml+xml;charset='.$this->_charset;
  161.         }else{
  162.             $this->_httpHeaders['Content-Type']='text/html;charset='.$this->_charset;
  163.         }
  164.  
  165.         $this->sendHttpHeaders();
  166.         $this->outputDoctype();
  167.         $this->_headSent = 1;
  168.         $this->doAfterActions();
  169.         if($this->bodyTpl != '')
  170.             $this->body->meta($this->bodyTpl);
  171.         $this->outputHtmlHeader();
  172.         echo '<body ';
  173.         foreach($this->bodyTagAttributes as $attr=>$value){
  174.             echo $attr,'="'htmlspecialchars($value),'" ';
  175.         }
  176.         echo ">\n";
  177.         $this->_headSent = 2;
  178.         echo implode("\n",$this->_bodyTop);
  179.         if($this->bodyTpl != '')
  180.             $this->body->display($this->bodyTpl);
  181.  
  182.         if($this->hasErrors()){
  183.             if($GLOBALS['gJConfig']->error_handling['showInFirebug']){
  184.                 echo '<script type="text/javascript">if(console){';
  185.                 foreach$GLOBALS['gJCoord']->errorMessages  as $e){
  186.                     switch ($e[0]{
  187.                       case 'warning':
  188.                         echo 'console.warn("[warning ';
  189.                         break;
  190.                       case 'notice':
  191.                         echo 'console.info("[notice ';
  192.                         break;
  193.                       case 'strict':
  194.                         echo 'console.info("[strict ';
  195.                         break;
  196.                       case 'error':
  197.                         echo 'console.error("[error ';
  198.                         break;
  199.                     }
  200.                     echo $e[1],'] ',str_replace(array('"',"\n","\r","\t"),array('\"','\\n','\\r','\\t'),$e[2]),' (',str_replace('\\','\\\\',$e[3]),' ',$e[4],')");';
  201.                 }
  202.                 echo '}else{alert("there are some errors, you should activate Firebug to see them");}</script>';
  203.             }else{
  204.                 echo '<div id="jelixerror" style="position:absolute;left:0px;top:0px;border:3px solid red; background-color:#f39999;color:black;">';
  205.                 echo $this->getFormatedErrorMsg();
  206.                 echo '<p><a href="#" onclick="document.getElementById(\'jelixerror\').style.display=\'none\';return false;">fermer</a></p></div>';
  207.             }
  208.         }
  209.         echo implode("\n",$this->_bodyBottom);
  210.         $msgs $GLOBALS['gJCoord']->logMessages;
  211.         if(count($msgs)) {
  212.             if(isset($msgs['response']&& count($msgs['response'])) {
  213.                 echo '<ul id="jelixlog">';
  214.                 foreach($msgs['response'as $m{
  215.                     echo '<li>',htmlspecialchars($m),'</li>';
  216.                 }
  217.                 echo '</ul>';
  218.             }
  219.             if(isset($msgs['firebug']&& count($msgs['firebug'])) {
  220.                 echo '<script type="text/javascript">if(console){';
  221.                 foreach($msgs['firebug'as $m{
  222.                     echo 'console.debug("',str_replace(array('"',"\n","\r","\t"),array('\"','\\n','\\r','\\t'),$m),'");';
  223.                 }
  224.                 echo '}else{alert("there are log messages, you should activate Firebug to see them");}</script>';
  225.             }
  226.         }
  227.         echo '</body></html>';
  228.         return true;
  229.     }
  230.  
  231.     /**
  232.      * The method you can overload in your inherited html response
  233.      * overload it if you want to add processes (stylesheet, head settings, additionnal content etc..)
  234.      * after all actions
  235.      * @since 1.1
  236.      */
  237.     protected function doAfterActions(){
  238.         $this->_commonProcess()// for compatibility with jelix 1.0
  239.     }
  240.  
  241.     /**
  242.      * same use as doAfterActions, but deprecated method. It is just here for compatibility with Jelix 1.0.
  243.      * Use doAfterActions instead
  244.      * @deprecated
  245.      */
  246.     protected function _commonProcess(){
  247.     }
  248.  
  249.     /**
  250.      * output errors
  251.      */
  252.     final public function outputErrors(){
  253.         if($this->_headSent < 1){
  254.              if(!$this->_httpHeadersSent){
  255.                 header("HTTP/1.0 500 Internal Server Error");
  256.                 header('Content-Type: text/html;charset='.$this->_charset);
  257.              }
  258.             echo '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">'"\n<html>";
  259.         }
  260.         if($this->_headSent < 2){
  261.             echo '<head><title>Errors</title></head><body>';
  262.         }
  263.         if($this->hasErrors()){
  264.             echo $this->getFormatedErrorMsg();
  265.         }else{
  266.             echo '<p style="color:#FF0000">Unknown Error</p>';
  267.         }
  268.         echo '</body></html>';
  269.     }
  270.  
  271.  
  272.     /**
  273.      * create html error messages
  274.      * @return string html content
  275.      */
  276.     protected function getFormatedErrorMsg(){
  277.         $errors='';
  278.         foreach$GLOBALS['gJCoord']->errorMessages  as $e){
  279.            $errors .=  '<p style="margin:0;"><b>['.$e[0].' '.$e[1].']</b> <span style="color:#FF0000">'.htmlspecialchars($e[2]ENT_NOQUOTES$this->_charset)."</span> \t".$e[3]." \t".$e[4]."</p>\n";
  280.         }
  281.         return $errors;
  282.     }
  283.  
  284.     /**
  285.      * add content to the body
  286.      * you can add additionnal content, before or after the content generated by the main template
  287.      * @param string $content additionnal html content
  288.      * @param boolean $beforeTpl true if you want to add it before the template content, else false for after
  289.      */
  290.     function addContent($content$beforeTpl false){
  291.       if($beforeTpl){
  292.         $this->_bodyTop[]=$content;
  293.       }else{
  294.          $this->_bodyBottom[]=$content;
  295.       }
  296.     }
  297.     
  298.     /**
  299.      * add a generic link to the head
  300.      * 
  301.      * @param string $href  url of the link
  302.      * @param string $rel   relation name
  303.      * @param string $type  mime type of the ressource
  304.      * @param string $title 
  305.      */ 
  306.     final public function addLink($href$rel$type=''$title=''{
  307.         $this->_Link[$hrefarray($rel$type$title);
  308.     }
  309.  
  310.     /**
  311.      * add a link to a javascript script in the document head
  312.      *
  313.      * $forIe parameter exists since 1.0b2
  314.      *
  315.      * @param string $src the link
  316.      * @param array $params additionnals attributes for the script tag
  317.      * @param boolean $forIE if true, the script sheet will be only for IE browser
  318.      */
  319.     final public function addJSLink ($src$params=array()$forIE=false){
  320.         if($forIE){
  321.             if (!isset ($this->_JSIELink[$src])){
  322.                 $this->_JSIELink[$src$params;
  323.             }
  324.         }else{
  325.             if (!isset ($this->_JSLink[$src])){
  326.                 $this->_JSLink[$src$params;
  327.             }
  328.         }
  329.     }
  330.  
  331.     /**
  332.      * add a link to a css stylesheet in the document head
  333.      *
  334.      * $forIe parameter exists since 1.0b2
  335.      *
  336.      * @param string $src the link
  337.      * @param array $params additionnals attributes for the link tag
  338.      * @param mixed $forIE if true, the style sheet will be only for IE browser. string values possible (ex:'lt IE 7')
  339.      */
  340.     final public function addCSSLink ($src$params=array ()$forIE=false){
  341.         if($forIE){
  342.             if (!isset ($this->_CSSIELink[$src])){
  343.                 if (!is_bool($forIE&& !empty($forIE))
  344.                     $params['_ieCondition'$forIE;
  345.                 $this->_CSSIELink[$src$params;
  346.             }
  347.         }else{
  348.             if (!isset ($this->_CSSLink[$src])){
  349.                 $this->_CSSLink[$src$params;
  350.             }
  351.         }
  352.     }
  353.  
  354.     /**
  355.      * add inline css style into the document (inside a <style> tag)
  356.      * @param string $selector css selector
  357.      * @param string $def      css properties for the given selector
  358.      */
  359.     final public function addStyle ($selector$def=null){
  360.         if (!isset ($this->_Styles[$selector])){
  361.             $this->_Styles[$selector$def;
  362.         }
  363.     }
  364.  
  365.     /**
  366.      * add additional content into the document head
  367.      * @param string $content 
  368.      * @since 1.0b1
  369.      */
  370.     final public function addHeadContent ($content){
  371.         $this->_Others[$content;
  372.     }
  373.  
  374.     /**
  375.      * add inline javascript code (inside a <script> tag)
  376.      * @param string $code  javascript source code
  377.      */
  378.     final public function addJSCode ($code){
  379.         $this->_JSCode[$code;
  380.     }
  381.  
  382.     /**
  383.      * add some keywords in a keywords meta tag
  384.      * @author Yann
  385.      * @param string $content keywords
  386.      * @since 1.0b1
  387.      */
  388.     final public function addMetaKeywords ($content){
  389.         $this->_MetaKeywords[$content;
  390.     }
  391.     /**
  392.      * add a description in a description meta tag
  393.      * @author Yann
  394.      * @param string $content a description
  395.      * @since 1.0b1
  396.      */
  397.     final public function addMetaDescription ($content){
  398.         $this->_MetaDescription[$content;
  399.     }
  400.  
  401.     /**
  402.      * generate the doctype. You can override it if you want to have your own doctype, like XHTML+MATHML.
  403.      * @since 1.1
  404.      */
  405.     protected function outputDoctype (){
  406.         if($this->_isXhtml){
  407.             echo '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 '.($this->_strictDoctype?'Strict':'Transitional').'//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-'.($this->_strictDoctype?'strict':'transitional').'.dtd">
  408. <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="',$this->_lang,'" lang="',$this->_lang,'">
  409. ';
  410.         }else{
  411.             echo '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01'.($this->_strictDoctype?'':' Transitional').'//EN" "http://www.w3.org/TR/html4/'.($this->_strictDoctype?'strict':'loose').'.dtd">'"\n";
  412.             echo '<html lang="',$this->_lang,'">';
  413.         }
  414.     }
  415.  
  416.     /**
  417.      * generate the content of the <head> content
  418.      */
  419.     final protected function outputHtmlHeader (){
  420.         echo '<head>'."\n";
  421.         if($this->_isXhtml && $this->xhtmlContentType && strstr($_SERVER['HTTP_ACCEPT'],'application/xhtml+xml')){      
  422.             echo '<meta content="application/xhtml+xml; charset='.$this->_charset.'" http-equiv="content-type"'.$this->_endTag;
  423.         else {
  424.             echo '<meta content="text/html; charset='.$this->_charset.'" http-equiv="content-type"'.$this->_endTag;
  425.         }
  426.         echo '<title>'.htmlspecialchars($this->title)."</title>\n";
  427.  
  428.         if(!empty($this->_MetaDescription)){
  429.             // meta description
  430.             $description implode(' ',$this->_MetaDescription);
  431.             echo '<meta name="description" content="'.htmlspecialchars($description).'" '.$this->_endTag;
  432.         }
  433.  
  434.         if(!empty($this->_MetaKeywords)){
  435.             // meta description
  436.             $keywords implode(',',$this->_MetaKeywords);
  437.             echo '<meta name="keywords" content="'.htmlspecialchars($keywords).'" '.$this->_endTag;
  438.         }
  439.  
  440.         // css link
  441.         foreach ($this->_CSSLink as $src=>$params){
  442.             //the extra params we may found in there.
  443.             $more '';
  444.             foreach ($params as $param_name=>$param_value){
  445.                 $more .= $param_name.'="'htmlspecialchars($param_value).'" ';
  446.             }
  447.             if(!isset($params['rel']))
  448.                 $more .='rel="stylesheet" ';
  449.             echo  '<link type="text/css" href="',htmlspecialchars($src),'" ',$more,$this->_endTag;
  450.         }
  451.  
  452.         foreach ($this->_CSSIELink as $src=>$params){
  453.             // special params for conditions on IE versions
  454.             if (!isset($params['_ieCondition']))
  455.               $params['_ieCondition''IE' ;
  456.             echo '<!--[if '.$params['_ieCondition'].' ]>';
  457.             //the extra params we may found in there.
  458.             $more '';
  459.             foreach ($params as $param_name=>$param_value){
  460.                 if ($param_name=='_ieCondition')
  461.                   continue ;
  462.                 $more .= $param_name.'="'htmlspecialchars($param_value).'" ';
  463.             }
  464.             if(!isset($params['rel']))
  465.                 $more .='rel="stylesheet" ';
  466.             echo  '<link type="text/css" href="',htmlspecialchars($src),'" ',$more,$this->_endTag;
  467.             echo '<![endif]-->';
  468.         }
  469.  
  470.         if($this->favicon != ''){
  471.             $fav htmlspecialchars($this->favicon);
  472.             echo '<link rel="icon" type="image/x-icon" href="',$fav,'" ',$this->_endTag;
  473.             echo '<link rel="shortcut icon" type="image/x-icon" href="',$fav,'" ',$this->_endTag;
  474.         }
  475.         
  476.         // others links
  477.         foreach($this->_Link as $href=>$params){
  478.             $more array();
  479.             if!empty($params[1]))
  480.                 $more['type="'.$params[1].'"';
  481.             if (!empty($params[2]))
  482.                 $more['title = "'.htmlspecialchars($params[2]).'"';
  483.             echo '<link rel="',$params[0],'" href="',htmlspecialchars($href),'" ',implode($more' '),$this->_endTag;
  484.         }
  485.  
  486.         // js link
  487.         foreach ($this->_JSLink as $src=>$params){
  488.             //the extra params we may found in there.
  489.             $more '';
  490.             foreach ($params as $param_name=>$param_value){
  491.                 $more .= $param_name.'="'htmlspecialchars($param_value).'" ';
  492.             }
  493.             echo '<script type="text/javascript" src="',htmlspecialchars($src),'" ',$more,'></script>',"\n";
  494.         }
  495.         if(count($this->_JSIELink)){
  496.             echo '<!--[if IE]>';
  497.             foreach ($this->_JSIELink as $src=>$params){
  498.                 //the extra params we may found in there.
  499.                 $more '';
  500.                 foreach ($params as $param_name=>$param_value){
  501.                     $more .= $param_name.'="'htmlspecialchars($param_value).'" ';
  502.                 }
  503.                 echo '<script type="text/javascript" src="',htmlspecialchars($src),'" ',$more,'></script>',"\n";
  504.             }
  505.             echo '<![endif]-->';
  506.         }
  507.  
  508.         // styles
  509.         if(count($this->_Styles)){
  510.             echo '<style type="text/css">
  511.             ';
  512.             foreach ($this->_Styles as $selector=>$value){
  513.                 if (strlen ($value)){
  514.                     //il y a une paire clef valeur.
  515.                     echo $selector.' {'.$value."}\n";
  516.                 }else{
  517.                     //il n'y a pas de valeur, c'est peut être simplement une commande.
  518.                     //par exemple @import qqchose, ...
  519.                     echo $selector"\n";
  520.                 }
  521.             }
  522.             echo "\n </style>\n";
  523.         }
  524.         // js code
  525.         if(count($this->_JSCode)){
  526.             echo '<script type="text/javascript">
  527. // <![CDATA[
  528.  '.implode ("\n"$this->_JSCode).'
  529. // ]]>
  530. </script>';
  531.         }
  532.         echo implode ("\n"$this->_Others)'</head>';
  533.     }
  534.  
  535.     /**
  536.      * used to erase some head properties
  537.      * @param array $what list of one or many of this strings : 'CSSLink', 'CSSIELink', 'Styles', 'JSLink', 'JSIELink', 'JSCode', 'Others','MetaKeywords','MetaDescription'. If null, it cleans all values.
  538.      */
  539.     final public function clearHtmlHeader ($what=null){
  540.         $cleanable array ('CSSLink''CSSIELink''Styles''JSLink','JSIELink''JSCode''Others','MetaKeywords','MetaDescription');
  541.         if($what==null)
  542.             $what$cleanable;
  543.         foreach ($what as $elem){
  544.             if (in_array ($elem$cleanable)){
  545.                 $name '_'.$elem;
  546.                 $this->$name array ();
  547.             }
  548.         }
  549.     }
  550.  
  551.     /**
  552.      * change the type of html for the output
  553.      * @param boolean $xhtml true if you want xhtml, false if you want html
  554.      */
  555.     final public function setXhtmlOutput($xhtml true){
  556.         $this->_isXhtml = $xhtml;
  557.         if($xhtml)
  558.             $this->_endTag = "/>\n";
  559.         else
  560.             $this->_endTag = ">\n";
  561.     }
  562.  
  563.     /**
  564.      * activate / deactivate the strict Doctype (activated by default)
  565.      * @param boolean $val true for strict, false for transitional
  566.      * @since 1.1.3
  567.      */
  568.     final public function strictDoctype($val true){
  569.         $this->_strictDoctype = $val;
  570.     }
  571.  
  572.     /**
  573.      * says if the response will be xhtml or html
  574.      * @return boolean true if it is xhtml
  575.      */
  576.     final public function isXhtml()return $this->_isXhtml}
  577.  
  578.     /**
  579.      * return the end of a html tag : "/>" or ">", depending if it will generate xhtml or html
  580.      * @return string 
  581.      */
  582.     final public function endTag()return $this->_endTag;}
  583.  
  584. }

Documentation generated on Thu, 22 Mar 2012 22:16:41 +0100 by phpDocumentor 1.4.3