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, Dominique Papin
  7. @contributor Warren Seine, Alexis Métaireau, Julien Issler, Olivier Demah, 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. require_once(JELIX_LIB_PATH.'utils/jMinifier.class.php');
  22.  
  23. /**
  24. * HTML response
  25. @package  jelix
  26. @subpackage core_response
  27. */
  28. class jResponseHtml extends jResponse {
  29.     /**
  30.     * jresponse id
  31.     * @var string 
  32.     */
  33.     protected $_type = 'html';
  34.  
  35.     /**
  36.      * Title of the document
  37.      * @var string 
  38.      */
  39.     public $title = '';
  40.  
  41.     /**
  42.      * favicon url linked to the document
  43.      * @var string 
  44.      * @since 1.0b2
  45.      */
  46.     public $favicon = '';
  47.  
  48.     /**
  49.      * The template engine used to generate the body content
  50.      * @var jTpl 
  51.      */
  52.     public $body = null;
  53.  
  54.     /**
  55.      * selector of the main template file
  56.      * This template should contains the body content, and is used by the $body template engine
  57.      * @var string 
  58.      */
  59.     public $bodyTpl = '';
  60.  
  61.     /**
  62.      * Selector of the template used when there are some errors, instead of $bodyTpl
  63.      * @var string 
  64.      */
  65.     public $bodyErrorTpl = '';
  66.  
  67.     /**
  68.      * body attributes
  69.      * This attributes are written on the body tags
  70.      * @var array 
  71.      */
  72.     public $bodyTagAttributesarray();
  73.  
  74.     /**
  75.      * says what part of the html head has been send
  76.      * @var integer 
  77.      */
  78.     protected $_headSent = 0;
  79.  
  80.     /**
  81.      * the charset of the document
  82.      * @var string 
  83.      */
  84.     protected $_charset;
  85.  
  86.     /**
  87.      * the lang of the document
  88.      * @var string 
  89.      */
  90.     protected $_lang;
  91.  
  92.     /**
  93.      * properties of the head content
  94.      */
  95.  
  96.     /**#@+
  97.      * content for the head
  98.      * @var array
  99.      */
  100.     protected $_CSSLink = array ();
  101.     protected $_CSSIELink = array ();
  102.     protected $_Styles  = array ();
  103.     protected $_JSLink  = array ();
  104.     protected $_JSIELink  = array ();
  105.     protected $_JSCodeBefore  = array ();
  106.     protected $_JSCode  = array ();
  107.     protected $_Others  = array ();
  108.     protected $_MetaKeywords = array();
  109.     protected $_MetaDescription = array();
  110.     protected $_MetaAuthor = '';
  111.     protected $_MetaGenerator = '';
  112.     protected $_Link = array();
  113.     /**#@-*/
  114.  
  115.     /**#@+
  116.      * content for the body
  117.      * @var array
  118.      */
  119.     protected $_bodyTop = array();
  120.     protected $_bodyBottom = array();
  121.     /**#@-*/
  122.  
  123.     /**
  124.      * says if the document is in xhtml or html
  125.      */
  126.     protected $_isXhtml = true;
  127.     protected $_endTag="/>\n";
  128.  
  129.     /**
  130.      * says if the document uses a Strict or Transitional Doctype
  131.      * @var boolean 
  132.      * @since 1.1.3
  133.      */
  134.     protected $_strictDoctype = true;
  135.  
  136.     /**
  137.      * says if xhtml content type should be send or not.
  138.      * it true, a verification of HTTP_ACCEPT is done.
  139.      * @var boolean 
  140.      */
  141.     public $xhtmlContentType = false;
  142.  
  143.  
  144.     /**
  145.     * constructor;
  146.     * setup the charset, the lang, the template engine
  147.     */
  148.     function __construct (){
  149.         global $gJConfig;
  150.         $this->_charset = $gJConfig->charset;
  151.         $this->_lang = $gJConfig->locale;
  152.         $this->body = new jTpl();
  153.         parent::__construct();
  154.     }
  155.  
  156.     /**
  157.      * output the html content
  158.      *
  159.      * @return boolean    true if the generated content is ok
  160.      */
  161.     public function output(){
  162.         $this->doAfterActions();
  163.  
  164.         $this->_headSent = 0;
  165.         if($this->_isXhtml && $this->xhtmlContentType && strstr($_SERVER['HTTP_ACCEPT'],'application/xhtml+xml')){
  166.             $this->_httpHeaders['Content-Type']='application/xhtml+xml;charset='.$this->_charset;
  167.         }else{
  168.             $this->_httpHeaders['Content-Type']='text/html;charset='.$this->_charset;
  169.         }
  170.         $this->sendHttpHeaders();
  171.         $this->outputDoctype();
  172.         $this->_headSent = 1;
  173.         
  174.         if($this->bodyTpl != '')
  175.             $this->body->meta($this->bodyTpl);
  176.         $this->outputHtmlHeader();
  177.         echo '<body ';
  178.         foreach($this->bodyTagAttributes as $attr=>$value){
  179.             echo $attr,'="'htmlspecialchars($value),'" ';
  180.         }
  181.         echo ">\n";
  182.         $this->_headSent = 2;
  183.         echo implode("\n",$this->_bodyTop);
  184.         if($this->bodyTpl != '')
  185.             $this->body->display($this->bodyTpl);
  186.  
  187.         if($this->hasErrors()){
  188.             if($GLOBALS['gJConfig']->error_handling['showInFirebug']){
  189.                 echo '<script type="text/javascript">if(console){';
  190.                 foreach$GLOBALS['gJCoord']->errorMessages  as $e){
  191.                     switch ($e[0]{
  192.                       case 'warning':
  193.                         echo 'console.warn("[warning ';
  194.                         break;
  195.                       case 'notice':
  196.                         echo 'console.info("[notice ';
  197.                         break;
  198.                       case 'strict':
  199.                         echo 'console.info("[strict ';
  200.                         break;
  201.                       case 'error':
  202.                         echo 'console.error("[error ';
  203.                         break;
  204.                     }
  205.                     $m $e[2]($e[5]?"\n".$e[5]:"");
  206.                     echo $e[1],'] ',str_replace(array('"',"\n","\r","\t"),array('\"','\\n','\\r','\\t'),$m),' (',str_replace('\\','\\\\',$e[3]),' ',$e[4],')");';
  207.                 }
  208.                 echo '}else{alert("there are some errors, you should activate Firebug to see them");}</script>';
  209.             }else{
  210.                 echo '<div id="jelixerror" style="position:absolute;left:0px;top:0px;border:3px solid red; background-color:#f39999;color:black;z-index:100;">';
  211.                 echo $this->getFormatedErrorMsg();
  212.                 echo '<p><a href="#" onclick="document.getElementById(\'jelixerror\').style.display=\'none\';return false;">close</a></p></div>';
  213.             }
  214.         }
  215.  
  216.         echo implode("\n",$this->_bodyBottom);
  217.         $msgs $GLOBALS['gJCoord']->logMessages;
  218.         if(count($msgs)) {
  219.             if(isset($msgs['response']&& count($msgs['response'])) {
  220.                 echo '<ul id="jelixlog">';
  221.                 foreach($msgs['response'as $m{
  222.                     echo '<li>',htmlspecialchars($m),'</li>';
  223.                 }
  224.                 echo '</ul>';
  225.             }
  226.             if(isset($msgs['firebug']&& count($msgs['firebug'])) {
  227.                 echo '<script type="text/javascript">if(console){';
  228.                 foreach($msgs['firebug'as $m{
  229.                     echo 'console.debug("',str_replace(array('"',"\n","\r","\t"),array('\"','\\n','\\r','\\t'),$m),'");';
  230.                 }
  231.                 echo '}else{alert("there are log messages, you should activate Firebug to see them");}</script>';
  232.             }
  233.         }
  234.         echo '</body></html>';
  235.         return true;
  236.     }
  237.  
  238.     /**
  239.      * The method you can overload in your inherited html response
  240.      * overload it if you want to add processes (stylesheet, head settings, additionnal content etc..)
  241.      * after all actions
  242.      * @since 1.1
  243.      */
  244.     protected function doAfterActions(){
  245.  
  246.     }
  247.  
  248.     /**
  249.      * output errors
  250.      */
  251.     public function outputErrors(){
  252.         if($this->_headSent < 1){
  253.              if(!$this->_httpHeadersSent){
  254.                 header("HTTP/1.0 500 Internal Server Error");
  255.                 header('Content-Type: text/html;charset='.$this->_charset);
  256.              }
  257.             echo '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">'"\n<html>";
  258.         }
  259.         if($this->_headSent < 2){
  260.             echo '<head><title>Errors</title></head><body>';
  261.         }
  262.         if($this->hasErrors()){
  263.             echo $this->getFormatedErrorMsg();
  264.         }else{
  265.             echo '<p style="color:#FF0000">Unknown Error</p>';
  266.         }
  267.         echo '</body></html>';
  268.     }
  269.  
  270.  
  271.     /**
  272.      * create html error messages
  273.      * @return string html content
  274.      */
  275.     protected function getFormatedErrorMsg(){
  276.         $errors='';
  277.         foreach$GLOBALS['gJCoord']->errorMessages  as $e){
  278.            $errors .=  '<p style="margin:0;"><b>['.$e[0].' '.$e[1].']</b> <span style="color:#FF0000">';
  279.            $errors .= htmlspecialchars($e[2]ENT_NOQUOTES$this->_charset)."</span> \t".$e[3]." \t".$e[4]."</p>\n";
  280.            if ($e[5])
  281.             $errors.= '<pre>'.htmlspecialchars($e[5]ENT_NOQUOTES$this->_charset).'</pre>';
  282.         }
  283.         return $errors;
  284.     }
  285.  
  286.     /**
  287.      * add content to the body
  288.      * you can add additionnal content, before or after the content generated by the main template
  289.      * @param string $content additionnal html content
  290.      * @param boolean $beforeTpl true if you want to add it before the template content, else false for after
  291.      */
  292.     function addContent($content$beforeTpl false){
  293.       if($beforeTpl){
  294.         $this->_bodyTop[]=$content;
  295.       }else{
  296.          $this->_bodyBottom[]=$content;
  297.       }
  298.     }
  299.     
  300.     /**
  301.      * add a generic link to the head
  302.      * 
  303.      * @param string $href  url of the link
  304.      * @param string $rel   relation name
  305.      * @param string $type  mime type of the ressource
  306.      * @param string $title 
  307.      */ 
  308.     final public function addLink($href$rel$type=''$title=''{
  309.         $this->_Link[$hrefarray($rel$type$title);
  310.     }
  311.  
  312.     /**
  313.      * add a link to a javascript script in the document head
  314.      *
  315.      * $forIe parameter exists since 1.0b2
  316.      *
  317.      * @param string $src the link
  318.      * @param array $params additionnals attributes for the script tag
  319.      * @param boolean $forIE if true, the script sheet will be only for IE browser
  320.      */
  321.     final public function addJSLink ($src$params=array()$forIE=false){
  322.         if($forIE){
  323.             if (!isset ($this->_JSIELink[$src])){
  324.                 $this->_JSIELink[$src$params;
  325.             }
  326.         }else{
  327.             if (!isset ($this->_JSLink[$src])){
  328.                 $this->_JSLink[$src$params;
  329.             }
  330.         }
  331.     }
  332.  
  333.     /**
  334.      * add a link to a css stylesheet in the document head
  335.      *
  336.      * $forIe parameter exists since 1.0b2
  337.      *
  338.      * @param string $src the link
  339.      * @param array $params additionnals attributes for the link tag
  340.      * @param mixed $forIE if true, the style sheet will be only for IE browser. string values possible (ex:'lt IE 7')
  341.      */
  342.     final public function addCSSLink ($src$params=array ()$forIE=false){
  343.         if($forIE){
  344.             if (!isset ($this->_CSSIELink[$src])){
  345.                 if (!is_bool($forIE&& !empty($forIE))
  346.                     $params['_ieCondition'$forIE;
  347.                 $this->_CSSIELink[$src$params;
  348.             }
  349.         }else{
  350.             if (!isset ($this->_CSSLink[$src])){
  351.                 $this->_CSSLink[$src$params;
  352.             }
  353.         }
  354.     }
  355.  
  356.     /**
  357.      * add inline css style into the document (inside a <style> tag)
  358.      * @param string $selector css selector
  359.      * @param string $def      css properties for the given selector
  360.      */
  361.     final public function addStyle ($selector$def=null){
  362.         if (!isset ($this->_Styles[$selector])){
  363.             $this->_Styles[$selector$def;
  364.         }
  365.     }
  366.  
  367.     /**
  368.      * add additional content into the document head
  369.      * @param string $content 
  370.      * @since 1.0b1
  371.      */
  372.     final public function addHeadContent ($content){
  373.         $this->_Others[$content;
  374.     }
  375.  
  376.     /**
  377.      * add inline javascript code (inside a <script> tag)
  378.      * @param string $code  javascript source code
  379.      * @param boolean $before will insert the code before js links if true
  380.      */
  381.     final public function addJSCode ($code$before false){
  382.         if ($before)
  383.             $this->_JSCodeBefore[$code;
  384.         else
  385.             $this->_JSCode[$code;
  386.     }
  387.  
  388.     /**
  389.      * add some keywords in a keywords meta tag
  390.      * @author Yann
  391.      * @param string $content keywords
  392.      * @since 1.0b1
  393.      */
  394.     final public function addMetaKeywords ($content){
  395.         $this->_MetaKeywords[$content;
  396.     }
  397.     /**
  398.      * add a description in a description meta tag
  399.      * @author Yann
  400.      * @param string $content a description
  401.      * @since 1.0b1
  402.      */
  403.     final public function addMetaDescription ($content){
  404.         $this->_MetaDescription[$content;
  405.     }
  406.     /**
  407.      * add author(s) in a author meta tag
  408.      * @author Olivier Demah
  409.      * @param string $content author(s)
  410.      * @since 1.2
  411.      */
  412.     final public function addMetaAuthor($content){
  413.         $this->_MetaAuthor = $content;
  414.     }
  415.     /**
  416.      * add generator a generator meta tag
  417.      * @author Olivier Demah
  418.      * @param string $content generator
  419.      * @since 1.2
  420.      */
  421.     final public function addMetaGenerator($content){
  422.         $this->_MetaGenerator = $content;
  423.     }
  424.     /**
  425.      * generate the doctype. You can override it if you want to have your own doctype, like XHTML+MATHML.
  426.      * @since 1.1
  427.      */
  428.     protected function outputDoctype (){
  429.         if($this->_isXhtml){
  430.             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">
  431. <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="',$this->_lang,'" lang="',$this->_lang,'">
  432. ';
  433.         }else{
  434.             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";
  435.             echo '<html lang="',$this->_lang,'">';
  436.         }
  437.     }
  438.  
  439.     protected function outputJsScriptTag$fileUrl$scriptParams$filePath null {
  440.         global $gJConfig;
  441.  
  442.         $params '';
  443.         ifis_array($scriptParams) ) {
  444.             foreach ($scriptParams as $param_name=>$param_value){
  445.                 $params .= $param_name.'="'htmlspecialchars($param_value).'" ';
  446.             }
  447.         else {
  448.             $params $scriptParams;
  449.         }
  450.  
  451.         $jsFilemtime '';
  452.         ifisset($gJConfig->jResponseHtml&& $gJConfig->jResponseHtml['jsUniqueUrlId']
  453.             && $filePath !== null
  454.             && (strpos($fileUrl,'http://')===FALSE//path is not absolute
  455.           {
  456.             $jsFilemtime "?".filemtime($filePath);
  457.         }
  458.         echo '<script type="text/javascript" src="',htmlspecialchars($fileUrl),$jsFilemtime,'" ',$params,'></script>',"\n";
  459.     }
  460.  
  461.     protected function outputCssLinkTag$fileUrl$cssParams$filePath null {
  462.         global $gJConfig;
  463.  
  464.         $params '';
  465.         ifis_array($cssParams) ) {
  466.             foreach ($cssParams as $param_name=>$param_value){
  467.                 $params .= $param_name.'="'htmlspecialchars($param_value).'" ';
  468.             }
  469.         else {
  470.             $params $cssParams;
  471.         }
  472.  
  473.         $cssFilemtime '';
  474.         ifisset($gJConfig->jResponseHtml&& $gJConfig->jResponseHtml['cssUniqueUrlId']
  475.             && $filePath !== null
  476.             && (strpos($fileUrl,'http://')===FALSE//path is not absolute
  477.           {
  478.             $cssFilemtime "?".filemtime($filePath);
  479.         }
  480.         echo '<link type="text/css" href="',htmlspecialchars($fileUrl),$cssFilemtime,'" ',$params,$this->_endTag,"\n";
  481.     }
  482.  
  483.     protected function outputJsScripts&$scriptList {
  484.         global $gJConfig;
  485.  
  486.         $minifyJsByParams array();
  487.         $minifyExcludeJS array();
  488.  
  489.         ifisset($gJConfig->jResponseHtml&& $gJConfig->jResponseHtml['minifyExcludeJS'{
  490.             $minifyExcludeJS explode','$gJConfig->jResponseHtml['minifyExcludeJS');
  491.         }
  492.  
  493.         $basePath $gJConfig->urlengine['basePath'];
  494.  
  495.         foreach ($scriptList as $src=>$params){
  496.             //the extra params we may found in there.
  497.             $scriptParams '';
  498.  
  499.             $pathSrc $src;
  500.             if $basePath != '/' && $basePath != '' {
  501.                     $res explode($basePath$src);
  502.                     if count($res)
  503.                         list(,$pathSrc$res;
  504.                 }
  505.  
  506.             $pathIsAbsolute (strpos($pathSrc,'http://')!==FALSE);
  507.  
  508.             ifisset($gJConfig->jResponseHtml&& $gJConfig->jResponseHtml['minifyJS'&&
  509.                 $pathIsAbsolute && in_array(basename($pathSrc)$minifyExcludeJS) ) {
  510.                 //this file should be minified
  511.                 $sparams=$params;
  512.                 ksort($sparams)//sort to avoid duplicity just because of params order
  513.                 foreach ($sparams as $param_name=>$param_value){
  514.                     $scriptParams .= $param_name.'="'htmlspecialchars($param_value).'" ';
  515.                 }
  516.                 $minifyJsByParams[$scriptParams]["$src";
  517.             else {
  518.                 // current script should not be minified
  519.                 // thus to preserve scripts order we should apply previous pending minifications and generate its script tag
  520.                 // ex: a.js, b.js, c.js, d.js where c should not be minified. script tag generated must be min_a_+_b.js, c.js, min_d.js
  521.                 foreach ($minifyJsByParams as $param_value=>$js_files{
  522.                     foreach (jMinifier::minify$js_files'js' as $minifiedJs {
  523.                         $this->outputJsScriptTag$basePath.$minifiedJs$param_valueJELIX_APP_WWW_PATH.$minifiedJs);
  524.                     }
  525.                 }
  526.                 // minified operation finished on pending scripts. thus clear js array of scripts to minify :
  527.                 $minifyJsByParams array();
  528.  
  529.                 $this->outputJsScriptTag$src$paramsJELIX_APP_WWW_PATH.$pathSrc );
  530.             }
  531.         }
  532.         //minify all pending JS script files (may be all files if none was excluded or had absolute URL)
  533.         foreach ($minifyJsByParams as $param_value=>$js_files{
  534.             foreach (jMinifier::minify$js_files'js' as $minifiedJs {
  535.                 $this->outputJsScriptTag($basePath.$minifiedJs$param_valueJELIX_APP_WWW_PATH.$minifiedJs);
  536.             }
  537.         }
  538.     }
  539.  
  540.     protected function outputCssLinks&$linkList {
  541.         global $gJConfig;
  542.  
  543.         $minifyCssByParams array();
  544.         $minifyExcludeCSS array();
  545.  
  546.         ifisset($gJConfig->jResponseHtml&& $gJConfig->jResponseHtml['minifyExcludeCSS'{
  547.             $minifyExcludeCSS explode','$gJConfig->jResponseHtml['minifyExcludeCSS');
  548.         }
  549.  
  550.         $basePath $gJConfig->urlengine['basePath'];
  551.  
  552.         foreach ($linkList as $src=>$params){
  553.             //the extra params we may found in there.
  554.             $cssParams '';
  555.             
  556.             $pathSrc $src;
  557.             if $basePath != '/' && $basePath != '' {
  558.                 $res explode($basePath$src);
  559.                 if count($res)
  560.                     list(,$pathSrc$res;
  561.             }
  562.  
  563.             $pathIsAbsolute (strpos($pathSrc,'http://')!==FALSE);
  564.  
  565.             ifisset($gJConfig->jResponseHtml&& $gJConfig->jResponseHtml['minifyCSS'&&
  566.                 $pathIsAbsolute && in_array(basename($pathSrc)$minifyExcludeCSS) ) {
  567.                 //this file should be minified
  568.                 $sparams=$params;
  569.                 ksort($sparams)//sort to avoid duplicity just because of params order
  570.                 foreach ($sparams as $param_name=>$param_value){
  571.                     if$param_name != "media" {
  572.                         $cssParams .= $param_name.'="'htmlspecialchars($param_value).'" ';
  573.                     }
  574.                 }
  575.                 if(!isset($params['rel']))
  576.                     $cssParams .='rel="stylesheet" ';
  577.                 ifisset($params['media') ) {
  578.                     //split for each media if specified
  579.                     foreach explode(','$params['media']as $medium{
  580.                         $myCssParams $cssParams 'media="' $medium '" ';
  581.                         $minifyCssByParams[$myCssParams]["$src";
  582.                     }
  583.                 else {
  584.                     $minifyCssByParams[$cssParams]["$src";
  585.                 }
  586.             else {
  587.                 // current stylesheet should not be minified
  588.                 // thus to preserve stylesheets order we should apply previous pending minifications and generate its link tag
  589.                 // ex: a.css, b.css, c.css, d.css where c should not be minified. script tag genrated must be min_a_+_b.css, c.js, min_d.js
  590.                 foreach ($minifyCssByParams as $param_value=>$css_files{
  591.                     foreach (jMinifier::minify$css_files'css' as $minifiedCss {
  592.                         $this->outputCssLinkTag$basePath.$minifiedCss$param_valueJELIX_APP_WWW_PATH.$minifiedCss);
  593.                     }
  594.                 }
  595.                 $minifyCssByParams array();
  596.                 
  597.                 if(!isset($params['rel']))
  598.                     $params['rel'='stylesheet';
  599.                 
  600.                 $this->outputCssLinkTag$src$paramsJELIX_APP_WWW_PATH.$pathSrc);
  601.             }
  602.         }
  603.         //minify all pending CSS files (may be all files if none was excluded or had absolute URL)
  604.         foreach ($minifyCssByParams as $param_value=>$css_files{
  605.             foreach (jMinifier::minify$css_files'css' as $minifiedCss {
  606.                 $this->outputCssLinkTag$basePath.$minifiedCss$param_valueJELIX_APP_WWW_PATH.$minifiedCss);
  607.             }
  608.         }
  609.     }
  610.  
  611.     /**
  612.      * generate the content of the <head> content
  613.      */
  614.     protected function outputHtmlHeader (){
  615.         global $gJConfig;
  616.  
  617.         echo '<head>'."\n";
  618.         if($this->_isXhtml && $this->xhtmlContentType && strstr($_SERVER['HTTP_ACCEPT'],'application/xhtml+xml')){      
  619.             echo '<meta content="application/xhtml+xml; charset='.$this->_charset.'" http-equiv="content-type"'.$this->_endTag;
  620.         else {
  621.             echo '<meta content="text/html; charset='.$this->_charset.'" http-equiv="content-type"'.$this->_endTag;
  622.         }
  623.         echo '<title>'.htmlspecialchars($this->title)."</title>\n";
  624.  
  625.         if(!empty($this->_MetaDescription)){
  626.             // meta description
  627.             $description implode(' ',$this->_MetaDescription);
  628.             echo '<meta name="description" content="'.htmlspecialchars($description).'" '.$this->_endTag;
  629.         }
  630.  
  631.         if(!empty($this->_MetaKeywords)){
  632.             // meta description
  633.             $keywords implode(',',$this->_MetaKeywords);
  634.             echo '<meta name="keywords" content="'.htmlspecialchars($keywords).'" '.$this->_endTag;
  635.         }
  636.         if (!empty($this->_MetaGenerator)) {
  637.             echo '<meta name="generator" content="'.htmlspecialchars($this->_MetaGenerator).'" '.$this->_endTag;
  638.         }
  639.         if (!empty($this->_MetaAuthor)) {
  640.             echo '<meta name="author" content="'.htmlspecialchars($this->_MetaAuthor).'" '.$this->_endTag;
  641.         }
  642.  
  643.         $this->outputCssLinks$this->_CSSLink );
  644.  
  645.         foreach ($this->_CSSIELink as $src=>$params){
  646.             // special params for conditions on IE versions
  647.             if (!isset($params['_ieCondition']))
  648.                 $params['_ieCondition''IE' ;
  649.             echo '<!--[if '.$params['_ieCondition'].' ]>';
  650.  
  651.             unset($params['_ieCondition']);
  652.             $cssIeLink array($src=>$params)//make a var to pass it by ref
  653.             $this->outputCssLinks$cssIeLink );
  654.  
  655.             echo '<![endif]-->';
  656.         }
  657.  
  658.         if($this->favicon != ''){
  659.             $fav htmlspecialchars($this->favicon);
  660.             echo '<link rel="icon" type="image/x-icon" href="',$fav,'" ',$this->_endTag;
  661.             echo '<link rel="shortcut icon" type="image/x-icon" href="',$fav,'" ',$this->_endTag;
  662.         }
  663.         
  664.         // others links
  665.         foreach($this->_Link as $href=>$params){
  666.             $more array();
  667.             if!empty($params[1]))
  668.                 $more['type="'.$params[1].'"';
  669.             if (!empty($params[2]))
  670.                 $more['title = "'.htmlspecialchars($params[2]).'"';
  671.             echo '<link rel="',$params[0],'" href="',htmlspecialchars($href),'" ',implode($more' '),$this->_endTag;
  672.         }
  673.  
  674.         // js code
  675.         if(count($this->_JSCodeBefore)){
  676.             echo '<script type="text/javascript">
  677. // <![CDATA[
  678.  '.implode ("\n"$this->_JSCodeBefore).'
  679. // ]]>
  680. </script>';
  681.         }
  682.  
  683.         $this->outputJsScripts$this->_JSLink );
  684.  
  685.         if(count($this->_JSIELink)){
  686.             echo '<!--[if IE]>';
  687.  
  688.             $this->outputJsScripts$this->_JSIELink );
  689.  
  690.             echo '<![endif]-->';
  691.         }
  692.  
  693.         // styles
  694.         if(count($this->_Styles)){
  695.             echo '<style type="text/css">
  696.             ';
  697.             foreach ($this->_Styles as $selector=>$value){
  698.                 if (strlen ($value)){
  699.                     //il y a une paire clef valeur.
  700.                     echo $selector.' {'.$value."}\n";
  701.                 }else{
  702.                     //il n'y a pas de valeur, c'est peut être simplement une commande.
  703.                     //par exemple @import qqchose, ...
  704.                     echo $selector"\n";
  705.                 }
  706.             }
  707.             echo "\n </style>\n";
  708.         }
  709.         // js code
  710.         if(count($this->_JSCode)){
  711.             echo '<script type="text/javascript">
  712. // <![CDATA[
  713.  '.implode ("\n"$this->_JSCode).'
  714. // ]]>
  715. </script>';
  716.         }
  717.         echo implode ("\n"$this->_Others)'</head>';
  718.     }
  719.  
  720.     /**
  721.      * used to erase some head properties
  722.      * @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.
  723.      */
  724.     public function clearHtmlHeader ($what=null){
  725.         $cleanable array ('CSSLink''CSSIELink''Styles''JSLink','JSIELink''JSCode''Others','MetaKeywords','MetaDescription');
  726.         if($what==null)
  727.             $what$cleanable;
  728.         foreach ($what as $elem){
  729.             if (in_array ($elem$cleanable)){
  730.                 $name '_'.$elem;
  731.                 $this->$name array ();
  732.             }
  733.         }
  734.     }
  735.  
  736.     /**
  737.      * change the type of html for the output
  738.      * @param boolean $xhtml true if you want xhtml, false if you want html
  739.      */
  740.     public function setXhtmlOutput($xhtml true){
  741.         $this->_isXhtml = $xhtml;
  742.         if($xhtml)
  743.             $this->_endTag = "/>\n";
  744.         else
  745.             $this->_endTag = ">\n";
  746.     }
  747.  
  748.     /**
  749.      * activate / deactivate the strict Doctype (activated by default)
  750.      * @param boolean $val true for strict, false for transitional
  751.      * @since 1.1.3
  752.      */
  753.     final public function strictDoctype($val true){
  754.         $this->_strictDoctype = $val;
  755.     }
  756.  
  757.     /**
  758.      * says if the response will be xhtml or html
  759.      * @return boolean true if it is xhtml
  760.      */
  761.     final public function isXhtml()return $this->_isXhtml}
  762.  
  763.     /**
  764.      * return the end of a html tag : "/>" or ">", depending if it will generate xhtml or html
  765.      * @return string 
  766.      */
  767.     final public function endTag()return $this->_endTag;}
  768.  
  769. }

Documentation generated on Thu, 19 Sep 2013 00:06:41 +0200 by phpDocumentor 1.4.3