X-Git-Url: https://git.llucax.com/software/bife/bife-all.git/blobdiff_plain/db685c4492b0985544eb54e959278dec2b68142b..refs/heads/master:/BIFE/Parser.php?ds=sidebyside diff --git a/BIFE/Parser.php b/BIFE/Parser.php index a084a4e..76a5845 100644 --- a/BIFE/Parser.php +++ b/BIFE/Parser.php @@ -34,36 +34,52 @@ */ 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