<?php
// vim: set expandtab tabstop=4 softtabstop=4 shiftwidth=4:
// +--------------------------------------------------------------------+
-// | BIFE - Buil It Fast & Easy |
+// | BIFE - Buil It FastEr |
// +--------------------------------------------------------------------+
// | This file is part of BIFE. |
// | |
// | along with Hooks; if not, write to the Free Software Foundation, |
// | Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
// +--------------------------------------------------------------------+
-// | Created: @date
-// | Authors: @author
+// | Created: Wed May 17 18:16:54 ART 2003 |
+// | Authors: Leandro Lucarella <luca@lugmen.org.ar> |
// +--------------------------------------------------------------------+
//
// $Id$
*/
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
/**
* 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
/**
* 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');
*/
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
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
// +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));
}
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