HTML_Page2
[ class tree: HTML_Page2 ] [ index: HTML_Page2 ] [ all elements ]

Source for file Page2.php

Documentation is available at Page2.php

  1. <?php
  2. /* vim: set expandtab tabstop=4 shiftwidth=4: */
  3. // +----------------------------------------------------------------------+
  4. // | HTML_Page2                                                           |
  5. // +----------------------------------------------------------------------+
  6. // | Copyright (c) 1997 - 2004 The PHP Group                              |
  7. // +----------------------------------------------------------------------+
  8. // | This source file is subject to version 3.0 of the PHP license,       |
  9. // | that is bundled with this package in the file LICENSE, and is        |
  10. // | available at through the world-wide-web at                           |
  11. // | http://www.php.net/license/3_0.txt.                                  |
  12. // | If you did not receive a copy of the PHP license and are unable to   |
  13. // | obtain it through the world-wide-web, please send a note to          |
  14. // | license@php.net so we can mail you a copy immediately.               |
  15. // +----------------------------------------------------------------------+
  16. // | Authors: Adam Daniel <adaniel1@eesus.jnj.com>                        |
  17. // |          Klaus Guenther <klaus@capitalfocus.org>                     |
  18. // +----------------------------------------------------------------------+
  19. //
  20. // $Id: Page2.php,v 1.11 2009/01/26 14:15:44 clockwerx Exp $
  21.  
  22. /**
  23.  * The PEAR::HTML_Page2 package provides a simple interface for generating an XHTML compliant page
  24.  * 
  25.  * Features:
  26.  * - supports virtually all HTML doctypes, from HTML 2.0 through XHTML 1.1 and
  27.  *   XHTML Basic 1.0 plus preliminary support for XHTML 2.0
  28.  * - namespace support
  29.  * - global language declaration for the document
  30.  * - line ending styles
  31.  * - full META tag support
  32.  * - support for stylesheet declaration in the head section
  33.  * - support for script declaration in the head section
  34.  * - support for linked stylesheets and scripts
  35.  * - full support for header <link> tags
  36.  * - body can be a string, object with toHtml or toString methods or an array
  37.  *   (can be combined)
  38.  * 
  39.  * Ideas for use:
  40.  * - Use to validate the output of a class for XHTML compliance
  41.  * - Quick prototyping using PEAR packages is now a breeze
  42.  * @category HTML
  43.  * @package  HTML_Page2
  44.  * @version  @package_version@
  45.  * @version  $Id: Page2.php,v 1.11 2009/01/26 14:15:44 clockwerx Exp $
  46.  * @license  http://www.php.net/license/3_0.txt PHP License 3.0
  47.  * @author   Adam Daniel <adaniel1@eesus.jnj.com>
  48.  * @author   Klaus Guenther <klaus@capitalfocus.org>
  49.  * @since   PHP 4.0.3pl1
  50.  */
  51.  
  52. /**
  53.  * Include PEAR core
  54.  */
  55. require_once 'PEAR.php';
  56.  
  57. /**
  58.  * Include HTML_Common class
  59.  * 
  60.  * <p>Additional required files:</p>
  61.  * 
  62.  * <p>HTML/Page2/Doctypes.php is required in private method
  63.  * _getDoctype()</p>
  64.  * 
  65.  * <p>HTML/Page2/Namespaces.php is required in private method
  66.  * _getNamespace()</p>
  67.  * 
  68.  * <p>HTML/Page2/Frameset.php is optionally required in method setDoctype() if
  69.  * the doctype variant is frameset.</p>
  70.  */
  71. require_once 'HTML/Common.php';
  72.  
  73. /**#@+
  74.  * Determines how content is added to the body.
  75.  * 
  76.  * Use with the @see addBodyContent method.
  77.  *
  78.  * @since      2.0.0
  79.  */
  80. define('HTML_PAGE2_APPEND',  0);
  81. define('HTML_PAGE2_PREPEND'1);
  82. define('HTML_PAGE2_REPLACE'2);
  83. /**#@-*/
  84.  
  85. /**
  86.  * (X)HTML Page generation class
  87.  * 
  88.  * <p>This class handles the details for creating a properly constructed XHTML page.
  89.  * Page caching, stylesheets, client side script, and Meta tags can be
  90.  * managed using this class.</p>
  91.  * 
  92.  * <p>The body may be a string, object, or array of objects or strings. Objects with
  93.  * toHtml() and toString() methods are supported.</p>
  94.  * 
  95.  * <p><b>XHTML Examples:</b></p>
  96.  * 
  97.  * <p>Simplest example:</p>
  98.  * <code>
  99.  * // the default doctype is XHTML 1.0 Transitional
  100.  * // All doctypes and defaults are set in HTML/Page/Doctypes.php
  101.  * $p = new HTML_Page2();
  102.  *
  103.  * //add some content
  104.  * $p->addBodyContent("<p>some text</p>");
  105.  * 
  106.  * // print to browser
  107.  * $p->display();
  108.  * ?>
  109.  * </code>
  110.  * 
  111.  * <p>Complex XHTML example:</p>
  112.  * <code>
  113.  * <?php
  114.  * // The array takes an array of attributes that determine many important
  115.  * // aspects of the page generations.
  116.  * 
  117.  * // Possible attributes are: charset, mime, lineend, tab, doctype, namespace,
  118.  * // language and cache
  119.  * 
  120.  * $p = new HTML_Page2(array (
  121.  *
  122.  *                          // Sets the charset encoding (default: utf-8)
  123.  *                          'charset'  => 'utf-8',
  124.  *
  125.  *                          // Sets the line end character (default: unix (\n))
  126.  *                          'lineend'  => 'unix',
  127.  *
  128.  *                          // Sets the tab string for autoindent (default: tab (\t))
  129.  *                          'tab'  => '  ',
  130.  *
  131.  *                          // This is where you define the doctype
  132.  *                          'doctype'  => "XHTML 1.0 Strict",
  133.  *
  134.  *                          // Global page language setting
  135.  *                          'language' => 'en',
  136.  *
  137.  *                          // If cache is set to true, the browser may cache the output.
  138.  *                          'cache'    => 'false'
  139.  *                          ));
  140.  *
  141.  * // Here we go
  142.  *
  143.  * // Set the page title
  144.  * $p->setTitle("My page");
  145.  * 
  146.  * // Add optional meta data
  147.  * $p->setMetaData("author", "My Name");
  148.  * 
  149.  * // Put something into the body
  150.  * $p->addBodyContent("<p>some text</p>");
  151.  *
  152.  * // If at some point you want to clear the page content
  153.  * // and output an error message, you can easily do that
  154.  * // See the source for {@link toHtml} and {@link _getDoctype}
  155.  * // for more details
  156.  * if ($error) {
  157.  *     $p->setTitle("Error!");
  158.  *     $p->setBody("<p>Houston, we have a problem: $error</p>");
  159.  *     $p->display();
  160.  *     die;
  161.  * } // end error handling
  162.  *
  163.  * // print to browser
  164.  * $p->display();
  165.  * // output to file
  166.  * $p->toFile('example.html');
  167.  * ?>
  168.  * </code>
  169.  * 
  170.  * Simple XHTML declaration example:
  171.  * <code>
  172.  * <?php
  173.  * $p = new HTML_Page2();
  174.  * // An XHTML compliant page (with title) is automatically generated
  175.  *
  176.  * // This overrides the XHTML 1.0 Transitional default
  177.  * $p->setDoctype('XHTML 1.0 Strict');
  178.  * 
  179.  * // Put some content in here
  180.  * $p->addBodyContent("<p>some text</p>");
  181.  *
  182.  * // print to browser
  183.  * $p->display();
  184.  * ?>
  185.  * </code>
  186.  * 
  187.  * <p><b>HTML examples:</b></p>
  188.  * 
  189.  * <p>HTML 4.01 example:</p>
  190.  * <code>
  191.  * <?php
  192.  * $p = new HTML_Page2('doctype="HTML 4.01 Strict"');
  193.  * $p->addBodyContent = "<p>some text</p>";
  194.  * $p->display();
  195.  * ?>
  196.  * </code>
  197.  * 
  198.  * <p>nuke doctype declaration:</p>
  199.  *
  200.  * <code>
  201.  * <?php
  202.  * $p = new HTML_Page2('doctype="none"');
  203.  * $p->addBodyContent = "<p>some text</p>";
  204.  * $p->display();
  205.  * ?>
  206.  * </code>
  207.  * 
  208.  * 
  209.  * @version 2.0.0
  210.  * @package HTML_Page2
  211.  * @author   Adam Daniel <adaniel1@eesus.jnj.com>
  212.  * @author   Klaus Guenther <klaus@capitalfocus.org>
  213.  */
  214. class HTML_Page2 extends HTML_Common {
  215.     
  216.     /**
  217.      * Contains the content of the <body> tag.
  218.      * 
  219.      * @var     array 
  220.      * @access  private
  221.      * @since   2.0
  222.      */
  223.     var $_body = array();
  224.     
  225.     /**
  226.      * Controls caching of the page
  227.      * 
  228.      * @var     bool 
  229.      * @access  private
  230.      * @since   2.0
  231.      */
  232.     var $_cache = false;
  233.     
  234.     /**
  235.      * Contains the character encoding string
  236.      * 
  237.      * @var     string 
  238.      * @access  private
  239.      * @since   2.0
  240.      */
  241.     var $_charset 'utf-8';
  242.     
  243.     /**
  244.      * Contains the !DOCTYPE definition
  245.      * 
  246.      * @var array 
  247.      * @access private
  248.      * @since   2.0
  249.      */
  250.     var $_doctype = array('type'=>'xhtml','version'=>'1.0','variant'=>'transitional');
  251.     
  252.     /**
  253.      * Contains the page language setting
  254.      * 
  255.      * @var     string 
  256.      * @access  private
  257.      * @since   2.0
  258.      */
  259.     var $_language 'en';
  260.     
  261.     /**
  262.      * Array of Header <link> tags
  263.      * 
  264.      * @var     array 
  265.      * @access  private
  266.      * @since   2.0
  267.      */
  268.     var $_links = array();
  269.     
  270.     /**
  271.      * Array of meta tags
  272.      * 
  273.      * @var     array 
  274.      * @access  private
  275.      * @since   2.0
  276.      */
  277.     var $_metaTags = array'standard' => array 'Generator' => 'PEAR HTML_Page' ) );
  278.     
  279.     /**
  280.      * Document mime type
  281.      * 
  282.      * @var      string 
  283.      * @access   private
  284.      * @since   2.0
  285.      */
  286.     var $_mime 'text/html';
  287.     
  288.     /**
  289.      * Document namespace
  290.      * 
  291.      * @var      string 
  292.      * @access   private
  293.      * @since   2.0
  294.      */
  295.     var $_namespace '';
  296.     
  297.     /**
  298.      * Document profile
  299.      * 
  300.      * @var      string 
  301.      * @access   private
  302.      * @since   2.0
  303.      */
  304.     var $_profile '';
  305.     
  306.     /**
  307.      * Array of linked scripts
  308.      * 
  309.      * @var      array 
  310.      * @access   private
  311.      * @since   2.0
  312.      */
  313.     var $_scripts = array();
  314.     
  315.     /**
  316.      * Array of scripts placed in the header
  317.      * 
  318.      * @var  array 
  319.      * @access   private
  320.      * @since   2.0
  321.      */
  322.     var $_script = array();
  323.     
  324.     /**
  325.      * Suppresses doctype
  326.      * 
  327.      * @var     bool 
  328.      * @access  private
  329.      * @since   2.0
  330.      */
  331.     var $_simple = false;
  332.     
  333.     /**
  334.      * Array of included style declarations
  335.      * 
  336.      * @var     array 
  337.      * @access  private
  338.      * @since   2.0
  339.      */
  340.     var $_style = array();
  341.     
  342.     /**
  343.      * Array of linked style sheets
  344.      * 
  345.      * @var     array 
  346.      * @access  private
  347.      * @since   2.0
  348.      */
  349.     var $_styleSheets = array();
  350.     
  351.     /**
  352.      * HTML page title
  353.      * 
  354.      * @var     string 
  355.      * @access  private
  356.      * @since   2.0
  357.      */
  358.     var $_title '';
  359.     
  360.     /**
  361.      * Defines whether XML prolog should be prepended to XHTML documents
  362.      * 
  363.      * @var     bool 
  364.      * @access  private
  365.      * @since   2.0
  366.      */
  367.     var $_xmlProlog = true;
  368.     
  369.     /**
  370.      * Contains an instance of {@see HTML_Page2_Frameset}
  371.      * 
  372.      * @var     object 
  373.      * @access  public
  374.      * @since   2.0
  375.      */
  376.     var $frameset;
  377.     
  378.     /**
  379.      * Class constructor.
  380.      *
  381.      * <p>Accepts an array of attributes</p>
  382.      * 
  383.      * <p><b>General options:</b></p>
  384.      *     - "lineend" => "unix|win|mac" (Sets line ending style; defaults to
  385.      *        unix.) See also {@link setLineEnd}.
  386.      *     - "tab"     => string (Sets line ending style; defaults to \t.) See
  387.      *        also {@link setTab}.
  388.      *     - "cache"   => "false|true"  See also {@link setCache}.
  389.      *     - "charset" => charset string (Sets charset encoding; defaults
  390.      *       to utf-8) See also {@link setCharset} and {@link getCharset}.
  391.      *     - "mime"    => mime encoding string (Sets document mime type;
  392.      *       defaults to text/html)  See also {@link setMimeEncoding}.
  393.      * <p><b>XHTML specific options:</b></p>
  394.      *     - "doctype"  => string (Sets XHTML doctype; defaults to
  395.      *       XHTML 1.0 Transitional.)  See also {@link setDoctype}.
  396.      *     - "language" => two letter language designation. (Defines global
  397.      *       document language; defaults to "en".) See also {@link setLang}.
  398.      *     - "namespace"  => string (Sets document namespace; defaults to the
  399.      *       W3C defined namespace.) See also {@link setNamespace}.
  400.      *     - "profile" => string (Sets head section profile) See also
  401.      *       {@link setHeadProfile}.
  402.      *     - "prolog" => bool (Enables or disables the XML prolog. This is
  403.      *       usually unwanted, as it makes the page invalid XHTML.) See also
  404.      *       {@link disableXmlProlog} and {@link enableXmlProlog}.
  405.      * 
  406.      * <p>For extensive usage examples, see class-level documentation
  407.      * ({@see HTML_Page2}).</p>
  408.      * 
  409.      * @param   mixed   $attributes     Associative array of table tag
  410.      *                                   attributes
  411.      * @access  public
  412.      * @since   2.0
  413.      */
  414.     function HTML_Page2($attributes = array())
  415.     {
  416.         
  417.         if ($attributes{
  418.             $attributes $this->_parseAttributes($attributes);
  419.         }
  420.         
  421.         if (isset($attributes['lineend'])) {
  422.             $this->setLineEnd($attributes['lineend']);
  423.         }
  424.         
  425.         if (isset($attributes['charset'])) {
  426.             $this->setCharset($attributes['charset']);
  427.         }
  428.         
  429.         if (isset($attributes['doctype'])){
  430.             if ($attributes['doctype'== 'none'{
  431.                 $this->_simple = true;
  432.             elseif ($attributes['doctype']{
  433.                 $this->setDoctype($attributes['doctype']);
  434.             }
  435.         }
  436.         
  437.         if (isset($attributes['language'])) {
  438.             $this->setLang($attributes['language']);
  439.         }
  440.         
  441.         if (isset($attributes['mime'])) {
  442.             $this->setMimeEncoding($attributes['mime']);
  443.         }
  444.         
  445.         if (isset($attributes['namespace'])) {
  446.             $this->setNamespace($attributes['namespace']);
  447.         }
  448.         
  449.         if (isset($attributes['profile'])) {
  450.             $this->setHeadProfile($attributes['profile']);
  451.         }
  452.         
  453.         if (isset($attributes['tab'])) {
  454.             $this->setTab($attributes['tab']);
  455.         }
  456.         
  457.         if (isset($attributes['cache'])) {
  458.             $this->setCache($attributes['cache']);
  459.         }
  460.         
  461.         if (isset($attributes['prolog'])) {
  462.             if ($attributes['prolog'=== false{
  463.                 $this->disableXmlProlog();
  464.             else {
  465.                 $this->enableXmlProlog();
  466.             }
  467.         }
  468.         
  469.     // end class constructor
  470.  
  471.     /**
  472.      * Iterates through an array, returning an HTML string
  473.      * 
  474.      * <p>It also handles objects, calling the toHTML or toString methods
  475.      * and propagating the line endings and tabs for objects that
  476.      * extend HTML_Common.</p>
  477.      * 
  478.      * <p>For more details read the well-documented source.</p>
  479.      * 
  480.      * @access  protected
  481.      * @param   mixed       $element   The element to be processed
  482.      * @return  string 
  483.      */
  484.     function _elementToHtml(&$element// It's a reference just to save some memory.
  485.     {
  486.         
  487.         // get the special formatting settings
  488.         $lnEnd  $this->_getLineEnd();
  489.         $tab    $this->_getTab();
  490.         $tabs   $this->_getTabs();
  491.         $offset $this->getTabOffset(+ 1;
  492.         
  493.         // initialize the variable that will collect our generated HTML
  494.         $strHtml ''
  495.         
  496.         // Attempt to generate HTML code for what is passed
  497.         if (is_object($element)) {
  498.             // If this is an object, attempt to generate the appropriate HTML 
  499.             // code.
  500.             
  501.             if (is_subclass_of($element'html_common')) {
  502.                 // For this special case, we set the appropriate indentation
  503.                 // and line end styles. That way uniform HTML is generated.
  504.                 
  505.                 // The reason this does not check for each method individually 
  506.                 // is that it could be that setTab, for example, could 
  507.                 // possibly refer to setTable, etc. And such ambiguity could
  508.                 // create a big mess. So this will simply bias  the HTML_Page 
  509.                 // class family toward other HTML_Common-based classes.
  510.                 
  511.                 // Of course, these features are not necessarily implemented
  512.                 // in all HTML_Common-based packages. But at least this makes 
  513.                 // it possible to propagate the settings.
  514.                 $element->setTabOffset($offset);
  515.                 $element->setTab($tab);
  516.                 $element->setLineEnd($lnEnd);
  517.             }
  518.             
  519.             // Attempt to generate code using first toHtml and then toString 
  520.             // methods. The result is not parsed with _elementToHtml because
  521.             // it would improperly add one tab indentation to the initial line
  522.             // of each object's output.
  523.             if (method_exists($element'toHtml')) {
  524.                 $strHtml .= $element->toHtml($lnEnd;
  525.             elseif (method_exists($element'toString')) {
  526.                 $strHtml .= $element->toString($lnEnd;
  527.             else {
  528.                 // If the class does not have an appropriate method, an error 
  529.                 // should be returned rather than simply dying or outputting
  530.                 // the difficult to troubleshoot 'Object' output.
  531.                 $class get_class($element);
  532.                 PEAR::raiseError("Error: Content object (class $class" .
  533.                                  'does not support  methods toHtml() or ' .
  534.                                  'toString().',0,PEAR_ERROR_TRIGGER);
  535.             }
  536.         elseif (is_array($element)) {
  537.             foreach ($element as $item{
  538.                 // Parse each element individually
  539.                 $strHtml .= $this->_elementToHtml($item);
  540.             }
  541.         else 
  542.             // If we don't have an object or array, we can simply output
  543.             // the element after indenting it and properly ending the line.
  544.             $strHtml .= $tabs $tab $element $lnEnd;
  545.         }
  546.         
  547.         return $strHtml;
  548.         
  549.     // end func _elementToHtml
  550.     
  551.     /**
  552.      * Generates the HTML string for the <body> tag
  553.      * 
  554.      * @access  private
  555.      * @return  string 
  556.      */
  557.     function _generateBody()
  558.     {
  559.         
  560.         // get line endings
  561.         $lnEnd $this->_getLineEnd();
  562.         $tabs $this->_getTabs();
  563.         
  564.         // If body attributes exist, add them to the body tag.
  565.         // Many attributes are depreciated because of CSS.
  566.         $strAttr $this->_getAttrString($this->_attributes);
  567.         
  568.         // If this is a frameset, we don't want to output the body tag, but 
  569.         // rather the <noframes> tag.
  570.         if (isset($this->_doctype['variant']&& $this->_doctype['variant'== 'frameset'{
  571.             $this->_tabOffset++;
  572.             $tabs $this->_getTabs();
  573.             $strHtml $tabs '<noframes>' $lnEnd;
  574.             $this->_tabOffset++;
  575.             $tabs $this->_getTabs();
  576.         else {
  577.             $strHtml '';
  578.         }
  579.         
  580.         if ($strAttr{
  581.             $strHtml .= $tabs . "<body $strAttr>" . $lnEnd;
  582.         else {
  583.             $strHtml .= $tabs '<body>' $lnEnd;
  584.         }
  585.  
  586.         // Allow for mixed content in the body array, recursing into inner
  587.         // array serching for non-array types.
  588.         $strHtml .= $this->_elementToHtml($this->_body);
  589.         
  590.         // Close tag
  591.         $strHtml .= $tabs '</body>' $lnEnd;
  592.         
  593.         // See above comment for frameset usage
  594.         if (isset($this->_doctype['variant']&& $this->_doctype['variant'== 'frameset'{
  595.             $this->_tabOffset--;
  596.             $strHtml .= $this->_getTabs('</noframes>' $lnEnd;
  597.             $this->_tabOffset--;
  598.         }
  599.         
  600.         // Let's roll!
  601.         return $strHtml;
  602.     // end func _generateBody
  603.     
  604.     /**
  605.      * Generates the HTML string for the <head> tag
  606.      * 
  607.      * @return string 
  608.      * @access private
  609.      */
  610.     function _generateHead()
  611.     {
  612.         // Close empty tags if XHTML for XML compliance
  613.         if ($this->_doctype['type'== 'html'){
  614.             $tagEnd '>';
  615.         else {
  616.             $tagEnd ' />';
  617.         }
  618.         
  619.         // get line endings
  620.         $lnEnd $this->_getLineEnd();
  621.         $tab $this->_getTab();
  622.         $tabs $this->_getTabs();
  623.         
  624.         $strHtml  $tabs '<head>' $lnEnd;
  625.         
  626.         // Generate META tags
  627.         foreach ($this->_metaTags as $type => $tag{
  628.             foreach ($tag as $name => $content{
  629.                 if ($type == 'http-equiv'{
  630.                     $strHtml .= $tabs $tab . "<meta http-equiv=\"$name\" content=\"$content\"" . $tagEnd $lnEnd;
  631.                 elseif ($type == 'standard'{
  632.                     $strHtml .= $tabs $tab . "<meta name=\"$name\" content=\"$content\"" . $tagEnd $lnEnd;
  633.                 }
  634.             }
  635.         }
  636.         
  637.         // Generate the title tag.
  638.         // Pre-XHTML compatibility:
  639.         //     This comes after meta tags because of possible
  640.         //     http-equiv character set declarations.
  641.         $strHtml .= $tabs $tab '<title>' $this->getTitle('</title>' $lnEnd;
  642.         
  643.         // Generate link declarations
  644.         foreach ($this->_links as $link{
  645.             $strHtml .= $tabs $tab $link $tagEnd $lnEnd;
  646.         }
  647.         
  648.         // Generate stylesheet links
  649.         foreach ($this->_styleSheets as $strSrc => $strAttr {
  650.             $strHtml .= $tabs $tab . "<link rel=\"stylesheet\" href=\"$strSrc\" type=\"".$strAttr['mime'].'"';
  651.             if (!is_null($strAttr['media'])){
  652.                 $strHtml .= ' media="'.$strAttr['media'].'"';
  653.             }
  654.             $strHtml .= $tagEnd $lnEnd;
  655.         }
  656.         
  657.         // Generate stylesheet declarations
  658.         foreach ($this->_style as $styledecl{
  659.             foreach ($styledecl as $type => $content{
  660.                 $strHtml .= $tabs $tab '<style type="' $type '">' $lnEnd;
  661.                 
  662.                 // This is for full XHTML support.
  663.                 if ($this->_mime == 'text/html' {
  664.                     $strHtml .= $tabs $tab $tab '<!--' $lnEnd;
  665.                 else {
  666.                     $strHtml .= $tabs $tab $tab '<![CDATA[' $lnEnd;
  667.                 }
  668.                 
  669.                 if (is_object($content)) {
  670.                     
  671.                     // first let's propagate line endings and tabs for other HTML_Common-based objects
  672.                     if (is_subclass_of($content"html_common")) {
  673.                         $content->setTab($tab);
  674.                         $content->setTabOffset(3);
  675.                         $content->setLineEnd($lnEnd);
  676.                     }
  677.                     
  678.                     // now let's get a string from the object
  679.                     if (method_exists($content"toString")) {
  680.                         $strHtml .= $content->toString($lnEnd;
  681.                     else {
  682.                         PEAR::raiseError('Error: Style content object does not support  method toString().',
  683.                                 0,PEAR_ERROR_TRIGGER);
  684.                     }
  685.                     
  686.                 else {
  687.                     $strHtml .= $content $lnEnd;
  688.                 }
  689.                 
  690.                 // See above note
  691.                 if ($this->_mime == 'text/html' {
  692.                     $strHtml .= $tabs $tab $tab '-->' $lnEnd;
  693.                 else {
  694.                     $strHtml .= $tabs $tab $tab ']]>' $lnEnd;
  695.                 }
  696.                 $strHtml .= $tabs $tab '</style>' $lnEnd;
  697.             }
  698.         // end generating stylesheet blocks
  699.         
  700.         // Generate script file links
  701.         foreach ($this->_scripts as $strSrc => $strType{
  702.             $strHtml .= $tabs $tab . "<script type=\"$strType\" src=\"$strSrc\"></script>" . $lnEnd;
  703.         }
  704.         
  705.         // Generate script declarations
  706.         foreach ($this->_script as $script{
  707.             foreach ($script as $type => $content{
  708.                 $strHtml .= $tabs $tab '<script type="' $type '">' $lnEnd;
  709.                 
  710.                 // This is for full XHTML support.
  711.                 if ($this->_mime == 'text/html' {
  712.                     $strHtml .= $tabs $tab $tab '// <!--' $lnEnd;
  713.                 else {
  714.                     $strHtml .= $tabs $tab $tab '<![CDATA[' $lnEnd;
  715.                 }
  716.                 
  717.                 if (is_object($content)) {
  718.                     
  719.                     // first let's propagate line endings and tabs for other HTML_Common-based objects
  720.                     if (is_subclass_of($content"html_common")) {
  721.                         $content->setTab($tab);
  722.                         $content->setTabOffset(3);
  723.                         $content->setLineEnd($lnEnd);
  724.                     }
  725.                     
  726.                     // now let's get a string from the object
  727.                     if (method_exists($content"toString")) {
  728.                         $strHtml .= $content->toString($lnEnd;
  729.                     else {
  730.                         PEAR::raiseError('Error: Script content object does not support  method toString().',
  731.                                 0,PEAR_ERROR_TRIGGER);
  732.                     }
  733.                     
  734.                 else {
  735.                     $strHtml .= $content $lnEnd;
  736.                 }
  737.                 
  738.                 // See above note
  739.                 if ($this->_mime == 'text/html' {
  740.                     $strHtml .= $tabs $tab $tab '// -->' $lnEnd;
  741.                 else {
  742.                     $strHtml .= $tabs $tab $tab '// ]]>' $lnEnd;
  743.                 }
  744.                 $strHtml .= $tabs $tab '</script>' $lnEnd;
  745.             }
  746.         // end generating script blocks
  747.         
  748.         // Close tag
  749.         $strHtml .=  $tabs '</head>' $lnEnd;
  750.         
  751.         // Let's roll!
  752.         return $strHtml;
  753.     // end func _generateHead
  754.     
  755.     /**
  756.      * Returns the doctype declaration
  757.      *
  758.      * @return string 
  759.      * @access private
  760.      */
  761.     function _getDoctype()
  762.     {
  763.         require('HTML/Page2/Doctypes.php');
  764.         
  765.         if (isset($this->_doctype['type'])) {
  766.             $type $this->_doctype['type'];
  767.         }
  768.         
  769.         if (isset($this->_doctype['version'])) {
  770.             $version $this->_doctype['version'];
  771.         }
  772.         
  773.         if (isset($this->_doctype['variant'])) {
  774.             $variant $this->_doctype['variant'];
  775.         }
  776.         
  777.         $strDoctype '';
  778.         
  779.         if (isset($variant)) {
  780.             if (isset($doctype[$type][$version][$variant][0])) {
  781.                 foreach $doctype[$type][$version][$variantas $string{
  782.                     $strDoctype .= $string.$this->_getLineEnd();
  783.                 }
  784.             }
  785.         elseif (isset($version)) {
  786.             if (isset($doctype[$type][$version][0])) {
  787.                 foreach $doctype[$type][$versionas $string{
  788.                     $strDoctype .= $string.$this->_getLineEnd();
  789.                 }
  790.             else {
  791.                 if (isset($default[$type][$version][0])) {
  792.                     $this->_doctype $this->_parseDoctypeString($default[$type][$version][0]);
  793.                     $strDoctype $this->_getDoctype();
  794.                 }
  795.             }
  796.         elseif (isset($type)) {
  797.             if (isset($default[$type][0])){
  798.                 $this->_doctype $this->_parseDoctypeString($default[$type][0]);
  799.                 $strDoctype $this->_getDoctype();
  800.             }
  801.         else {
  802.             $this->_doctype $this->_parseDoctypeString($default['default'][0]);
  803.             $strDoctype $this->_getDoctype();
  804.         }
  805.         
  806.         if ($strDoctype{
  807.             return $strDoctype;
  808.         else {
  809.             PEAR::raiseError('Error: "'.$this->getDoctypeString().'" is an unsupported or illegal document type.',
  810.                                     0,PEAR_ERROR_TRIGGER);
  811.             $this->_simple = true;
  812.             return false;
  813.         }
  814.         
  815.     // end func _getDoctype
  816.     
  817.     /**
  818.      * Retrieves the document namespace
  819.      *
  820.      * @return string 
  821.      * @access private
  822.      */
  823.     function _getNamespace()
  824.     {
  825.         
  826.         require('HTML/Page2/Namespaces.php');
  827.         
  828.         if (isset($this->_doctype['type'])) {
  829.             $type $this->_doctype['type'];
  830.         }
  831.         
  832.         if (isset($this->_doctype['version'])) {
  833.             $version $this->_doctype['version'];
  834.         }
  835.         
  836.         if (isset($this->_doctype['variant'])) {
  837.             $variant $this->_doctype['variant'];
  838.         }
  839.         
  840.         $strNamespace '';
  841.         
  842.         if (isset($variant)){
  843.             if (isset($namespace[$type][$version][$variant][0]&& is_string($namespace[$type][$version][$variant][0])) {
  844.                 $strNamespace $namespace[$type][$version][$variant][0];
  845.             elseif (isset($namespace[$type][$version][0]&& is_string($namespace[$type][$version][0]) ) {
  846.                 $strNamespace $namespace[$type][$version][0];
  847.             elseif (isset($namespace[$type][0]&& is_string($namespace[$type][0]) ) {
  848.                 $strNamespace $namespace[$type][0];
  849.             }
  850.         elseif (isset($version)) {
  851.             if (isset($namespace[$type][$version][0]&& is_string($namespace[$type][$version][0]) ) {
  852.                 $strNamespace $namespace[$type][$version][0];
  853.             elseif (isset($namespace[$type][0]&& is_string($namespace[$type][0]) ) {
  854.                 $strNamespace $namespace[$type][0];
  855.             }
  856.         else {
  857.             if (isset($namespace[$type][0]&& is_string($namespace[$type][0]) ) {
  858.                 $strNamespace $namespace[$type][0];
  859.             }
  860.         }
  861.         
  862.         if ($strNamespace{
  863.             return $strNamespace;
  864.         else {
  865.             PEAR::raiseError('Error: "' $this->getDoctypeString(.
  866.                                     '" does not have a default namespace.' .
  867.                                     ' Use setNamespace() to define your namespace.',
  868.                                     0PEAR_ERROR_TRIGGER);
  869.             return false;
  870.         }
  871.         
  872.     // end func _getNamespace
  873.     
  874.     /**
  875.      * Parses a doctype declaration like "XHTML 1.0 Strict" to an array
  876.      *
  877.      * @param   string  $string     The string to be parsed
  878.      * @return array 
  879.      * @access private
  880.      */
  881.     function _parseDoctypeString($string)
  882.     {
  883.         
  884.         $split explode(' ',strtolower($string));
  885.         $elements count($split);
  886.         
  887.         if (isset($split[2])){
  888.             $array = array('type'=>$split[0],'version'=>$split[1],'variant'=>$split[2]);
  889.         elseif (isset($split[1])){
  890.             $array = array('type'=>$split[0],'version'=>$split[1]);
  891.         else {
  892.             $array = array('type'=>$split[0]);
  893.         }
  894.         
  895.         return $array;
  896.         
  897.     // end func _parseDoctypeString
  898.     
  899.     /**
  900.      * Sets the content of the <body> tag
  901.      * 
  902.      * <p>It is possible to add objects, strings or an array of strings
  903.      * and/or objects. Objects must have a toHtml or toString method.</p>
  904.      * 
  905.      * <p>By default, if content already exists, the new content is appended.
  906.      * If you wish to overwrite whatever is in the body, use {@link setBody};
  907.      * {@link unsetBody} completely empties the body without inserting new
  908.      * content. You can also use {@link prependBodyContent} to prepend content
  909.      * to whatever is currently in the array of body elements.</p>
  910.      * 
  911.      * <p>The following constants are defined to be passed as the flag
  912.      * attribute: HTML_PAGE2_APPEND, HTML_PAGE2_PREPEND and HTML_PAGE2_REPLACE.
  913.      * Their usage should be quite clear from their names.</p>
  914.      * 
  915.      * @param mixed $content  New <body> tag content (may be passed as a
  916.      *                         reference)
  917.      * @param int   $flag     Determines whether to prepend, append or replace
  918.      *                         the content. Use pre-defined constants.
  919.      * @access public
  920.      */
  921.     function addBodyContent($content$flag = HTML_PAGE2_APPEND)
  922.     {
  923.         
  924.         if ($flag == HTML_PAGE2_REPLACE{       // replaces any content in body 
  925.             $this->unsetBody();
  926.             $this->_body[=$content;
  927.         elseif ($flag == HTML_PAGE2_PREPEND// prepends content to the body 
  928.             array_unshift($this->_body$content);
  929.         else {                                // appends content to the body
  930.             $this->_body[=$content;
  931.         }
  932.         
  933.     // end addBodyContent    
  934.     
  935.     /**
  936.      * Adds a linked script to the page
  937.      * 
  938.      * @param    string  $url        URL to the linked script
  939.      * @param    string  $type       Type of script. Defaults to 'text/javascript'
  940.      * @access   public
  941.      */
  942.     function addScript($url$type="text/javascript")
  943.     {
  944.         $this->_scripts[$url$type;
  945.     // end func addScript
  946.     
  947.     /**
  948.      * Adds a script to the page
  949.      *
  950.      * <p>Content can be a string or an object with a toString method.
  951.      * Defaults to text/javascript.</p>
  952.      * 
  953.      * @access   public
  954.      * @param    mixed   $content   Script (may be passed as a reference)
  955.      * @param    string  $type      Scripting mime (defaults to 'text/javascript')
  956.      * @return   void 
  957.      */
  958.     function addScriptDeclaration($content$type 'text/javascript')
  959.     {
  960.         $this->_script[][strtolower($type)=$content;
  961.     // end func addScriptDeclaration
  962.     
  963.     /**
  964.      * Adds a linked stylesheet to the page
  965.      * 
  966.      * @param    string  $url    URL to the linked style sheet
  967.      * @param    string  $type   Mime encoding type
  968.      * @param    string  $media  Media type that this stylesheet applies to
  969.      * @access   public
  970.      * @return   void 
  971.      */
  972.     function addStyleSheet($url$type 'text/css'$media = null)
  973.     {
  974.         $this->_styleSheets[$url]['mime']  $type;
  975.         $this->_styleSheets[$url]['media'$media;
  976.     // end func addStyleSheet
  977.     
  978.     /**
  979.      * Adds a stylesheet declaration to the page
  980.      * 
  981.      * <p>Content can be a string or an object with a toString method.
  982.      * Defaults to text/css.</p>
  983.      * 
  984.      * @access   public
  985.      * @param    mixed   $content   Style declarations (may be passed as a reference)
  986.      * @param    string  $type      Type of stylesheet (defaults to 'text/css')
  987.      * @return   void 
  988.      */
  989.     function addStyleDeclaration($content$type 'text/css')
  990.     {
  991.         $this->_style[][strtolower($type)=$content;
  992.     // end func addStyleDeclaration
  993.     
  994.     /**
  995.      * Adds a shortcut icon (favicon)
  996.      * 
  997.      * <p>This adds a link to the icon shown in the favorites list or on
  998.      * the left of the url in the address bar. Some browsers display
  999.      * it on the tab, as well.</p>
  1000.      * 
  1001.      * @access    public
  1002.      * @param     string  $href        The link that is being related.
  1003.      * @param     string  $type        File type
  1004.      * @param     string  $relation    Relation of link
  1005.      * @return    void 
  1006.      */
  1007.     function addFavicon($href$type 'image/x-icon'$relation 'shortcut icon'{
  1008.         $this->_links[= "<link href=\"$href\" rel=\"$relation\" type=\"$type\"";
  1009.     // end func addFavicon
  1010.  
  1011.     /**
  1012.      * Adds <link> tags to the head of the document
  1013.      * 
  1014.      * <p>$relType defaults to 'rel' as it is the most common relation type used.
  1015.      * ('rev' refers to reverse relation, 'rel' indicates normal, forward relation.)
  1016.      * Typical tag: <link href="index.php" rel="Start"></p>
  1017.      * 
  1018.      * @access   public
  1019.      * @param    string  $href       The link that is being related.
  1020.      * @param    string  $relation   Relation of link.
  1021.      * @param    string  $relType    Relation type attribute.  Either rel or rev (default: 'rel').
  1022.      * @param    array   $attributes Associative array of remaining attributes.
  1023.      * @return   void 
  1024.      */
  1025.     function addHeadLink($href$relation$relType 'rel'$attributes = array()) {
  1026.         $attributes $this->_parseAttributes($attributes);
  1027.         $generatedTag $this->_getAttrString($attributes);
  1028.         $generatedTag = "<link href=\"$href\" $relType=\"$relation\"" . $generatedTag;
  1029.         $this->_links[$generatedTag;
  1030.     // end func addHeadLink
  1031.  
  1032.     /**
  1033.      * Returns the current API version
  1034.      * 
  1035.      * @access   public
  1036.      * @return   double 
  1037.      */
  1038.     function apiVersion()
  1039.     {
  1040.         return 2.0;
  1041.     // end func apiVersion
  1042.     
  1043.     /**
  1044.      *  Disables prepending the XML prolog for XHTML documents
  1045.      * 
  1046.      * <p>Normally, XHTML documents require the XML prolog to be on the first
  1047.      * line of each valid document:</p>
  1048.      * 
  1049.      * <code>
  1050.      * <?xml version="1.0" encoding="utf-8"?>
  1051.      * <!DOCTYPE html
  1052.      *     PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
  1053.      *     "http://www.w3c.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
  1054.      * 
  1055.      * <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
  1056.      * <head>
  1057.      * ...
  1058.      * </code>
  1059.      * 
  1060.      * <p>However, some browsers, most noticeably Microsoft Internet Explorer,
  1061.      * have difficulties properly displaying XHTML in compatibility mode with
  1062.      * this. This method is for workaround solutions, such as the infamous CSS
  1063.      * Box Hack.</p>
  1064.      * 
  1065.      * <p>The opposite (and default) effect can be achieved using the
  1066.      * {@link enableXmlProlog} method.</p>
  1067.      * 
  1068.      * <p>Usage:</p>
  1069.      * 
  1070.      * <code>
  1071.      * $page->disableXmlProlog();
  1072.      * </code>
  1073.      * 
  1074.      * @access   public
  1075.      * @return  void 
  1076.      */
  1077.     function disableXmlProlog()
  1078.     {
  1079.         $this->_xmlProlog = false;
  1080.     // end func disableXmlProlog
  1081.     
  1082.     /**
  1083.      * Enables prepending the XML prolog for XHTML documents (default)
  1084.      * 
  1085.      * <p>This method enables the default XHTML output, with an XML prolog on
  1086.      * the first line of the document. See {@link disableXmlProlog} for more
  1087.      * details on why it may or may not be advantageous to have the XML prolog
  1088.      * disabled.</p>
  1089.      * 
  1090.      * <p>Usage:</p>
  1091.      * 
  1092.      * <code>
  1093.      * $page->enableXmlProlog();
  1094.      * </code>
  1095.      * 
  1096.      * @access   public
  1097.      * @return   void 
  1098.      */
  1099.     function enableXmlProlog()
  1100.     {
  1101.         $this->_xmlProlog = true;
  1102.     // end func enableXmlProlog
  1103.     
  1104.     /**
  1105.      * Returns the document charset encoding.
  1106.      * 
  1107.      * @access public
  1108.      * @return string 
  1109.      */
  1110.     function getCharset()
  1111.     {
  1112.         return $this->_charset;
  1113.     // end setCache
  1114.     
  1115.     /**
  1116.      * Returns the document type string
  1117.      *
  1118.      * @access public
  1119.      * @return string 
  1120.      */
  1121.     function getDoctypeString()
  1122.     {
  1123.         $strDoctype strtoupper($this->_doctype['type']);
  1124.         $strDoctype .= ' '.ucfirst(strtolower($this->_doctype['version']));
  1125.         if ($this->_doctype['variant']{
  1126.             $strDoctype .= ' ' ucfirst(strtolower($this->_doctype['variant']));
  1127.         }
  1128.         return trim($strDoctype);
  1129.     // end func getDoctypeString
  1130.     
  1131.     /**
  1132.      * Returns the document language.
  1133.      * 
  1134.      * @return string 
  1135.      * @access public
  1136.      */
  1137.     function getLang()
  1138.     {
  1139.         return $this->_language;
  1140.     // end func getLang
  1141.     
  1142.     /**
  1143.      * Return the title of the page.
  1144.      * 
  1145.      * @return   string 
  1146.      * @access   public
  1147.      */
  1148.     function getTitle()
  1149.     {
  1150.         if (!$this->_title){
  1151.             if ($this->_simple{
  1152.                 return 'New Page';
  1153.             else {
  1154.                 return 'New '$this->getDoctypeString(' Compliant Page';
  1155.             }
  1156.         else {
  1157.             return $this->_title;
  1158.         }
  1159.     // end func getTitle
  1160.     
  1161.     /**
  1162.      * Prepends content to the content of the <body> tag. Wrapper for {@link addBodyContent}
  1163.      * 
  1164.      * <p>If you wish to overwrite whatever is in the body, use {@link setBody};
  1165.      * {@link addBodyContent} provides full functionality including appending;
  1166.      * {@link unsetBody} completely empties the body without inserting new content.
  1167.      * It is possible to add objects, strings or an array of strings and/or objects
  1168.      * Objects must have a toString method.</p>
  1169.      *
  1170.      * @param mixed $content  New <body> tag content (may be passed as a reference)
  1171.      * @access public
  1172.      */
  1173.     function prependBodyContent($content)
  1174.     {
  1175.         $this->addBodyContent($contentHTML_PAGE2_PREPEND);
  1176.     // end func prependBodyContent
  1177.     
  1178.     /**
  1179.      * Sets the content of the <body> tag.
  1180.      * 
  1181.      * <p>If content exists, it is overwritten. If you wish to use a "safe"
  1182.      * version, use {@link addBodyContent}. Objects must have a toString
  1183.      * method.</p>
  1184.      * 
  1185.      * <p>This function acts as a wrapper for {@link addBodyContent}. If you
  1186.      * are using PHP 4.x and would like to pass an object by reference, this
  1187.      * is not the function to use. Use {@link addBodyContent} with the flag
  1188.      * HTML_PAGE2_REPLACE instead.</p>
  1189.      * 
  1190.      * @param mixed    $content   New <body> tag content. May be an object.
  1191.      *                             (may be passed as a reference)
  1192.      * @access public
  1193.      */
  1194.     function setBody($content)
  1195.     {
  1196.         $this->addBodyContent($contentHTML_PAGE2_REPLACE);
  1197.     // end setBody
  1198.     
  1199.     /**
  1200.      * Unsets the content of the <body> tag.
  1201.      * 
  1202.      * @access public
  1203.      */
  1204.     function unsetBody()
  1205.     {
  1206.         $this->_body = array();
  1207.     // end unsetBody
  1208.     
  1209.     /**
  1210.      * Sets the attributes of the <body> tag
  1211.      * 
  1212.      * <p>If attributes exist, they are overwritten. In XHTML, all attribute
  1213.      * names must be lowercase. As lowercase attributes are legal in SGML, all
  1214.      * attributes are automatically lowercased. This also prevents accidentally
  1215.      * creating duplicate attributes when attempting to update one.</p>
  1216.      * 
  1217.      * @param  array   $attributes   <body> tag attributes.
  1218.      * @access public
  1219.      */
  1220.     function setBodyAttributes($attributes)
  1221.     {
  1222.         $this->setAttributes($attributes);
  1223.     // end setBodyAttributes
  1224.  
  1225.     /**
  1226.      * Defines if the document should be cached by the browser
  1227.      * 
  1228.      * <p>Defaults to false.</p>
  1229.      * 
  1230.      * <p>A fully configurable cache header is in the works. for now, though
  1231.      * if you would like to determine exactly what caching headers are sent to
  1232.      * to the browser, set cache to true, and then output your own headers
  1233.      * before calling {@link display}.</p>
  1234.      * 
  1235.      * @param  string   $cache  Options are currently 'true' or 'false'
  1236.      * @access public
  1237.      */
  1238.     function setCache($cache 'false')
  1239.     {
  1240.         if ($cache == 'true'){
  1241.             $this->_cache = true;
  1242.         else {
  1243.             $this->_cache = false;
  1244.         }
  1245.     // end setCache
  1246.     
  1247.     /**
  1248.      * Sets the document charset
  1249.      * 
  1250.      * <p>By default, HTML_Page2 uses UTF-8 encoding. This is properly handled
  1251.      * by PHP, but remember to use the htmlentities attribute for charset so
  1252.      * that whatever you get from a database is properly handled by the
  1253.      * browser.</p>
  1254.      * 
  1255.      * <p>The current most popular encoding: iso-8859-1. If it is used,
  1256.      * htmlentities and htmlspecialchars can be used without any special
  1257.      * settings.</p>
  1258.      * 
  1259.      * @param   string   $type  Charset encoding string
  1260.      * @access  public
  1261.      * @return  void 
  1262.      */
  1263.     function setCharset($type 'utf-8')
  1264.     {
  1265.         $this->_charset $type;
  1266.     // end setCache
  1267.     
  1268.     /**
  1269.      * Sets or alters the !DOCTYPE declaration.
  1270.      * 
  1271.      * <p>Can be set to "strict", "transitional" or "frameset".
  1272.      * Defaults to "XHTML 1.0 Transitional".</p>
  1273.      * 
  1274.      * <p>This must come <i>after</i> declaring the character encoding with
  1275.      * {@link setCharset} or directly when the class is initiated
  1276.      * {@link HTML_Page2}. Use in conjunction with {@link setMimeEncoding}</p>
  1277.      * 
  1278.      * <p>Framesets are not yet implemented.</p>
  1279.      * 
  1280.      * @param   string   $type  String containing a document type
  1281.      * @access  public
  1282.      * @return  void 
  1283.      */
  1284.     function setDoctype($type "XHTML 1.0 Transitional")
  1285.     {
  1286.         $this->_doctype $this->_parseDoctypeString($type);
  1287.         if($this->_doctype['variant'== 'frameset'{
  1288.             
  1289.             $options = array('master' => true);
  1290.             if ($this->_doctype['type'== 'xhtml'{
  1291.                 $options['xhtml'= true;
  1292.             }
  1293.             
  1294.             // make sure we have the frameset class loaded
  1295.             require_once 'HTML/Page2/Frameset.php';
  1296.             $this->frameset = new HTML_Page2_Frameset($options);
  1297.         }
  1298.     // end func setDoctype
  1299.     
  1300.     /**
  1301.      * Sets the <head> profile
  1302.      * 
  1303.      * <p>Profiles allow for adding various uncommented links, etc. to the
  1304.      * head section. For more details, see the W3C documents
  1305.      * ({@link http://www.w3.org/TR/html4/struct/global.html#h-7.4.4.3}
  1306.      * http://www.w3.org/TR/html4/struct/global.html#h-7.4.4.3} and
  1307.      * {@link http://www.w3.org/TR/html401/types.html#type-links}
  1308.      * http://www.w3.org/TR/html401/types.html#type-links})
  1309.      * detailing proper use.</p>
  1310.      * 
  1311.      * @param    string    $profile   URL to profile
  1312.      * @access   public
  1313.      * @return   void 
  1314.      */
  1315.     function setHeadProfile($profile '')
  1316.     {
  1317.         $this->_profile $profile;
  1318.     // end func setHeadProfile
  1319.     
  1320.     /**
  1321.      * Sets the global document language declaration. Default is English.
  1322.      * 
  1323.      * @access public
  1324.      * @param   string   $lang    Two-letter language designation
  1325.      */
  1326.     function setLang($lang "en")
  1327.     {
  1328.         $this->_language strtolower($lang);
  1329.     // end setLang
  1330.     
  1331.     /**
  1332.      * Sets or alters a meta tag.
  1333.      * 
  1334.      * @param string  $name           Value of name or http-equiv tag
  1335.      * @param string  $content        Value of the content tag
  1336.      * @param bool    $http_equiv     META type "http-equiv" defaults to null
  1337.      * @return void 
  1338.      * @access public
  1339.      */
  1340.     function setMetaData($name$content$http_equiv = false)
  1341.     {
  1342.         if ($content == ''{
  1343.             $this->unsetMetaData($name$http_equiv);
  1344.         else {
  1345.             if ($http_equiv == true{
  1346.                 $this->_metaTags['http-equiv'][$name$content;
  1347.             else {
  1348.                 $this->_metaTags['standard'][$name$content;
  1349.             }
  1350.         }
  1351.     // end func setMetaData
  1352.     
  1353.     /**
  1354.      * Unsets a meta tag.
  1355.      *
  1356.      * @param string  $name           Value of name or http-equiv tag
  1357.      * @param bool    $http_equiv     META type "http-equiv" defaults to null
  1358.      * @return void 
  1359.      * @access public
  1360.      */
  1361.     function unsetMetaData($name$http_equiv = false)
  1362.     {
  1363.         if ($http_equiv == true{
  1364.             unset($this->_metaTags['http-equiv'][$name]);
  1365.         else {
  1366.             unset($this->_metaTags['standard'][$name]);
  1367.         }
  1368.     // end func unsetMetaData
  1369.  
  1370.     /**
  1371.      * Sets an http-equiv Content-Type meta tag
  1372.      * 
  1373.      * @access   public
  1374.      * @return   void 
  1375.      */
  1376.     function setMetaContentType()
  1377.     {
  1378.         $this->setMetaData('Content-Type'$this->_mime '; charset=' $this->_charset true );
  1379.     // end func setMetaContentType
  1380.     
  1381.     /**
  1382.      * Shortcut to set or alter a refresh meta tag
  1383.      * 
  1384.      * <p>If no $url is passed, "self" is presupposed, and the appropriate URL
  1385.      * will be automatically generated. In this case, an optional third
  1386.      * boolean parameter enables https redirects to self.</p>
  1387.      * 
  1388.      * @param int     $time    Time till refresh (in seconds)
  1389.      * @param string  $url     Absolute URL or "self"
  1390.      * @param bool    $https   If $url == self, this allows for the https
  1391.      *                          protocol defaults to null
  1392.      * @return void 
  1393.      * @access public
  1394.      */
  1395.     function setMetaRefresh($time$url 'self'$https = false)
  1396.     {
  1397.         if ($url == 'self'{
  1398.             if ($https
  1399.                 $protocol 'https://';
  1400.             else {
  1401.                 $protocol 'http://';
  1402.             }
  1403.             $url $protocol $_SERVER['HTTP_HOST'$_SERVER['REQUEST_URI'];
  1404.         }
  1405.         $this->setMetaData("Refresh""$time; url=$url"true);
  1406.     // end func setMetaRefresh
  1407.     
  1408.     /**
  1409.      * Sets the document MIME encoding that is sent to the browser.
  1410.      * 
  1411.      * <p>This usually will be text/html because most browsers cannot yet
  1412.      * accept the proper mime settings for XHTML: application/xhtml+xml
  1413.      * and to a lesser extent application/xml and text/xml. See the W3C note
  1414.      * ({@link http://www.w3.org/TR/xhtml-media-types/}
  1415.      * http://www.w3.org/TR/xhtml-media-types/}) for more details.</p>
  1416.      * 
  1417.      * <p>Here is a possible way of automatically including the proper mime
  1418.      * type for XHTML 1.0 if the requesting browser supports it:</p>
  1419.      * 
  1420.      * <code>
  1421.      * <?php
  1422.      * // Initialize the HTML_Page2 object:
  1423.      * require 'HTML/Page2.php';
  1424.      * $page = new HTML_Page2();
  1425.      * 
  1426.      * // Check if browse can take the proper mime type
  1427.      * if ( strpos($_SERVER['HTTP_ACCEPT'], 'application/xhtml+xml') ) {
  1428.      *     $page->setDoctype('XHTML 1.0 Strict');
  1429.      *     $page->setMimeEncoding('application/xhtml+xml');
  1430.      * } else {
  1431.      *     // HTML that qualifies for XHTML 1.0 Strict automatically
  1432.      *     // also complies with XHTML 1.0 Transitional, so if the
  1433.      *     // requesting browser doesn't take the necessary mime type
  1434.      *     // for XHTML 1.0 Strict, let's give it what it can take.
  1435.      *     $page->setDoctype('XHTML 1.0 Transitional');
  1436.      * }
  1437.      * 
  1438.      * // finish building your page here..
  1439.      * 
  1440.      * $page->display();
  1441.      * ?>
  1442.      * </code>
  1443.      * 
  1444.      * @param    string    $type 
  1445.      * @access   public
  1446.      * @return   void 
  1447.      */
  1448.     function setMimeEncoding($type 'text/html')
  1449.     {
  1450.         $this->_mime strtolower($type);
  1451.     // end func setMimeEncoding
  1452.     
  1453.     /**
  1454.      * Sets the document namespace
  1455.      * 
  1456.      * <p>By default, W3C namespaces are used. However, if you need to define
  1457.      * your own namespace, you can set it here.</p>
  1458.      * 
  1459.      * <p>Usage:<p>
  1460.      * 
  1461.      * <code>
  1462.      * // This is how you can set your own namespace:
  1463.      * $page->setNamespace('http://www.w3.org/1999/xhtml');
  1464.      * 
  1465.      * // This reverts to default setting and retrieves the appropriate
  1466.      * // W3C namespace for the document type:
  1467.      * $page->setNamespace();
  1468.      * </code>
  1469.      * 
  1470.      * @param    string    $namespace  Optional. W3C namespaces are used by default.
  1471.      * @access   public
  1472.      * @return   void 
  1473.      */
  1474.     function setNamespace($namespace '')
  1475.     {
  1476.         if (isset($namespace)){
  1477.             $this->_namespace $namespace;
  1478.         else {
  1479.             $this->_namespace $this->_getNamespace();
  1480.         }
  1481.     // end func setTitle
  1482.     
  1483.     /**
  1484.      * Sets the title of the page
  1485.      * 
  1486.      * <p>Usage:</p>
  1487.      * 
  1488.      * <code>
  1489.      * $page->setTitle('My Page');
  1490.      * </code>
  1491.      * 
  1492.      * @param    string    $title 
  1493.      * @access   public
  1494.      * @return   void 
  1495.      */
  1496.     function setTitle($title)
  1497.     {
  1498.         $this->_title $title;
  1499.     // end func setTitle
  1500.     
  1501.     /**
  1502.      * Generates and returns the complete page as a string
  1503.      * 
  1504.      * <p>This is what you would call if you want to save the page in a
  1505.      * database. It creates a complete, valid HTML document, and returns
  1506.      * it as a string.</p>
  1507.      * 
  1508.      * <p>Usage example:</p>
  1509.      * <code>
  1510.      * <?php
  1511.      * require "HTML/Page2.php";
  1512.      * $page = new HTML_Page2();
  1513.      * $page->setTitle('My Page');
  1514.      * $page->addBodyContent('<h1>My Page</h1>');
  1515.      * $page->addBodyContent('<p>First Paragraph.</p>');
  1516.      * $page->addBodyContent('<p>Second Paragraph.</p>');
  1517.      * $html = $page->toHtml();
  1518.      * // here you insert HTML into a database
  1519.      * ?>
  1520.      * </code>
  1521.      * 
  1522.      * @return string 
  1523.      * @access public
  1524.      */
  1525.     function toHtml()
  1526.     {
  1527.         
  1528.         // get line endings
  1529.         $lnEnd $this->_getLineEnd();
  1530.         
  1531.         // get the doctype declaration
  1532.         $strDoctype $this->_getDoctype();
  1533.         
  1534.         // This determines how the doctype is declared and enables various
  1535.         // features depending on whether the the document is XHTML, HTML or
  1536.         // if no doctype declaration is desired
  1537.         if ($this->_simple{
  1538.             
  1539.             $strHtml '<html>' $lnEnd;
  1540.             
  1541.         elseif ($this->_doctype['type'== 'xhtml'{
  1542.             
  1543.             // get the namespace if not already set
  1544.             if (!$this->_namespace){
  1545.                 $this->_namespace $this->_getNamespace();
  1546.             }
  1547.             
  1548.             $strHtml $strDoctype $lnEnd;
  1549.             $strHtml .= '<html xmlns="' $this->_namespace '" xml:lang="' $this->_language '"';
  1550.             
  1551.             // If a special profile is defined, make sure it is included
  1552.             // in the opening html tag. Normally this will not be the case.
  1553.             if ($this->_profile{
  1554.                 $strHtml .= ' profile="'.$this->_profile.'"';
  1555.             }
  1556.             $strHtml .= '>' $lnEnd;
  1557.             
  1558.             // check whether the XML prolog should be prepended
  1559.             if ($this->_xmlProlog){
  1560.                 $strHtml  '<?xml version="1.0" encoding="' $this->_charset '"?>' $lnEnd $strHtml;
  1561.             }
  1562.             
  1563.         else {
  1564.             
  1565.             $strHtml  $strDoctype $lnEnd;
  1566.             $strHtml .= '<html';
  1567.             
  1568.             // If a special profile is defined, make sure it is included
  1569.             // in the opening html tag. Normally this will not be the case.
  1570.             if ($this->_profile{
  1571.                 $strHtml .= ' profile="'.$this->_profile.'"';
  1572.             }
  1573.             
  1574.             $strHtml .= '>' $lnEnd;
  1575.             
  1576.         }
  1577.         
  1578.         // indent all nodes of <html> one place
  1579.         $this->_tabOffset++;
  1580.         
  1581.         $strHtml .= $this->_generateHead();
  1582.         
  1583.         if (isset($this->_doctype['variant']&& $this->_doctype['variant'== 'frameset'{
  1584.             
  1585.             // pass on settings to the frameset
  1586.             $this->frameset->setTab($this->_getTab());
  1587.             $this->frameset->setTabOffset($this->getTabOffset());
  1588.             $this->frameset->setLineEnd($lnEnd);
  1589.             
  1590.             $strHtml .= $this->frameset->toHtml();
  1591.             $strHtml .= $this->_generateBody();
  1592.             $strHtml .= $this->_getTabs('</frameset>' $lnEnd;
  1593.             
  1594.         else {
  1595.             
  1596.             $strHtml .= $this->_generateBody();
  1597.             
  1598.         }
  1599.         
  1600.         // In case something else is going to be done with this object,
  1601.         // let's set the offset back to normal.
  1602.         $this->_tabOffset--;
  1603.         
  1604.         $strHtml .= '</html>';
  1605.         return $strHtml;
  1606.     // end func toHtml
  1607.     
  1608.     /**
  1609.      * Generates the document and outputs it to a file.
  1610.      * 
  1611.      * <p>Uses {@link file_put_contents} when available. Includes a workaround
  1612.      * for older versions of PHP.</p>
  1613.      * 
  1614.      * <p>Usage example:</p>
  1615.      * <code>
  1616.      * <?php
  1617.      * require "HTML/Page2.php";
  1618.      * $page = new HTML_Page2();
  1619.      * $page->setTitle('My Page');
  1620.      * $page->addBodyContent('<h1>My Page</h1>');
  1621.      * $page->addBodyContent('<p>First Paragraph.</p>');
  1622.      * $page->addBodyContent('<p>Second Paragraph.</p>');
  1623.      * $page->toFile('myPage.html');
  1624.      * ?>
  1625.      * </code>
  1626.      * 
  1627.      * @return  void 
  1628.      * @since   2.0
  1629.      * @access  public
  1630.      */
  1631.     function toFile($filename)
  1632.     {
  1633.         file_put_contents($filename$this->toHtml());
  1634.         
  1635.         if (!file_exists($filename)){
  1636.             PEAR::raiseError("HTML_Page::toFile() error: Failed to write to $filename",0,PEAR_ERROR_TRIGGER);
  1637.         }
  1638.         
  1639.     // end func toFile
  1640.     
  1641.     /**
  1642.      * Outputs the HTML content to the browser
  1643.      * 
  1644.      * <p>This method outputs to the default display device. Normally that
  1645.      * will be the browser.</p>
  1646.      * 
  1647.      * <p>If caching is turned off, which is the default case, this generates
  1648.      * the appropriate headers:</p>
  1649.      * 
  1650.      * <code>
  1651.      * header("Expires: Tue, 1 Jan 1980 12:00:00 GMT");
  1652.      * header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
  1653.      * header("Cache-Control: no-cache");
  1654.      * header("Pragma: no-cache");
  1655.      * </code>
  1656.      * 
  1657.      * <p>This functionality can be disabled:</p>
  1658.      * 
  1659.      * <code>
  1660.      * $page->setCache('true');
  1661.      * </code>
  1662.      * 
  1663.      * @return   void 
  1664.      * @access   public
  1665.      */
  1666.     function display()
  1667.     {
  1668.         
  1669.         // If caching is to be implemented, this bit of code will need to be 
  1670.         // replaced with a private function. Else it may be possible to  
  1671.         // borrow from Cache or Cache_Lite.
  1672.         if(!$this->_cache{
  1673.             header("Expires: Tue, 1 Jan 1980 12:00:00 GMT");
  1674.             header("Last-Modified: " gmdate("D, d M Y H:i:s"" GMT");
  1675.             header("Cache-Control: no-cache");
  1676.             header("Pragma: no-cache");
  1677.         }
  1678.         
  1679.         // Set mime type and character encoding
  1680.         header('Content-Type: ' $this->_mime .  '; charset=' $this->_charset);
  1681.         
  1682.         // Generate HTML document
  1683.         $strHtml $this->toHTML();
  1684.         
  1685.         // Output to browser, screen or other default device
  1686.         print $strHtml;
  1687.         
  1688.     // end func display
  1689.     
  1690. }
  1691. ?>

Documentation generated on Thu, 29 Jan 2009 09:30:08 -0500 by phpDocumentor 1.4.0. PEAR Logo Copyright © PHP Group 2004.