]> git.llucax.com Git - mecon/meconlib.git/blob - pear_lib_tmp/HTML/Page.php
Cambios minimos de desenio
[mecon/meconlib.git] / pear_lib_tmp / HTML / Page.php
1 <?php
2 /* vim: set expandtab tabstop=4 shiftwidth=4: */
3 // +----------------------------------------------------------------------+
4 // | PHP Version 4                                                        |
5 // +----------------------------------------------------------------------+
6 // | Copyright (c) 1997 - 2003 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$
21
22 require_once 'PEAR.php';
23 require_once 'HTML/Common.php';
24 // HTML/Page/Doctypes.php is required in _getDoctype()
25 // HTML/Page/Namespaces.php is required in _getNamespace()
26
27 /**
28  * Base class for XHTML pages
29  *
30  * This class handles the details for creating a properly constructed XHTML page.
31  * Page caching, stylesheets, client side script, and Meta tags can be
32  * managed using this class.
33  * 
34  * The body may be a string, object, or array of objects or strings. Objects with
35  * toHtml() and toString() methods are supported.
36  * 
37  *
38  * XHTML Examples:
39  * ---------------
40  *
41  * Simplest example:
42  * -----------------
43  * <code>
44  * // the default doctype is XHTML 1.0 Transitional
45  * // All doctypes and defaults are set in HTML/Page/Doctypes.php
46  * $p = new HTML_Page();
47  *
48  * //add some content
49  * $p->addBodyContent("<p>some text</p>");
50  *
51  * // print to browser
52  * $p->display();
53  * </code>
54  * 
55  * Complex XHTML example:
56  * ----------------------
57  * <code>
58  * // The initializing code can also be in in the form of an HTML
59  * // attr="value" string.
60  * // Possible attributes are: charset, mime, lineend, tab, doctype, namespace, language and cache
61  * 
62  * $p = new HTML_Page(array (
63  *
64  *                          // Sets the charset encoding
65  *                          // utf-8 is default
66  *                          'charset'  => 'utf-8',
67  *
68  *                          // Sets the line end character
69  *                          // unix (\n) is default
70  *                          'lineend'  => 'unix',
71  *
72  *                          // Sets the tab string for autoindent
73  *                          // tab (\t) is default
74  *                          'tab'  => '  ',
75  *
76  *                          // This is where you define the doctype
77  *                          'doctype'  => "XHTML 1.0 Strict",
78  *
79  *                          // Global page language setting
80  *                          'language' => 'en',
81  *
82  *                          // If cache is set to true, the browser may
83  *                          // cache the output. Else 
84  *                          'cache'    => 'false'
85  *                          ));
86  *
87  * // Here we go
88  *
89  * // Set the page title
90  * $p->setTitle("My page");
91  * 
92  * // Add optional meta data
93  * $p->addMetaData("author", "My Name");
94  * 
95  * // Put something into the body
96  * $p->addBodyContent = "<p>some text</p>";
97  *
98  * // If at some point you want to clear the page content
99  * // and output an error message, you can easily do that
100  * // See the source for {@link toHtml} and {@link _getDoctype}
101  * // for more details
102  * if ($error) {
103  *     $p->setTitle("Error!");
104  *     $p->setBodyContent("<p>Houston, we have a problem: $error</p>");
105  *     $p->display();
106  *     die;
107  * } // end error handling
108  *
109  * // print to browser
110  * $p->display();
111  * </code>
112  * 
113  * Simple XHTML declaration example:
114  * <code>
115  * $p = new HTML_Page();
116  * // An XHTML compliant page (with title) is automatically generated
117  *
118  * // This overrides the XHTML 1.0 Transitional default
119  * $p->setDoctype('XHTML 1.0 Strict');
120  * 
121  * // Put some content in here
122  * $p->addBodyContent("<p>some text</p>");
123  *
124  * // print to browser
125  * $p->display();
126  * </code>
127  * 
128  *
129  * HTML examples:
130  * --------------
131  *
132  * HTML 4.01 example:
133  * ------------------
134  * <code>
135  * $p = new HTML_Page('doctype="HTML 4.01 Strict"');
136  * $p->addBodyContent = "<p>some text</p>";
137  * $p->display();
138  * </code>
139  * 
140  * nuke doctype declaration:
141  * -------------------------
142  * <code>
143  * $p = new HTML_Page('doctype="none"');
144  * $p->addBodyContent = "<p>some text</p>";
145  * $p->display();
146  * </code>
147  * 
148  * @author       Adam Daniel <adaniel1@eesus.jnj.com>
149  * @author       Klaus Guenther <klaus@capitalfocus.org>
150  * @version      2.0
151  * @since        PHP 4.0.3pl1
152  */
153 class HTML_Page extends HTML_Common {
154     
155     /**
156      * Contains the content of the &lt;body&gt; tag.
157      * 
158      * @var     array
159      * @access  private
160      */
161     var $_body = array();
162     
163     /**
164      * Controls caching of the page
165      * 
166      * @var     bool
167      * @access  private
168      */
169     var $_cache = false;
170     
171     /**
172      * Contains the character encoding string
173      * 
174      * @var     string
175      * @access  private
176      */
177     var $_charset = 'utf-8';
178     
179     /**
180      * Contains the !DOCTYPE definition
181      * 
182      * @var array
183      * @access private
184      */
185     var $_doctype = array('type'=>'xhtml','version'=>'1.0','variant'=>'transitional');
186     
187     /**
188      * Contains the page language setting
189      * 
190      * @var     string
191      * @access  private
192      */
193     var $_language = 'en';
194     
195     /**
196      * Array of meta tags
197      * 
198      * @var     array
199      * @access  private
200      */
201     var $_metaTags = array( 'standard' => array ( 'Generator' => 'PEAR HTML_Page' ) );
202     
203     /**
204      * Document mime type
205      * 
206      * @var  string
207      * @access   private
208      */
209     var $_mime = 'text/html';
210     
211     /**
212      * Document namespace
213      * 
214      * @var  string
215      * @access   private
216      */
217     var $_namespace = '';
218     
219     /**
220      * Array of linked scripts
221      * 
222      * @var  array
223      * @access   private
224      */
225     var $_scripts = array();
226     
227     /**
228      * Array of scripts placed in the header
229      * 
230      * @var  array
231      * @access   private
232      */
233     var $_script = array();
234     
235     /**
236      * Array of linked scripts
237      * 
238      * @var     array
239      * @access  private
240      */
241     var $_simple = false;
242     
243     /**
244      * Array of included style declarations
245      * 
246      * @var     array
247      * @access  private
248      */
249     var $_style = array();
250     
251     /**
252      * Array of linked style sheets
253      * 
254      * @var     array
255      * @access  private
256      */
257     var $_styleSheets = array();
258     
259     /**
260      * HTML page title
261      * 
262      * @var     string
263      * @access  private
264      */
265     var $_title = '';
266     
267     /**
268      * Class constructor
269      * Possible attributes are:
270      * - general options:
271      *     - "lineend" => "unix|win|mac" (Sets line ending style; defaults to unix.)
272      *     - "tab"     => string (Sets line ending style; defaults to \t.)
273      *     - "cache"   => "false|true"
274      *     - "charset" => charset string (Sets charset encoding; defaults to utf-8)
275      *     - "mime"    => mime encoding string (Sets document mime type; defaults to text/html)
276      * - XHTML specific:
277      *     - "doctype"  => string (Sets XHTML doctype; defaults to XHTML 1.0 Transitional.)
278      *     - "language" => two letter language designation. (Defines global document language; defaults to "en".)
279      *     - "namespace"  => string (Sets document namespace; defaults to the W3C defined namespace.)
280      * 
281      * @param   mixed   $attributes     Associative array of table tag attributes
282      *                                  or HTML attributes name="value" pairs
283      * @access  public
284      */
285     function HTML_Page($attributes = array())
286     {
287         $commonVersion = 1.7;
288         if (HTML_Common::apiVersion() < $commonVersion) {
289             return PEAR::raiseError("HTML_Page version " . $this->apiVersion() . " requires " .
290                 "HTML_Common version 1.2 or greater.", 0, PEAR_ERROR_TRIGGER);
291         }
292         
293         if ($attributes) {
294             $attributes = $this->_parseAttributes($attributes);
295         }
296         
297         if (isset($attributes['lineend'])) {
298             $this->setLineEnd($attributes['lineend']);
299         }
300         
301         if (isset($attributes['charset'])) {
302             $this->setCharset($attributes['charset']);
303         }
304         
305         if (isset($attributes['doctype'])){
306             if ($attributes['doctype'] == 'none') {
307                 $this->_simple = true;
308             } elseif ($attributes['doctype']) {
309                 $this->setDoctype($attributes['doctype']);
310             }
311         }
312         
313         if (isset($attributes['language'])) {
314             $this->setLang($attributes['language']);
315         }
316         
317         if (isset($attributes['mime'])) {
318             $this->setMimeEncoding($attributes['mime']);
319         }
320         
321         if (isset($attributes['namespace'])) {
322             $this->setNamespace($attributes['namespace']);
323         }
324         
325         if (isset($attributes['tab'])) {
326             $this->setTab($attributes['tab']);
327         }
328         
329         if (isset($attributes['cache'])) {
330             $this->setCache($attributes['cache']);
331         }
332         
333     }
334     
335     /**
336      * Generates the HTML string for the &lt;body&lt; tag
337      * 
338      * @access  private
339      * @return  string
340      */
341     function _generateBody()
342     {
343         
344         // get line endings
345         $lnEnd = $this->_getLineEnd();
346         $tab = $this->_getTab();
347         
348         // If body attributes exist, add them to the body tag.
349         // Depreciated because of CSS
350         $strAttr = $this->_getAttrString($this->_attributes);
351         
352         if ($strAttr) {
353             $strHtml = "<body $strAttr>" . $lnEnd;
354         } else {
355             $strHtml = '<body>' . $lnEnd;
356         }
357         
358         // Allow for mixed content in the body array
359         // Iterate through the array and process each element
360         foreach ($this->_body as $element) {
361             if (is_object($element)) {
362                 if (is_subclass_of($element, "html_common")) {
363                     $element->setTab($tab);
364                     $element->setTabOffset(1);
365                     $element->setLineEnd($lnEnd);
366                 }
367                 if (method_exists($element, "toHtml")) {
368                     $strHtml .= $element->toHtml() . $lnEnd;
369                 } elseif (method_exists($element, "toString")) {
370                     $strHtml .= $element->toString() . $lnEnd;
371                 }
372             } elseif (is_array($element)) {
373                 foreach ($element as $level2) {
374                     if (is_subclass_of($level2, "html_common")) {
375                         $level2->setTabOffset(1);
376                         $level2->setTab($tab);
377                         $level2->setLineEnd($lnEnd);
378                     }
379                     if (is_object($level2)) {
380                         if (method_exists($level2, "toHtml")) {
381                             $strHtml .= $level2->toHtml() . $lnEnd;
382                         } elseif (method_exists($level2, "toString")) {
383                             $strHtml .= $level2->toString() . $lnEnd;
384                         }
385                     } else {
386                         $strHtml .= $tab . $level2 . $lnEnd;
387                     }
388                 }
389             } else {
390                 $strHtml .= $tab . $element . $lnEnd;
391             }
392         }
393         
394         // Close tag
395         $strHtml .= '</body>' . $lnEnd;
396         
397         // Let's roll!
398         return $strHtml;
399     } // end func _generateHead
400     
401     /**
402      * Generates the HTML string for the &lt;head&lt; tag
403      * 
404      * @return string
405      * @access private
406      */
407     function _generateHead()
408     {
409         // close empty tags if XHTML
410         if ($this->_doctype['type'] == 'html'){
411             $tagEnd = '>';
412         } else {
413             $tagEnd = ' />';
414         }
415         
416         // get line endings
417         $lnEnd = $this->_getLineEnd();
418         $tab = $this->_getTab();
419         
420         $strHtml  = '<head>' . $lnEnd;
421         $strHtml .= $tab . '<title>' . $this->getTitle() . '</title>' . $lnEnd;
422         
423         // Generate META tags
424         foreach ($this->_metaTags as $type => $tag) {
425             foreach ($tag as $name => $content) {
426                 if ($type == 'http-equiv') {
427                     $strHtml .= $tab . "<meta http-equiv=\"$name\" content=\"$content\"" . $tagEnd . $lnEnd;
428                 } elseif ($type == 'standard') {
429                     $strHtml .= $tab . "<meta name=\"$name\" content=\"$content\"" . $tagEnd . $lnEnd;
430                 }
431             }
432         }
433         
434         // Generate stylesheet links
435         foreach ($this->_styleSheets as $strStyleSheet) {
436             $strHtml .= $tab . "<link rel=\"stylesheet\" href=\"$strStyleSheet\" type=\"text/css\"" . $tagEnd . $lnEnd;
437         }
438         
439         // Generate stylesheet declarations
440         foreach ($this->_style as $type => $content) {
441             $strHtml .= $tab . '<style type="' . $type . '">' . $lnEnd;
442             
443             // This is for full XHTML supporte.
444             if ($this->_mime == 'text/html' ) {
445                 $strHtml .= $tab . $tab . '<!--' . $lnEnd;
446             } else {
447                 $strHtml .= $tab . $tab . '<![CDATA[' . $lnEnd;
448             }
449             
450             if (is_object($content)) {
451                 
452                 // first let's propagate line endings and tabs for other HTML_Common-based objects
453                 if (is_subclass_of($content, "html_common")) {
454                     $content->setTab($tab);
455                     $content->setTabOffset(3);
456                     $content->setLineEnd($lnEnd);
457                 }
458                 
459                 // now let's get a string from the object
460                 if (method_exists($content, "toString")) {
461                     $strHtml .= $content->toString() . $lnEnd;
462                 } else {
463                     return PEAR::raiseError('Error: Style content object does not support  method toString().',
464                     0,PEAR_ERROR_TRIGGER);
465                 }
466                 
467             } else {
468                 $strHtml .= $content . $lnEnd;
469             }
470             
471             // See above note
472             
473             if ($this->_mime == 'text/html' ) {
474                 $strHtml .= $tab . $tab . '-->' . $lnEnd;
475             } else {
476                 $strHtml .= $tab . $tab . ']]>' . $lnEnd;
477             }
478             $strHtml .= $tab . '</style>' . $lnEnd;
479         }
480         
481         // Generate script file links
482         foreach ($this->_scripts as $strSrc => $strType) {
483             $strHtml .= $tab . "<script type=\"$strType\" src=\"$strSrc\"></script>" . $lnEnd;
484         }
485         
486         // Generate script declarations
487         foreach ($this->_script as $type => $content) {
488             $strHtml .= $tab . '<script type="' . $type . '">' . $lnEnd;
489             
490             // This is for full XHTML support.
491             if ($this->_mime == 'text/html' ) {
492                 $strHtml .= $tab . $tab . '<!--' . $lnEnd;
493             } else {
494                 $strHtml .= $tab . $tab . '<![CDATA[' . $lnEnd;
495             }
496             
497             if (is_object($content)) {
498                 
499                 // first let's propagate line endings and tabs for other HTML_Common-based objects
500                 if (is_subclass_of($content, "html_common")) {
501                     $content->setTab($tab);
502                     $content->setTabOffset(3);
503                     $content->setLineEnd($lnEnd);
504                 }
505                 
506                 // now let's get a string from the object
507                 if (method_exists($content, "toString")) {
508                     $strHtml .= $content->toString() . $lnEnd;
509                 } else {
510                     return PEAR::raiseError('Error: Script content object does not support  method toString().',
511                     0,PEAR_ERROR_TRIGGER);
512                 }
513                 
514             } else {
515                 $strHtml .= $content . $lnEnd;
516             }
517             
518             // See above note
519             if ($this->_mime == 'text/html' ) {
520                 $strHtml .= $tab . $tab . '-->' . $lnEnd;
521             } else {
522                 $strHtml .= $tab . $tab . ']]>' . $lnEnd;
523             }
524             $strHtml .= $tab . '</script>' . $lnEnd;
525         }
526         
527         // Close tag
528         $strHtml .=  '</head>' . $lnEnd;
529         
530         // Let's roll!
531         return $strHtml;
532     } // end func _generateHead
533     
534     /**
535      * Returns the doctype declaration
536      *
537      * @return mixed
538      * @access private
539      */
540     function _getDoctype()
541     {
542         require('HTML/Page/Doctypes.php');
543         
544         if (isset($this->_doctype['type'])) {
545             $type = $this->_doctype['type'];
546         }
547         
548         if (isset($this->_doctype['version'])) {
549             $version = $this->_doctype['version'];
550         }
551         
552         if (isset($this->_doctype['variant'])) {
553             $variant = $this->_doctype['variant'];
554         }
555         
556         $strDoctype = '';
557         
558         if (isset($variant)) {
559             if (isset($doctype[$type][$version][$variant][0])) {
560                 foreach ( $doctype[$type][$version][$variant] as $string) {
561                     $strDoctype .= $string.$this->_getLineEnd();
562                 }
563             }
564         } elseif (isset($version)) {
565             if (isset($doctype[$type][$version][0])) {
566                 foreach ( $doctype[$type][$version] as $string) {
567                     $strDoctype .= $string.$this->_getLineEnd();
568                 }
569             } else {
570                 if (isset($default[$type][$version][0])) {
571                     $this->_doctype = $this->_parseDoctypeString($default[$type][$version][0]);
572                     $strDoctype = $this->_getDoctype();
573                 }
574             }
575         } elseif (isset($type)) {
576             if (isset($default[$type][0])){
577                 $this->_doctype = $this->_parseDoctypeString($default[$type][0]);
578                 $strDoctype = $this->_getDoctype();
579             }
580         } else {
581             $this->_doctype = $this->_parseDoctypeString($default['default'][0]);
582             $strDoctype = $this->_getDoctype();
583         }
584         
585         if ($strDoctype) {
586             return $strDoctype;
587         } else {
588             return PEAR::raiseError('Error: "'.$this->getDoctypeString().'" is an unsupported or illegal document type.',
589                                     0,PEAR_ERROR_TRIGGER);
590         }
591         
592     } // end func _getDoctype
593     
594     /**
595      * Retrieves the document namespace
596      *
597      * @return mixed
598      * @access private
599      */
600     function _getNamespace()
601     {
602         require('HTML/Page/Namespaces.php');
603         
604         if (isset($this->_doctype['type'])) {
605             $type = $this->_doctype['type'];
606         }
607         
608         if (isset($this->_doctype['version'])) {
609             $version = $this->_doctype['version'];
610         }
611         
612         if (isset($this->_doctype['variant'])) {
613             $variant = $this->_doctype['variant'];
614         }
615         
616         $strNamespace = '';
617         
618         if (isset($variant)){
619             if (isset($namespace[$type][$version][$variant][0]) && is_string($namespace[$type][$version][$variant][0])) {
620                 $strNamespace = $namespace[$type][$version][$variant][0];
621             } elseif (isset($namespace[$type][$version][0]) && is_string($namespace[$type][$version][0]) ) {
622                 $strNamespace = $namespace[$type][$version][0];
623             } elseif (isset($namespace[$type][0]) && is_string($namespace[$type][0]) ) {
624                 $strNamespace = $namespace[$type][0];
625             }
626         } elseif (isset($version)) {
627             if (isset($namespace[$type][$version][0]) && is_string($namespace[$type][$version][0]) ) {
628                 $strNamespace = $namespace[$type][$version][0];
629             } elseif (isset($namespace[$type][0]) && is_string($namespace[$type][0]) ) {
630                 $strNamespace = $namespace[$type][0];
631             }
632         } else {
633             if (isset($namespace[$type][0]) && is_string($namespace[$type][0]) ) {
634                 $strNamespace = $namespace[$type][0];
635             }
636         }
637             
638         
639         if ($strNamespace) {
640             return $strNamespace;
641         } else {
642             return PEAR::raiseError('Error: "'.$this->getDoctypeString().'" does not have a default namespace. Use setNamespace() to define your namespace.',
643                                     0,PEAR_ERROR_TRIGGER);
644         }
645         
646     } // end func _getNamespace
647     
648     /**
649      * Parses a doctype declaration like "XHTML 1.0 Strict" to an array
650      *
651      * @param   string  $string     The string to be parsed
652      * @return string
653      * @access private
654      */
655     function _parseDoctypeString($string)
656     {
657         $split = explode(' ',strtolower($string));
658         $elements = count($split);
659         
660         if (isset($split[2])){
661             $array = array('type'=>$split[0],'version'=>$split[1],'variant'=>$split[2]);
662         } elseif (isset($split[1])){
663             $array = array('type'=>$split[0],'version'=>$split[1]);
664         } else {
665             $array = array('type'=>$split[0]);
666         }
667         
668         return $array;
669     } // end func _parseDoctypeString
670     
671     /**
672      * Sets the content of the &lt;body&gt; tag. If content already exists,
673      * the new content is appended.
674      * If you wish to overwrite whatever is in the body, use {@link setBody};
675      * {@link unsetBody} completely empties the body without inserting new content.
676      * It is possible to add objects, strings or an array of strings and/or objects
677      * Objects must have a toString method.
678      * 
679      * @param mixed $content  New &lt;body&gt; tag content (may be passed as a reference)
680      * @access public
681      */
682     function addBodyContent($content)
683     {
684         $this->_body[] =& $content;
685         if (is_object($content)) {
686             if (method_exists($content, "toStyleSheet")) {
687                 $this->addStyleSheet($content->toStyleSheet());
688             }
689             if (method_exists($content, "toScript")) {
690                                 $script = $content->toScript();
691                                 if (is_array($script)) {
692                                         $this->addScript($script[0], $script[1]);
693                                 } else {
694                                         $this->addScript($script);
695                                 }
696             }
697         } elseif (is_array($content)) {
698                         foreach ($content as $element) {
699                         if (is_object($content)) {
700                                         if (method_exists($element, "toStyleSheet")) {
701                                                 $this->addStyleSheet($element->toStyleSheet());
702                                         }
703                                         if (method_exists($element, "toScript")) {
704                                                 $script = $element->toScript();
705                                                 if (is_array($script)) {
706                                                         $this->addScript($script[0], $script[1]);
707                                                 } else {
708                                                         $this->addScript($script);
709                                                 }
710                                         }
711                                 }
712                         }
713                 }
714     } // end addBodyContent    
715     
716     /**
717      * Adds a linked script to the page
718      * 
719      * @param    string  $url        URL to the linked script
720      * @param    string  $type       Type of script. Defaults to 'text/javascript'
721      * @access   public
722      */
723     function addScript($url, $type="text/javascript")
724     {
725         $this->_scripts[$url] = $type;
726     } // end func addScript
727     
728     /**
729      * Adds a script to the page.
730      * Content can be a string or an object with a toString method.
731      * Defaults to text/javascript.
732      * 
733      * @access   public
734      * @param    mixed   $content   Script (may be passed as a reference)
735      * @param    string  $type      Scripting mime (defaults to 'text/javascript')
736      * @return   void
737      */
738     function addScriptDeclaration($content, $type = 'text/javascript')
739     {
740         $this->_script[strtolower($type)] =& $content;
741     } // end func addScriptDeclaration
742     
743     /**
744      * Adds a linked stylesheet to the page
745      * 
746      * @param    string  $url    URL to the linked style sheet
747      * @access   public
748      * @return   void
749      */
750     function addStyleSheet($url)
751     {
752         $this->_styleSheets[$url] = $url;
753     } // end func addStyleSheet
754     
755     /**
756      * Adds a stylesheet declaration to the page.
757      * Content can be a string or an object with a toString method.
758      * Defaults to text/css.
759      * 
760      * @access   public
761      * @param    mixed   $content   Style declarations (may be passed as a reference)
762      * @param    string  $type      Type of stylesheet (defaults to 'text/css')
763      * @return   void
764      */
765     function addStyleDeclaration($content, $type = 'text/css')
766     {
767         $this->_style[strtolower($type)] =& $content;
768     } // end func addStyleDeclaration
769     
770     /**
771      * Returns the current API version
772      * 
773      * @access   public
774      * @returns  double
775      */
776     function apiVersion()
777     {
778         return 2.0;
779     } // end func apiVersion
780     
781     /**
782      * Returns the document charset encoding.
783      * 
784      * @access public
785      * @returns string
786      */
787     function getCharset()
788     {
789         return $this->_charset;
790     } // end setCache
791     
792     /**
793      * Returns the document type string
794      *
795      * @access private
796      * @return string
797      */
798     function getDoctypeString()
799     {
800         $strDoctype = strtoupper($this->_doctype['type']);
801         $strDoctype .= ' '.ucfirst(strtolower($this->_doctype['version']));
802         if ($this->_doctype['variant']) {
803             $strDoctype .= ' ' . ucfirst(strtolower($this->_doctype['variant']));
804         }
805         return trim($strDoctype);
806     } // end func getDoctypeString
807     
808     /**
809      * Returns the document language.
810      * 
811      * @return string
812      * @access public
813      */
814     function getLang ()
815     {
816         return $this->_language;
817     } // end func getLang
818     
819     /**
820      * Return the title of the page.
821      * 
822      * @returns  string
823      * @access   public
824      */
825     function getTitle()
826     {
827         if (!$this->_title){
828             if ($this->_simple) {
829                 return 'New Page';
830             } else {
831                 return 'New '. $this->getDoctypeString() . ' Compliant Page';
832             }
833         } else {
834             return $this->_title;
835         }
836     } // end func getTitle
837     
838     /**
839      * Sets the content of the &lt;body&gt; tag. If content exists, it is overwritten.
840      * If you wish to use a "safe" version, use {@link addBodyContent}
841      * Objects must have a toString method.
842      * 
843      * @param mixed $content New &lt;body&gt; tag content. May be an object. (may be passed as a reference)
844      * @access public
845      */
846     function setBody($content)
847     {
848         $this->unsetBody();
849         $this->addBodyContent($content);
850     } // end setBody
851     
852     /**
853      * Unsets the content of the &lt;body&gt; tag.
854      * 
855      * @access public
856      */
857     function unsetBody()
858     {
859         $this->_body = '';
860     } // end unsetBody
861         
862     /**
863      * Defines if the document should be cached by the browser. Defaults to false.
864      * 
865      * @param string $cache Options are currently 'true' or 'false'. Defaults to 'false'.
866      * @access public
867      */
868     function setCache($cache = 'false')
869     {
870         if ($cache == 'true'){
871             $this->_cache = true;
872         } else {
873             $this->_cache = false;
874         }
875     } // end setCache
876     
877     /**
878      * Defines if the document should be cached by the browser. Defaults to false.
879      * 
880      * @param string $cache Options are currently 'true' or 'false'. Defaults to 'false'.
881      * @access public
882      * @returns void
883      */
884     function setCharset($type = 'utf-8')
885     {
886         $this->_charset = $type;
887     } // end setCache
888     
889     /**
890      * Sets or alters the XHTML !DOCTYPE declaration. Can be set to "strict",
891      * "transitional" or "frameset". Defaults to "transitional". This must come
892      * _after_ declaring the character encoding with {@link setCharset} or directly
893      * when the class is initiated {@link HTML_Page}.
894      * 
895      * @param string $type   String containing a document type. Defaults to "XHTML 1.0 Transitional"
896      * @access public
897      * @returns void
898      */
899     function setDoctype($type = "XHTML 1.0 Transitional")
900     {
901         $this->_doctype = $this->_parseDoctypeString($type);
902     } // end func setDoctype
903     
904     /**
905      * Sets the global document language declaration. Default is English.
906      * 
907      * @access public
908      * @param string $lang Two-letter language designation.
909      */
910     function setLang($lang = "en")
911     {
912         $this->_language = strtolower($lang);
913     } // end setLang
914     
915     /**
916      * Sets or alters a meta tag.
917      * 
918      * @param string  $name     Value of name or http-equiv tag
919      * @param string  $content  Value of the content tag
920      * @param bool    $http_equiv     META type "http-equiv" defaults to NULL
921      * @return void
922      * @access public
923      */
924     function setMetaData($name, $content, $http_equiv = false)
925     {
926         if ($http_equiv == true) {
927             $this->_metaTags['http-equiv'][$name] = $content;
928         } else {
929             $this->_metaTags['standard'][$name] = $content;
930         }
931     } // end func setMetaData
932     
933     /**
934      * Sets an http-equiv Content-Type meta tag
935      * 
936      * @access   public
937      * @returns  void
938      */
939     function setMetaContentType()
940     {
941         $this->setMetaData('Content-Type', $this->_mime . '; charset=' . $this->_charset , true );
942     } // end func setMetaContentType
943     
944     /**
945      * Easily sets or alters a refresh meta tag. 
946      * If no $url is passed, "self" is presupposed, and the appropriate URL
947      * will be automatically generated.
948      * 
949      * @param string  $time    Time till refresh (in seconds)
950      * @param string  $url     Absolute URL or "self"
951      * @param bool    $https   If $url = self, this allows for the https protocol defaults to NULL
952      * @return void
953      * @access public
954      */
955     function setMetaRefresh($time, $url = 'self', $https = false)
956     {
957         if ($url == 'self') {
958             if ($https) { 
959                 $protocol = 'https://';
960             } else {
961                 $protocol = 'http://';
962             }
963             $url = $protocol . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
964         }
965         $this->setMetaData("Refresh", "$time; url=$url", true);
966     } // end func setMetaRefresh
967     
968     /**
969      * Sets the document MIME encoding that is sent to the browser.
970      * 
971      * @param    string    $type
972      * @access   public
973      * @returns  void
974      */
975     function setMimeEncoding($type = 'text/html')
976     {
977         $this->_mime = strtolower($type);
978     } // end func setMimeEncoding
979     
980     /**
981      * Sets the document namespace
982      * 
983      * @param    string    $namespace  Optional. W3C namespaces are used by default.
984      * @access   public
985      * @returns  void
986      */
987     function setNamespace($namespace = '')
988     {
989         if (isset($namespace)){
990             $this->_namespace = $namespace;
991         } else {
992             $this->_namespace = $this->_getNamespace();
993         }
994     } // end func setTitle
995     
996     /**
997      * Sets the title of the page
998      * 
999      * @param    string    $title
1000      * @access   public
1001      * @returns  void
1002      */
1003     function setTitle($title)
1004     {
1005         $this->_title = $title;
1006     } // end func setTitle
1007     
1008     /**
1009      * Generates and returns the complete page as a string.
1010      * 
1011      * @return string
1012      * @access private
1013      */
1014     function toHTML()
1015     {
1016         
1017         // get line endings
1018         $lnEnd = $this->_getLineEnd();
1019         
1020         // get the doctype declaration
1021         $strDoctype = $this->_getDoctype();
1022         
1023         // This determines how the doctype is declared
1024         if ($this->_simple) {
1025             
1026             $strHtml = '<html>' . $lnEnd;
1027             
1028         } elseif ($this->_doctype['type'] == 'xhtml') {
1029             
1030             // get the namespace if not already set
1031             if (!$this->_namespace){
1032                 $this->_namespace = $this->_getNamespace();
1033             }
1034             
1035             $strHtml  = '<?xml version="1.0" encoding="' . $this->_charset . '"?>' . $lnEnd;
1036             $strHtml .= $strDoctype . $lnEnd;
1037             $strHtml .= '<html xmlns="' . $this->_namespace . '" xml:lang="' . $this->_language . '">' . $lnEnd;
1038             
1039         } else {
1040             
1041             $strHtml  = $strDoctype . $lnEnd;
1042             $strHtml .= '<html>' . $lnEnd;
1043             
1044         }
1045
1046         $strHtml .= $this->_generateHead();
1047         $strHtml .= $this->_generateBody();
1048         $strHtml .= '</html>';
1049         return $strHtml;
1050     } // end func toHtml
1051
1052     /**
1053      * Outputs the HTML content to the screen.
1054      * 
1055      * @access    public
1056      */
1057     function display()
1058     {
1059         if(! $this->_cache) {
1060             header("Expires: Tue, 1 Jan 1980 12:00:00 GMT");
1061             header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
1062             header("Cache-Control: no-cache");
1063             header("Pragma: no-cache");
1064         }
1065         
1066         // set character encoding
1067         header('Content-Type: ' . $this->_mime .  '; charset=' . $this->_charset);
1068         
1069         $strHtml = $this->toHTML();
1070         print $strHtml;
1071     } // end func display
1072     
1073 }
1074 ?>