phpldapadmin/lib/xmlTemplates.php

608 lines
15 KiB
PHP

<?php
/**
* Classes and functions for XML based templates.
*
* @author The phpLDAPadmin development team
* @package phpLDAPadmin
*/
/**
* XML Templates Class
*
* @package phpLDAPadmin
* @subpackage Templates
*/
abstract class xmlTemplates {
# The server ID that these templates are configured for.
protected $server_id;
# Our array of the available templates.
protected $templates = array();
public function __construct($server_id) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
{
debug_log('Entered (%%)', 5, 0, __FILE__, __LINE__, __METHOD__, $fargs);
}
$this->server_id = $server_id;
$server = $_SESSION[APPCONFIG]->getServer($this->server_id);
$custom_prefix = $server->getValue('custom','pages_prefix');
$class = $this->getClassVars();
$changed = false;
# Try to get the templates from our CACHE.
if ($this->templates = get_cached_item($server_id,$class['item'])) {
if (DEBUG_ENABLED)
{
debug_log('Using CACHED templates', 4, 0, __FILE__, __LINE__, __METHOD__);
}
# See if the template_time has expired to see if we should reload the templates.
foreach ($this->templates as $index => $template) {
# If the file no longer exists, we'll delete the template.
if (! file_exists($template->getFileName())) {
unset($this->templates[$index]);
$changed = true;
system_message(array(
'title'=>_('Template XML file removed.'),
'body'=>sprintf('%s %s (%s)',_('Template XML file has removed'),$template->getName(false),$template->getType()),
'type'=>'info','special'=>true));
continue;
}
if (($template->getReadTime() < (time()-$class['cachetime']))
&& (filectime($template->getFileName()) > $template->getReadTime())) {
system_message(array(
'title'=>_('Template XML file changed.'),
'body'=>sprintf('%s %s (%s)',_('Template XML file has changed and been reread'),$template->getName(false),$template->getType()),
'type'=>'info','special'=>true));
$changed = true;
$this->templates[$index] = new $class['name']($this->server_id,$template->getName(false),$template->getFileName(),$template->getType(),$index);
}
}
if (DEBUG_ENABLED)
{
debug_log('Templates refreshed', 4, 0, __FILE__, __LINE__, __METHOD__);
}
# See if there are any new template files
$index = max(array_keys($this->templates))+1;
foreach ($class['types'] as $type) {
$dir = $class['dir'].$type;
$dh = opendir($dir);
if (! $type)
{
$type = 'template';
}
while ($file = readdir($dh)) {
# Ignore any files that are not XML files.
if (! preg_match('/.xml$/',$file))
{
continue;
}
# Ignore any files that are not the predefined custom files.
if ($_SESSION[APPCONFIG]->getValue('appearance','custom_templates_only')
&& ! preg_match("/^${custom_prefix}/",$file))
{
continue;
}
$filename = sprintf('%s/%s',$dir,$file);
if (! in_array($filename,$this->getTemplateFiles())) {
$templatename = preg_replace('/.xml$/','',$file);
$this->templates[$index] = new $class['name']($this->server_id,$templatename,$filename,$type,$index);
$index++;
$changed = true;
system_message(array(
'title'=>_('New Template XML found.'),
'body'=>sprintf('%s %s (%s)',_('A new template XML file has been loaded'),$file,$type),
'type'=>'info','special'=>true));
}
}
}
} else {
if (DEBUG_ENABLED)
{
debug_log('Parsing templates', 4, 0, __FILE__, __LINE__, __METHOD__);
}
# Need to reset this, as get_cached_item() returns null if nothing cached.
$this->templates = array();
$changed = true;
$counter = 0;
foreach ($class['types'] as $type) {
$dir = $class['dir'].$type;
$dh = opendir($class['dir'].$type);
if (! $type)
{
$type = 'template';
}
while ($file = readdir($dh)) {
# Ignore any files that are not XML files.
if (! preg_match('/.xml$/',$file))
{
continue;
}
# Ignore any files that are not the predefined custom files.
if ($_SESSION[APPCONFIG]->getValue('appearance','custom_templates_only')
&& ! preg_match("/^${custom_prefix}/",$file))
{
continue;
}
$filename = sprintf('%s/%s',$dir,$file);
# Store the template
$templatename = preg_replace('/.xml$/','',$file);
$this->templates[$counter] = new $class['name']($this->server_id,$templatename,$filename,$type,$counter);
$counter++;
}
}
}
if (DEBUG_ENABLED)
{
debug_log('Templates loaded', 4, 0, __FILE__, __LINE__, __METHOD__);
}
if ($changed) {
masort($this->templates,'title');
set_cached_item($server_id,$class['item'],'null',$this->templates);
}
}
/**
* This will return our custom class variables, used by the parent to create objects.
*/
private function getClassVars() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
{
debug_log('Entered (%%)', 5, 0, __FILE__, __LINE__, __METHOD__, $fargs);
}
$class = array();
switch (get_class($this)) {
case 'Queries':
$class['item'] = 'query';
$class['name'] = 'Query';
$class['cachetime'] = $_SESSION[APPCONFIG]->getValue('cache','query_time');
$class['types'] = array('');
$class['dir'] = QUERYDIR;
break;
case 'Templates':
$class['item'] = 'template';
$class['name'] = 'Template';
$class['cachetime'] = $_SESSION[APPCONFIG]->getValue('cache','template_time');
$class['types'] = array('creation','modification');
$class['dir'] = TMPLDIR;
break;
default:
debug_dump_backtrace(sprintf('Unknown class %s',get_class($this)),1);
}
return $class;
}
/**
* Return a list of templates by their type
* This function should return a sorted list, as the array is built sorted.
*
* @param null $type
* @param null $container
* @param bool $disabled
* @return array List of templates of the type
*/
public function getTemplates($type=null,$container=null,$disabled=false) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
{
debug_log('Entered (%%)', 5, 0, __FILE__, __LINE__, __METHOD__, $fargs);
}
$result = array();
if (is_array($this->templates))
{
foreach ($this->templates as $details)
{
# Clone this, as we'll disable some templates, as a result of the container being requested.
$template = clone $details;
if ( ! is_null($container) && ($regexp = $template->getRegExp()) && ( ! @preg_match('/' . $regexp . '/i', $container)))
{
$template->setInvalid(_('This template is not valid in this container'), TRUE);
if ($_SESSION[APPCONFIG]->getValue('appearance', 'hide_template_regexp'))
{
$template->setInvisible();
}
}
if ($template->isVisible() && ( ! $disabled || ! $template->isAdminDisabled()))
{
if (is_null($type) || ( ! is_null($type) && $template->isType($type)))
{
$result[] = $template;
}
}
}
}
return $result;
}
/**
* Return a template by its ID
*
* @param string The template ID as it was when it was generated (normally used in $_REQUEST vars).
* @return object Template (or default template if the ID doesnt exist)
*/
public function getTemplate($templateid) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
{
debug_log('Entered (%%)', 5, 0, __FILE__, __LINE__, __METHOD__, $fargs);
}
$class = $this->getClassVars();
foreach ($this->templates as $template)
{
if ($template->getID() === $templateid)
{
return clone $template;
}
}
# If we get here, the template ID didnt exist, so return a blank template, which be interpreted as the default template
$object = new $class['name']($this->server_id,null,null,'default');
return $object;
}
/**
* Get a list of template filenames.
*/
private function getTemplateFiles() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
{
debug_log('Entered (%%)', 5, 0, __FILE__, __LINE__, __METHOD__, $fargs);
}
$result = array();
foreach ($this->templates as $template)
{
$result[] = $template->getFileName();
}
return $result;
}
}
/**
* XML Template Class
*
* @package phpLDAPadmin
* @subpackage Templates
*/
abstract class xmlTemplate {
# Server ID that the template is linked to
protected $server_id;
# Template unique ID
protected $id;
# Template name - as extracted from the filename
protected $name;
# Template type - creation/modification
protected $type;
# Time this object was created
protected $readtime;
# Template file name
protected $filename;
# The TEMPLATE attributes as per the template definition, or the DN entry
protected $attributes = array();
public function __construct($server_id,$name=null,$filename=null,$type=null,$id=null) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
{
debug_log('Entered (%%)', 5, 0, __FILE__, __LINE__, __METHOD__, $fargs);
}
$this->server_id = $server_id;
$this->name = $name;
$this->type = $type;
$this->filename = $filename;
$this->readtime = time();
$this->id = $id;
# If there is no filename, then this template is a default template.
if (is_null($filename))
{
return;
}
# If we have a filename, parse the template file and build the object.
$objXML = new xml2array();
$xmldata = $objXML->parseXML(file_get_contents($filename),$filename);
$this->storeTemplate($xmldata);
}
/**
* Get an attribute ID
*
* @param string The Attribute being searched.
* @return int Attribute ID in the array
*/
protected function getAttrID($attr) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
{
debug_log('Entered (%%)', 5, 0, __FILE__, __LINE__, __METHOD__, $fargs);
}
foreach ($this->attributes as $index => $attribute)
{
if (strtolower($attr) == $attribute->getName() || in_array(strtolower($attr), $attribute->getAliases()))
{
return $index;
}
}
return null;
}
/**
* Get the Template filename.
*/
public function getFileName() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
{
debug_log('Entered (%%)', 5, 1, __FILE__, __LINE__, __METHOD__, $fargs, $this->filename);
}
return $this->filename;
}
/**
* Return the template by ID
*/
public function getID() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
{
debug_log('Entered (%%)', 5, 0, __FILE__, __LINE__, __METHOD__, $fargs, $this->id);
}
if ($this->name)
{
return sprintf('%s:%s', $this->getName(FALSE), $this->id);
}
else
{
return 'none';
}
}
/**
* Return the template name
*
* @param boolean Force the name to be lowercase (default)
*/
public function getName($lower=true) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
{
debug_log('Entered (%%)', 5, 1, __FILE__, __LINE__, __METHOD__, $fargs, $this->name);
}
if ($lower)
{
return strtolower($this->name);
}
else
{
return $this->name;
}
}
/**
* Get the Template read time.
*/
public function getReadTime() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
{
debug_log('Entered (%%)', 5, 1, __FILE__, __LINE__, __METHOD__, $fargs, $this->readtime);
}
return $this->readtime;
}
/**
* Return this LDAP Server object
*
* @return object DataStore Server
*/
protected function getServer() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
{
debug_log('Entered (%%)', 5, 1, __FILE__, __LINE__, __METHOD__, $fargs);
}
return $_SESSION[APPCONFIG]->getServer($this->getServerID());
}
/**
* Return the LDAP server ID
*
* @return int Server ID
*/
protected function getServerID() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
{
debug_log('Entered (%%)', 5, 1, __FILE__, __LINE__, __METHOD__, $fargs, $this->server_id);
}
return $this->server_id;
}
/**
* Test if a template is of a type
*
* @param $type
* @return boolean
*/
public function isType($type) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
{
debug_log('Entered (%%)', 5, 0, __FILE__, __LINE__, __METHOD__, $fargs, $this->type);
}
if ($this->type == $type)
{
return TRUE;
}
else
{
return FALSE;
}
}
/**
* Return the template type
*/
public function getType() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
{
debug_log('Entered (%%)', 5, 1, __FILE__, __LINE__, __METHOD__, $fargs, $this->type);
}
return $this->type;
}
/**
* Get template title
*/
public function getTitle() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
{
debug_log('Entered (%%)', 5, 0, __FILE__, __LINE__, __METHOD__, $fargs);
}
if (! isset($this->title) && ! isset($this->description))
{
return '';
}
return isset($this->title) ? $this->title : $this->description;
}
/**
* Add another attribute to this template
*
* @param $name
* @param $value
* @param null $source
* @return Attribute|DnAttribute|GidAttribute|MultiLineAttribute Attribute ID
*/
public function addAttribute($name,$value,$source=null) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
{
debug_log('Entered (%%)', 5, 0, __FILE__, __LINE__, __METHOD__, $fargs);
}
if (! is_array($value))
{
debug_dump_backtrace('Value should be an array()', 1);
}
$server = $this->getServer();
# Initialise the Attribute Factory.
$attribute_factory = new AttributeFactory();
if (preg_match('/;/',$name))
{
system_message(array(
'title' => 'phpLDAPadmin doesnt support RFC3866.',
'body' => sprintf('%s {%s} (%s)', 'PLA might not do what you expect...', $name, (is_array($value) ? serialize($value) : $value)),
'type' => 'warn'));
}
# If there isnt a schema item for this attribute
$attribute = $attribute_factory->newAttribute($name,$value,$server->getIndex(),$source);
$attrid = $this->getAttrID($attribute->getName());
if (is_null($attrid))
{
$this->attributes[] = $attribute;
}
return $attribute;
}
/**
* Get the attribute names
*
* @return array Array of attributes Names
*/
public function getAttributeNames() {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
{
debug_log('Entered (%%)', 5, 0, __FILE__, __LINE__, __METHOD__, $fargs);
}
$result = array();
foreach ($this->attributes as $attribute)
{
$result[] = $attribute->getName();
}
return $result;
}
/**
* Get a specific Attribute
*
* @param string Name of attribute to retrieve
* @return object Attribute
*/
public function getAttribute($name) {
if (DEBUG_ENABLED && (($fargs=func_get_args())||$fargs='NOARGS'))
{
debug_log('Entered (%%)', 5, 0, __FILE__, __LINE__, __METHOD__, $fargs);
}
foreach ($this->attributes as $attribute)
{
if (($attribute->getName() == strtolower($name)) || in_array(strtolower($name), $attribute->getAliases()))
{
return $attribute;
}
}
return null;
}
/**
* May be overloaded in other classes
*/
public function isAdminDisabled() {}
}