Major changes in node children validation.
+ comments added.
This commit is contained in:
parent
54595b6f96
commit
5ffbc365cb
|
@ -23,119 +23,242 @@
|
|||
|
||||
|
||||
Author : $Author: tomas $
|
||||
Version : $Revision: 1.2 $
|
||||
Version : $Revision: 1.3 $
|
||||
Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/storageServer/var/Validator.php,v $
|
||||
|
||||
------------------------------------------------------------------------------*/
|
||||
define('VAL_ROOT', 110);
|
||||
define('VAL_NOREQ', 111);
|
||||
define('VAL_NOREQE', 111);
|
||||
define('VAL_NOONEOF', 112);
|
||||
define('VAL_UNKNOWNE', 113);
|
||||
define('VAL_UNKNOWNA', 114);
|
||||
define('VAL_NOTDEF', 115);
|
||||
define('VAL_UNEXPONEOF', 116);
|
||||
define('VAL_FORMAT', 117);
|
||||
define('VAL_CONTENT', 118);
|
||||
define('VAL_NOREQA', 119);
|
||||
define('VAL_ATTRIB', 120);
|
||||
|
||||
#require_once "";
|
||||
|
||||
/**
|
||||
* Simple XML validator against structure stored in PHP hash-array hierarchy.
|
||||
*
|
||||
* It should be replaced by XML schema validation in the future.
|
||||
* Basic format files:
|
||||
* <ul>
|
||||
* <li>audioClipFormat.php</li>
|
||||
* <li>webstreamFormat.php</li>
|
||||
* <li>playlistFormat.php</li>
|
||||
* </ul>
|
||||
* It probably should be replaced by XML schema validation in the future.
|
||||
*/
|
||||
class Validator{
|
||||
/**
|
||||
*
|
||||
* string - format type of validated document
|
||||
*/
|
||||
var $format = '';
|
||||
var $formatType = NULL;
|
||||
/**
|
||||
*
|
||||
*
|
||||
*/
|
||||
var $data = '';
|
||||
var $format = NULL;
|
||||
/**
|
||||
*
|
||||
* string - gunid of validated file for identification in mass input
|
||||
*/
|
||||
var $anode = '';
|
||||
var $gunid = NULL;
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param formatType string - format type of validated document
|
||||
* @param gunid string - gunid of validated file for identification
|
||||
* in mass input
|
||||
*/
|
||||
function Validator($format)
|
||||
function Validator($formatType, $gunid)
|
||||
{
|
||||
$this->format = $format;
|
||||
$this->formatType = $formatType;
|
||||
$this->gunid = $gunid;
|
||||
$formats = array(
|
||||
'audioclip' => "audioClipFormat",
|
||||
'playlist' => "playlistFormat",
|
||||
'webstream' => "webstreamFormat",
|
||||
);
|
||||
if(!isset($formats[$formatType])) return $this->_err(VAL_FORMAT);
|
||||
$format = $formats[$formatType];
|
||||
$formatFile = dirname(__FILE__)."/$format.php";
|
||||
if(!file_exists($formatFile)) return $this->_err(VAL_FORMAT);
|
||||
require $formatFile;
|
||||
$this->format = $$format;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate document - only wrapper for validateNode method
|
||||
*
|
||||
* @param data object, validated object tree
|
||||
* @return TRUE or PEAR::error
|
||||
*/
|
||||
function validate(&$data)
|
||||
{
|
||||
$this->data =& $data;
|
||||
$r = $this->validateNode($data, $this->format['_root']);
|
||||
return $r;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validation of one element node from object tree
|
||||
*
|
||||
* @param node object - validated node
|
||||
* @param fname string - aktual name in format structur
|
||||
* @return TRUE or PEAR::error
|
||||
*/
|
||||
function validateNode(&$node, $fname)
|
||||
{
|
||||
$dname = strtolower(($node->ns? $node->ns.":" : '').$node->name);
|
||||
$format =& $this->format;
|
||||
if(DEBUG) echo"\nVAL::validateNode: 1 $dname/$fname\n";
|
||||
if($dname != $fname) return $this->_err(VAL_ROOT);
|
||||
// check root node name:
|
||||
if($dname != $fname) return $this->_err(VAL_ROOT, $fname);
|
||||
// check if this element is defined in format:
|
||||
if(!isset($format[$fname])) return $this->_err(VAL_NOTDEF, $fname);
|
||||
$attrs = array();
|
||||
foreach($node->attrs as $i=>$attr){
|
||||
$attrs[$attr->name] =& $node->attrs[$i];
|
||||
$listr = $this->isListedAs($fname, $attr->name, 'attrs', 'required');
|
||||
$listi = $this->isListedAs($fname, $attr->name, 'attrs', 'implied');
|
||||
$listn = $this->isListedAs($fname, $attr->name, 'attrs', 'normal');
|
||||
if($listr===FALSE && $listi===FALSE && $listn===FALSE)
|
||||
return $this->_err(VAL_UNKNOWNA, $attr->name);
|
||||
// check element content
|
||||
if(isset($format[$fname]['regexp'])){
|
||||
// echo "XXX {$format[$fname]['regexp']} / ".$node->content."\n";
|
||||
if(!preg_match("|{$format[$fname]['regexp']}|", $node->content))
|
||||
return $this->_err(VAL_CONTENT, $fname);
|
||||
}
|
||||
// validate attributes:
|
||||
$ra = $this->validateAttributes($node, $fname);
|
||||
if(PEAR::isError($ra)) return $ra;
|
||||
// validate children:
|
||||
$r = $this->validateChildren($node, $fname);
|
||||
if(PEAR::isError($r)) return $r;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validation of attributes
|
||||
*
|
||||
* @param node object - validated node
|
||||
* @param fname string - aktual name in format structure
|
||||
* @return TRUE or PEAR::error
|
||||
*/
|
||||
function validateAttributes(&$node, $fname)
|
||||
{
|
||||
$format =& $this->format;
|
||||
$attrs = array();
|
||||
// check if all attrs are permitted here:
|
||||
foreach($node->attrs as $i=>$attr){
|
||||
$aname = strtolower(($attr->ns? $attr->ns.":" : '').$attr->name);
|
||||
$attrs[$aname] =& $node->attrs[$i];
|
||||
if(!$this->isAttrInFormat($fname, $aname))
|
||||
return $this->_err(VAL_UNKNOWNA, $aname);
|
||||
// check attribute format
|
||||
// echo "XXA $aname\n";
|
||||
if(isset($format[$aname]['regexp'])){
|
||||
// echo "XAR {$format[$fname]['regexp']} / ".$node->content."\n";
|
||||
if(!preg_match("|{$format[$aname]['regexp']}|", $attr->val))
|
||||
return $this->_err(VAL_ATTRIB, $aname);
|
||||
}
|
||||
}
|
||||
// check if all required attrs are here:
|
||||
if(isset($format[$fname]['attrs'])){
|
||||
$fattrs =& $format[$fname]['attrs'];
|
||||
if(isset($fattrs['required'])){
|
||||
foreach($fattrs['required'] as $i=>$attr){
|
||||
if(!isset($childs[$attr])) return $this->_err(VAL_NOREQ, $attr);
|
||||
if(!isset($attrs[$attr]))
|
||||
return $this->_err(VAL_NOREQA, $attr);
|
||||
}
|
||||
}
|
||||
}
|
||||
$childs = array();
|
||||
foreach($node->children as $i=>$ch){
|
||||
$chname = strtolower(($ch->ns? $ch->ns.":" : '').$ch->name);
|
||||
$childs[$chname] =& $node->children[$i];
|
||||
$listo = $this->isListedAs($fname, $chname, 'childs', 'optional');
|
||||
$listr = $this->isListedAs($fname, $chname, 'childs', 'required');
|
||||
$list1 = $this->isListedAs($fname, $chname, 'childs', 'oneof');
|
||||
if($listo===FALSE && $listr===FALSE && $list1===FALSE)
|
||||
return $this->_err(VAL_UNKNOWNE, $chname);
|
||||
}
|
||||
//var_dump($childs);
|
||||
if(isset($format[$fname]['childs'])){
|
||||
$fchilds =& $format[$fname]['childs'];
|
||||
if(isset($fchilds['required'])){
|
||||
foreach($fchilds['required'] as $i=>$ch){
|
||||
if(!isset($childs[$ch])) return $this->_err(VAL_NOREQ, $ch);
|
||||
}
|
||||
}
|
||||
if(isset($fchilds['oneof'])){
|
||||
$one = FALSE;
|
||||
foreach($fchilds['oneof'] as $i=>$ch){
|
||||
if(isset($childs[$ch])) $one = TRUE;
|
||||
}
|
||||
if(!$one) return $this->_err(VAL_NOONEOF);
|
||||
}
|
||||
}
|
||||
foreach($childs as $chname=>$ch){
|
||||
$r = $this->validateNode($childs[$chname], $chname);
|
||||
if(PEAR::isError($r)) return $r;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validation children nodes
|
||||
*
|
||||
* @param node object - validated node
|
||||
* @param fname string - aktual name in format structure
|
||||
* @return TRUE or PEAR::error
|
||||
*/
|
||||
function isListedAs($fname, $chname, $nType='childs', $reqType='required')
|
||||
function validateChildren(&$node, $fname)
|
||||
{
|
||||
$format =& $this->format;
|
||||
$childs = array();
|
||||
// check if all children are permitted here:
|
||||
foreach($node->children as $i=>$ch){
|
||||
$chname = strtolower(($ch->ns? $ch->ns.":" : '').$ch->name);
|
||||
// echo "XXE $chname\n";
|
||||
if(!$this->isChildInFormat($fname, $chname))
|
||||
return $this->_err(VAL_UNKNOWNE, $chname);
|
||||
// call children recursive:
|
||||
$r = $this->validateNode($node->children[$i], $chname);
|
||||
if(PEAR::isError($r)) return $r;
|
||||
$childs[$chname] = TRUE;
|
||||
}
|
||||
// check if all required children are here:
|
||||
if(isset($format[$fname]['childs'])){
|
||||
$fchilds =& $format[$fname]['childs'];
|
||||
if(isset($fchilds['required'])){
|
||||
foreach($fchilds['required'] as $i=>$ch){
|
||||
if(!isset($childs[$ch])) return $this->_err(VAL_NOREQE, $ch);
|
||||
}
|
||||
}
|
||||
// required one from set
|
||||
if(isset($fchilds['oneof'])){
|
||||
$one = FALSE;
|
||||
foreach($fchilds['oneof'] as $i=>$ch){
|
||||
if(isset($childs[$ch])){
|
||||
if($one) return $this->_err(
|
||||
VAL_UNEXPONEOF, "$ch in $fname");
|
||||
$one = TRUE;
|
||||
}
|
||||
}
|
||||
if(!$one) return $this->_err(VAL_NOONEOF);
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if child is presented in format structure
|
||||
*
|
||||
* @param fname string - node name in format structure
|
||||
* @param chname string - child node name
|
||||
* @return boolean
|
||||
*/
|
||||
function isChildInFormat($fname, $chname)
|
||||
{
|
||||
$listo = $this->isInFormatAs($fname, $chname, 'childs', 'optional');
|
||||
$listr = $this->isInFormatAs($fname, $chname, 'childs', 'required');
|
||||
$list1 = $this->isInFormatAs($fname, $chname, 'childs', 'oneof');
|
||||
return ($listo!==FALSE || $listr!==FALSE || $list1!==FALSE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if attribute is presented in format structure
|
||||
*
|
||||
* @param fname string - node name in format structure
|
||||
* @param aname string - attribute name
|
||||
* @return boolean
|
||||
*/
|
||||
function isAttrInFormat($fname, $aname)
|
||||
{
|
||||
$listr = $this->isInFormatAs($fname, $aname, 'attrs', 'required');
|
||||
$listi = $this->isInFormatAs($fname, $aname, 'attrs', 'implied');
|
||||
$listn = $this->isInFormatAs($fname, $aname, 'attrs', 'normal');
|
||||
return ($listr!==FALSE || $listi!==FALSE || $listn!==FALSE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if node/attribute is presented in format structure
|
||||
*
|
||||
* @param fname string - node name in format structure
|
||||
* @param chname string - node/attribute name
|
||||
* @param nType string - 'childs' | 'attrs'
|
||||
* @param reqType string - <ul>
|
||||
* <li>for elements: 'required' | 'optional' | 'oneof'</li>
|
||||
* <li>for attributes: 'required' | 'implied' | 'normal'</li>
|
||||
* </ul>
|
||||
* @return boolean/int (index int format array returned if found)
|
||||
*/
|
||||
function isInFormatAs($fname, $chname, $nType='childs', $reqType='required')
|
||||
{
|
||||
$format =& $this->format;
|
||||
$listed = (
|
||||
|
@ -147,25 +270,38 @@ class Validator{
|
|||
}
|
||||
|
||||
/**
|
||||
* Error exception generator
|
||||
*
|
||||
* @param errno int - erron code
|
||||
* @param par string - optional string for more descriptive error messages
|
||||
* @return PEAR::error
|
||||
*/
|
||||
function _err($errno, $par='')
|
||||
{
|
||||
$msg = array(
|
||||
110=>'Wrong root element',
|
||||
111=>'Required object missing',
|
||||
112=>'One-of object missing',
|
||||
111=>'Required element missing',
|
||||
112=>'One-of element missing',
|
||||
113=>'Unknown element',
|
||||
114=>'Unknown attribute',
|
||||
115=>'Not defined',
|
||||
116=>'Unexpected second object from one-of set',
|
||||
117=>'Unknown format',
|
||||
118=>'Invalid content',
|
||||
119=>'Required attribute missing',
|
||||
120=>'Invalid attribute format',
|
||||
);
|
||||
return PEAR::raiseError(
|
||||
"Validator: {$msg[$errno]} #$errno ($par)"
|
||||
"Validator: {$msg[$errno]} #$errno ($par, gunid={$this->gunid})",
|
||||
$errno
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
* @param
|
||||
* @return
|
||||
* /
|
||||
function ()
|
||||
{
|
||||
|
|
Loading…
Reference in New Issue