read and parse widgets on serverside

This commit is contained in:
Ralf Becker 2011-08-18 18:08:40 +00:00
parent 5e54d6b12b
commit d095250d85
2 changed files with 308 additions and 0 deletions

View File

@ -0,0 +1,112 @@
<?php
/**
* EGroupware - eTemplate serverside template widget
*
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
* @package etemplate
* @subpackage api
* @link http://www.egroupware.org
* @author Ralf Becker <RalfBecker@outdoor-training.de>
* @copyright 2002-11 by RalfBecker@outdoor-training.de
* @version $Id$
*/
/* testwise to have autoloading
if (!isset($GLOBALS['egw_info']))
{
$GLOBALS['egw_info'] = array(
'flags' => array(
'currentapp' => 'login',
),
);
include_once '../../header.inc.php';
}
*/
/**
* eTemplate widget baseclass
*/
class etemplate_template_widget extends etemplate_widget
{
/**
* Cache of already read templates
*
* @var array with name => template pairs
*/
protected static $cache = array();
/**
* Read a templates specified by name, template(-set) and version
*
* @param string $name
* @param string $template_set='default'
* @param string $version=''
* @param string $load_via='' use given template to load $name
* @todo Reading customized templates from database
* @return etemplate_template_widget|boolean false if not found
*/
public static function read($name, $template_set='default', $version='', $load_via='')
{
$start = microtime(true);
if (isset(self::$cache[$name]) || !($path = self::relPath($name, $template_set, $version)))
{
if ((!$path || self::read($load_via, $template_set)) && isset(self::$cache[$name]))
{
error_log(__METHOD__."('$name', '$template_set', '$version', '$load_via') read from cache");
return self::$cache[$name];
}
error_log(__METHOD__."('$name', '$template_set', '$version', '$load_via') template NOT found!");
return false;
}
$reader = new XMLReader();
if (!$reader->open(EGW_SERVER_ROOT.$path)) return false;
while($reader->read())
{
if ($reader->nodeType == XMLReader::ELEMENT && $reader->name == 'template')
{
$template = new etemplate_template_widget($reader);
//echo $template->id; _debug_array($template);
self::$cache[$template->id] = $template;
if ($template->id == $name)
{
error_log(__METHOD__."('$name', '$template_set', '$version', '$load_via') read in ".round(1000.0*(microtime(true)-$start),2)." ms");
return $template;
}
}
}
// template not found in file, should never happen
error_log(__METHOD__."('$name', '$template_set', '$version', '$load_via') template NOT found in file '$path'!");
return false;
}
/**
* Get path/URL relative to EGroupware install of a template
*
* @param string $name
* @param string $template_set='default'
* @param string $version=''
* @return string|boolean path of template xml file or false if not found
*/
public static function relPath($name, $template_set='default', $version='')
{
list($app, $rest) = explode('.', $name, 2);
$path = '/'.$app.'/templates/'.$template_set.'/'.$rest.'.xet';
if (file_exists(EGW_SERVER_ROOT.$path)) return $path;
if ($templateSet != 'default')
{
$path = '/'.$app.'/templates/default/'.$rest.'.xet';
if (file_exists(EGW_SERVER_ROOT.$path)) return $path;
}
return false;
}
}
/*
header('Content-Type: text/xml');
$template = etemplate_template_widget::read('timesheet.edit');
$template->toXml();
*/

View File

@ -0,0 +1,196 @@
<?php
/**
* EGroupware - eTemplate widget baseclass
*
* @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
* @package etemplate
* @subpackage api
* @link http://www.egroupware.org
* @author Ralf Becker <RalfBecker@outdoor-training.de>
* @copyright 2002-11 by RalfBecker@outdoor-training.de
* @version $Id$
*/
/**
* eTemplate widget baseclass
*/
class etemplate_widget
{
/**
* Widget type
*
* @var string
*/
public $type;
/**
* Widget id
*
* @var string
*/
public $id;
/**
* Widget attributes
*
* @var array
*/
public $attrs = array();
/**
* Children
*
* @var array
*/
protected $children = array();
/**
* Constructor
*
* @param string|XMLReader $xml string with xml or XMLReader positioned on the element to construct
* @throws egw_exception_wrong_parameter
*/
public function __construct($xml)
{
if (is_a($xml, 'XMLReader'))
{
$reader = $xml;
}
else
{
$reader = new XMLReader();
if (!$reader->XML($xml))
{
throw new egw_exception_wrong_parameter("Can't parse xml:\n$xml");
}
}
$this->type = $reader->name;
$depth = $reader->depth;
// read all attributes
while($reader->moveToNextAttribute())
{
if ($reader->name == 'id')
{
$this->id = $reader->value;
}
else
{
$this->attrs[$reader->name] = $reader->value;
}
}
while($reader->read() && $reader->depth > $depth)
{
if ($reader->nodeType == XMLReader::ELEMENT && $reader->depth > $depth)
{
$this->children[] = self::factory($reader->name, $reader, $reader->getAttribute('id'));
}
}
}
/**
* Factory method to construct all widgets
*
* @param string $type
* @param string|XMLReader $xml
* @param string $id=null
*/
public static function factory($type, $xml, $id=null)
{
static $type2class_name = array();
$class_name =& $type2class_name[$type];
if (!isset($class_name))
{
list($basetype) = explode('-',$type);
if (!class_exists($class_name = 'etemplate_'.str_replace('-','_',$type).'_widget') &&
!class_exists($class_name = 'etemplate_'.str_replace('-','_',$basetype).'_widget'))
{
// default to widget class, we can not ignore it, as the widget may contain other widgets
$class_name = 'etemplate_widget';
}
}
// currently only overlays can contain templates, other widgets can only reference to templates via id
if ($type == 'template' && $id && ($template = etemplate_template_widget::read($id)))
{
return $template;
}
return new $class_name($xml);
}
/**
* Iterate over children to find the one with the given id and optional type
*
* @param string $id
* @param string $type=null
* @return etemplate_widget or NULL
*/
public function getElementById($id, $type=null)
{
foreach($this->children as $child)
{
if ($child->id === $id && (is_null($type) || $child->type === $type))
{
return $child;
}
if (($element = $child->getElementById($id, $type)))
{
return $element;
}
}
return null;
}
/**
* Validate input of a widget
*
* @param array $content
* @param string $cname='' current namespace
* @return mixed
*/
public function validate(array $content, $cname = '')
{
}
/**
* Convert object to string
*
* @return string
*/
public function __toString()
{
return $this->type.'#'.$this->id;
}
/**
* Convert widget (incl. children) to xml
*
* @param string $indent=''
* @return string
*/
public function toXml($indent='')
{
echo "$indent<$this->type";
if ($this->id) echo ' id="'.htmlspecialchars($this->id).'"';
foreach($this->attrs as $name => $value)
{
echo ' '.$name.'="'.htmlspecialchars($value).'"';
}
if ($this->children)
{
echo ">\n";
foreach($this->children as $child)
{
$child->toXml($indent."\t");
}
echo "$indent</$this->type>\n";
}
else
{
echo " />\n";
}
}
}