]> git.llucax.com Git - software/bife/bife-all.git/blobdiff - BIFE/Parser.php
Base package is splited (again), so BIFE no longer depends on
[software/bife/bife-all.git] / BIFE / Parser.php
index a084a4e0ab605702cd4598291e51c543526c2aaf..76a58459a04e3b57b36a34b826eac71fbad8158e 100644 (file)
  */
 class BIFE_Parser {
     /**
-     * Output string.
+     * Top level widget.
      *
-     * @var    string $output
-     * @access public
+     * @var    BIFE_Widget $root
+     * @access protected
      */
-    var $output;
+    var $root = null;
 
     /**
      * XML parser resource.
      *
      * @var    resource $parser
-     * @access public
+     * @access protected
      */
-    var $parser;
+    var $parser = null;
 
     /**
-     * Template to use to render the parsed file.
+     * BIFE widgets stack.
      *
-     * @var    HTML_Template_Sigma $template
-     * @access public
+     * @var    array $stack
+     * @access protected
      */
-    var $template;
+    var $stack = array();
 
     /**
-     * BIFE widgets stack.
+     * Fallback class to use in case that a widget class is not found.
      *
-     * @var    array $stack
-     * @access public
+     * @var    string $fallback
+     * @access protected
+     */
+    var $fallback = '';
+
+    /**
+     * XML cache directory. Empty if no cahching must be done (for current dir use '.').
+     *
+     * @var    string $cache
+     * @access protected
      */
-    var $stack;
+    var $cache = '/tmp';
+
+    /**
+     * Files required by the parsed XML file.
+     *
+     * @var    array $requires
+     * @access protected
+     */
+    var $requires = array();
 
     // ~X2C
 
@@ -71,14 +87,15 @@ class BIFE_Parser {
     /**
      * Constructor.
      *
-     * @param  HTML_Template_Sigma &$template Template to use to render the widgets.
+     * @param  string $fallback Fallback class name (none if empty).
+     * @param  string $cache XML cache directory. Empty is no caching will be done.
      *
      * @return void
      * @access public
      */
-    function BIFE_Parser(&$template) // ~X2C
+    function BIFE_Parser($fallback = '', $cache = '/tmp') // ~X2C
     {
-        $this->__construct($template);
+        $this->__construct($fallback, $cache);
     }
     // -X2C
 
@@ -86,17 +103,17 @@ class BIFE_Parser {
     /**
      * Constructor.
      *
-     * @param  HTML_Template_Sigma &$template Template to use to render the widgets.
+     * @param  string $fallback Fallback class name (none if empty).
+     * @param  string $cache XML cache directory. Empty is no caching will be done.
      *
      * @return void
      * @access public
      */
-    function __construct(&$template) // ~X2C
+    function __construct($fallback = '', $cache = '/tmp') // ~X2C
     {
-        $this->stack    = array();
-        $this->output   = '';
         $this->parser   = xml_parser_create();
-        $this->template =& $template;
+        $this->fallback = $fallback;
+        $this->cache    = $cache;
         xml_set_object($this->parser, $this);
         xml_set_element_handler($this->parser, 'startElement', 'endElement');
         xml_set_character_data_handler($this->parser, 'characterData');
@@ -129,18 +146,33 @@ class BIFE_Parser {
      */
     function startElement($parser, $name, $attrs) // ~X2C
     {
-        $class = "BIFE_$name";
+        $class = 'bife_' . strtolower(strtr($name, ':', '_'));
         if (!class_exists($class)) {
-            include_once 'BIFE/' . ucfirst(strtolower($name)) . '.php';
+            $inc = 'BIFE/' .
+                strtr(ucwords(strtr(strtolower($name), ':', ' ')), ' ', '/') .
+                '.php';
+            if (@include_once $inc) {
+                $this->includes[] = $inc;
+            }
         }
         if (class_exists($class)) {
             $obj =& new $class($attrs);
+            // XXX - Does this check make sense?
             if (!is_a($obj, 'bife_widget')) {
                 trigger_error("Class '$class' is not a BIFE_Widget.", E_USER_WARNING);
             }
             $this->stack[] =& $obj;
         } else {
-            trigger_error("Class not found '$class'.", E_USER_ERROR);
+            if ($this->fallback) {
+                $class = $this->fallback;
+                $obj =& new $class($name, $attrs);
+                if (!is_a($obj, 'bife_fallback')) {
+                    trigger_error("Class '$class' is not a BIFE_Fallback.", E_USER_WARNING);
+                }
+                $this->stack[] =& $obj;
+            } else {
+                trigger_error("Class not found '$class'.", E_USER_ERROR);
+            }
         }
     }
     // -X2C
@@ -163,9 +195,9 @@ class BIFE_Parser {
         end($this->stack);
         $parent =& $this->stack[key($this->stack)];
         if ($parent) {
-            $parent->addContents($current->render($this->template));
+            $parent->addContents($current);
         } else {
-            $this->output = $current->render($this->template);
+            $this->root =& $current;
         }
     }
     // -X2C
@@ -214,16 +246,26 @@ class BIFE_Parser {
 
     // +X2C Operation 37
     /**
-     * Parse a XML file returning the rendered output.
+     * Parse a XML file with a complete and valid XML document.
      *
      * @param  string $filename Filename to parse.
      *
-     * @return void
+     * @return &BIFE_Widget
      * @access public
      */
-    function parseFile($filename) // ~X2C
+    function &parseFile($filename) // ~X2C
     {
-        if ($fp = @fopen($filename, "r")) {
+        if ($this->cache) {
+            $cache = $this->cache . '/' . 'bife_parser_cache' . strtr(realpath($filename), '/', '_');
+            if (@filemtime($cache) > @filemtime($filename)) {
+                $file = file($cache);
+                foreach(unserialize(trim(array_shift($file))) as $required) {
+                    include_once $required;
+                }
+                return unserialize(join('', $file));
+            }
+        }
+        if ($fp = @fopen($filename, 'r')) {
             while ($data = fread($fp, 4096)) {
                 $this->parse($data, feof($fp));
             }
@@ -232,22 +274,32 @@ class BIFE_Parser {
                 E_USER_WARNING);
         }
         fclose($fp);
+        if ($this->cache) {
+            $fp = fopen($cache, 'w');
+            fputs($fp, serialize($this->includes) . "\n");
+            fputs($fp, serialize($this->root));
+            fclose($fp);
+        }
+        return $this->root;
     }
     // -X2C
 
-    // +X2C Operation 38
+    // +X2C Operation 74
     /**
-     * Get rendered output.
+     * Parse a XML string with a complete and valid XML document.
+     *
+     * @param  string $data XML data to parse.
      *
-     * @return string
+     * @return &BIFE_Widget
      * @access public
      */
-    function getOutput() // ~X2C
+    function &parseString($data) // ~X2C
     {
-        return $this->output;
+        $this->parse($data, true);
+        return $this->root;
     }
     // -X2C
 
 } // -X2C Class :Parser
 
-?>
+?>
\ No newline at end of file