diff --git a/livesupport/modules/storageServer/var/MetaData.php b/livesupport/modules/storageServer/var/MetaData.php index fba9fca0c..0b393cd6d 100644 --- a/livesupport/modules/storageServer/var/MetaData.php +++ b/livesupport/modules/storageServer/var/MetaData.php @@ -23,14 +23,12 @@ Author : $Author: tomas $ - Version : $Revision: 1.23 $ + Version : $Revision: 1.24 $ Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/storageServer/var/MetaData.php,v $ ------------------------------------------------------------------------------*/ define('DEBUG', FALSE); #define('DEBUG', TRUE); -define('VALIDATE', FALSE); -#define('VALIDATE', TRUE); define('MODIFY_LAST_MATCH', TRUE); require_once "XML/Util.php"; @@ -56,6 +54,7 @@ class MetaData{ */ function MetaData(&$gb, $gunid, $resDir) { + $this->config =& $gb->config; $this->dbc =& $gb->dbc; $this->mdataTable = $gb->mdataTable; $this->gunid = $gunid; @@ -83,7 +82,8 @@ class MetaData{ if($this->exists) return FALSE; $tree =& $this->parse($mdata, $loc); if(PEAR::isError($tree)) return $tree; - $res = $this->validate($tree, $format); + $this->format = $format; + $res = $this->validate($tree); if(PEAR::isError($res)) return $res; $res = $this->storeDoc($tree); if(PEAR::isError($res)) return $res; @@ -215,6 +215,25 @@ class MetaData{ */ function setMetadataEl($mid, $value=NULL) { + $info = $this->dbc->getRow(" + SELECT parmd.predns as parns, parmd.predicate as parname, + md.predxml, md.predns as chns, md.predicate as chname + FROM {$this->mdataTable} parmd + INNER JOIN {$this->mdataTable} md + ON parmd.id=md.subject AND md.subjns='_I' + WHERE md.id=$mid + "); + if(PEAR::isError($info)) return $info; + if(is_null($info)){ + return PEAR::raiseError( + "MetaData::setMetadataEl: parent container not found" + ); + } + extract($info); + $parname = ($parns ? "$parns:" : '').$parname; + $category = ($chns ? "$chns:" : '').$chname; + $r = $this->validateOneValue($parname, $category, $predxml, $value); + if(PEAR::isError($r)) return $r; if(!is_null($value)){ $sql = " UPDATE {$this->mdataTable} @@ -240,17 +259,22 @@ class MetaData{ */ function insertMetadataEl($parid, $category, $value=NULL, $predxml='T') { - $cnt = $this->dbc->getOne(" - SELECT count(*) FROM {$this->mdataTable} + $category = strtolower($category); + $parent = $this->dbc->getRow(" + SELECT predns, predicate, predxml FROM {$this->mdataTable} WHERE gunid=x'{$this->gunid}'::bigint AND id=$parid "); - if(PEAR::isError($cnt)) return $cnt; - if($cnt < 1){ + if(PEAR::isError($parent)) return $parent; + if(is_null($parent)){ return PEAR::raiseError( "MetaData::insertMetadataEl: container not found" ); } - $a = XML_Util::splitQualifiedName(strtolower($category)); + $parNs = ($parent['predns'] ? "{$parent['predns']}:" : ''); + $parName = $parNs.$parent['predicate']; + $r = $this->validateOneValue($parName, $category, $predxml, $value); + if(PEAR::isError($r)) return $r; + $a = XML_Util::splitQualifiedName($category); if(PEAR::isError($a)) return $a; $catNs = $a['namespace']; $cat = $a['localPart']; @@ -396,6 +420,14 @@ class MetaData{ return $this->fname; } + /** + * Set the metadata format to the object instance + */ + function setFormat($format=NULL) + { + $this->format = $format; + } + /** * Check if there are any file's metadata in database * @@ -458,17 +490,13 @@ class MetaData{ * Validate parsed metadata * * @param tree array, parsed tree - * @param format string, metadata format for validation - * ('audioclip' | 'playlist' | 'webstream' | NULL) - * (NULL = no validation) * @return true or PEAR::error */ - function validate(&$tree, $format=NULL) + function validate(&$tree) { - //echo"
";var_dump($tree);exit;
-        if(VALIDATE && !is_null($format)){
+        if($this->config['validate'] && !is_null($this->format)){
             require_once"Validator.php";
-            $val =& new Validator($format, $this->gunid);
+            $val =& new Validator($this->format, $this->gunid);
             if(PEAR::isError($val)) return $val;
             $res = $val->validate($tree);
             if(PEAR::isError($res)) return $res;
@@ -476,6 +504,24 @@ class MetaData{
         return TRUE;
     }
     
+    /**
+     *  Validate one metadata value (on insert/update)
+     *
+     *  @param
+     *  @return true or PEAR::error
+     */
+    function validateOneValue($parName, $category, $predxml, $value)
+    {
+        if($this->config['validate'] && !is_null($this->format)){
+            require_once"Validator.php";
+            $val =& new Validator($this->format, $this->gunid);
+            if(PEAR::isError($val)) return $val;
+            $r = $val->validateOneValue($parName, $category, $predxml, $value);
+            if(PEAR::isError($r)) return $r;
+        }
+        return TRUE;
+    }
+    
     /**
      *  Insert parsed metadata into database
      *
diff --git a/livesupport/modules/storageServer/var/Playlist.php b/livesupport/modules/storageServer/var/Playlist.php
index c1a70c386..38d63d8b8 100644
--- a/livesupport/modules/storageServer/var/Playlist.php
+++ b/livesupport/modules/storageServer/var/Playlist.php
@@ -23,7 +23,7 @@
  
  
     Author   : $Author: tomas $
-    Version  : $Revision: 1.3 $
+    Version  : $Revision: 1.4 $
     Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/storageServer/var/Playlist.php,v $
 
 ------------------------------------------------------------------------------*/
@@ -89,15 +89,24 @@ class Playlist extends StoredFile{
      */
     function getPlInfo()
     {
+        $parid = $this->getContainer('playlist');
+        if(PEAR::isError($parid)){ return $parid; }
         // get playlist length and record id:
-        $r = $this->md->getMetadataEl('dcterms:extent');
+        $r = $this->md->getMetadataEl('playlength', $parid);
         if(PEAR::isError($r)){ return $r; }
         if(isset($r[0])){
             $plLen = $r[0]['value'];
             $plLenMid = $r[0]['mid'];
         }else{
-            $plLen = '00:00:00.000000';
-            $plLenMid = NULL;
+            $r = $this->md->getMetadataEl('dcterms:extent');
+            if(PEAR::isError($r)){ return $r; }
+            if(isset($r[0])){
+                $plLen = $r[0]['value'];
+                $plLenMid = $r[0]['mid'];
+            }else{
+                $plLen = '00:00:00.000000';
+                $plLenMid = NULL;
+            }
         }
         // get main playlist container
         $parid = $this->getContainer('playlist');
@@ -277,7 +286,7 @@ class Playlist extends StoredFile{
         $offset = $plLen;
         $plElInfo = $this->insertPlaylistElement($parid, $offset,
             $acGunid, $acLen, $acTit, $fadeIn, $fadeOut);
-        if(PEAR::isError($plElInfo)){ return $plElnfo; }
+        if(PEAR::isError($plElInfo)){ return $plElInfo; }
         extract($plElInfo); // 'plElId', 'plElGunid', 'fadeInId', 'fadeOutId'
 
         /* commented - maybe useless (C++ part doesn't do it)
diff --git a/livesupport/modules/storageServer/var/StoredFile.php b/livesupport/modules/storageServer/var/StoredFile.php
index b0c6ed161..14a07d672 100644
--- a/livesupport/modules/storageServer/var/StoredFile.php
+++ b/livesupport/modules/storageServer/var/StoredFile.php
@@ -23,7 +23,7 @@
  
  
     Author   : $Author: tomas $
-    Version  : $Revision: 1.23 $
+    Version  : $Revision: 1.24 $
     Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/storageServer/var/StoredFile.php,v $
 
 ------------------------------------------------------------------------------*/
@@ -162,7 +162,7 @@ class StoredFile{
             : "gunid=x'$gunid'::bigint"
         );
         $row = $gb->dbc->getRow("
-            SELECT id, to_hex(gunid)as gunid, mime, name
+            SELECT id, to_hex(gunid)as gunid, mime, name, ftype
             FROM {$gb->filesTable} WHERE $cond
         ");
         if(PEAR::isError($row)) return $row;
@@ -177,6 +177,7 @@ class StoredFile{
         $ac->mime = $row['mime'];
         $ac->name = $row['name'];
         $ac->id   = $row['id'];
+        $ac->md->setFormat($row['ftype']);
         return $ac;
     }
 
diff --git a/livesupport/modules/storageServer/var/Validator.php b/livesupport/modules/storageServer/var/Validator.php
index a0ffdf8de..32b1381bb 100644
--- a/livesupport/modules/storageServer/var/Validator.php
+++ b/livesupport/modules/storageServer/var/Validator.php
@@ -23,7 +23,7 @@
  
  
     Author   : $Author: tomas $
-    Version  : $Revision: 1.3 $
+    Version  : $Revision: 1.4 $
     Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/storageServer/var/Validator.php,v $
 
 ------------------------------------------------------------------------------*/
@@ -38,6 +38,7 @@ define('VAL_FORMAT', 117);
 define('VAL_CONTENT', 118);
 define('VAL_NOREQA', 119);
 define('VAL_ATTRIB', 120);
+define('VAL_PREDXML', 121);
 
 #require_once "";
 
@@ -56,11 +57,11 @@ class Validator{
     /**
      *  string - format type of validated document
      */
-    var $formatType = NULL;
-    /**
-     *  
-     */
     var $format = NULL;
+    /**
+     *  Preloaded format tree structure
+     */
+    var $formTree = NULL;
     /**
      *  string - gunid of validated file for identification in mass input
      */
@@ -68,25 +69,25 @@ class Validator{
     /**
      *  Constructor
      *
-     *  @param formatType string - format type of validated document
+     *  @param format string - format type of validated document
      *  @param gunid string - gunid of validated file for identification
      *          in mass input
      */
-    function Validator($formatType, $gunid)
+    function Validator($format, $gunid)
     {
-        $this->formatType   = $formatType;
+        $this->format   = $format;
         $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(!isset($formats[$format])) return $this->_err(VAL_FORMAT);
+        $formatName = $formats[$format];
+        $formatFile = dirname(__FILE__)."/$formatName.php";
         if(!file_exists($formatFile)) return $this->_err(VAL_FORMAT);
         require $formatFile;
-        $this->format = $$format;
+        $this->formTree = $$formatName;
     }
 
     /**
@@ -97,30 +98,62 @@ class Validator{
      */
     function validate(&$data)
     {
-        $r = $this->validateNode($data, $this->format['_root']);
+        $r = $this->validateNode($data, $this->formTree['_root']);
         return $r;
     }
 
+    /**
+     *  Validate one metadata value (on insert/update)
+     *
+     *  @param
+     *  @return TRUE or PEAR::error
+     */
+    function validateOneValue($fname, $category, $predxml, $value)
+    {
+        $formTree =& $this->formTree;
+        switch($predxml){
+            case'T':
+                if(!$this->isChildInFormat($fname, $category))
+                    return $this->_err(113, "$category in $fname");
+                break;
+            case'A':
+                if(!$this->isAttrInFormat($fname, $category))
+                    return $this->_err(114, "$category in $fname");
+                break;
+            case'N':
+                return TRUE;
+                break;
+            default:
+                return $this->_err(VAL_PREDXML, $predxml);
+        }
+        if(isset($formTree[$category]['regexp'])){
+            // echo "XXX {$formTree[$fname]['regexp']} / ".$node->content."\n";
+            if(!preg_match("|{$formTree[$category]['regexp']}|", $value))
+                return $this->_err(VAL_CONTENT, $category);
+        }
+        
+    }
+
     /**
      *  Validation of one element node from object tree
      *
      *  @param node object - validated node
-     *  @param fname string - aktual name in format structur
+     *  @param fname string - aktual name in format structure
      *  @return TRUE or PEAR::error
      */
     function validateNode(&$node, $fname)
     {
         $dname = strtolower(($node->ns? $node->ns.":" : '').$node->name);
-        $format =& $this->format;
+        $formTree =& $this->formTree;
         if(DEBUG) echo"\nVAL::validateNode: 1 $dname/$fname\n";
         // 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);
+        if(!isset($formTree[$fname])) return $this->_err(VAL_NOTDEF, $fname);
         // check element content
-        if(isset($format[$fname]['regexp'])){
-            // echo "XXX {$format[$fname]['regexp']} / ".$node->content."\n";
-            if(!preg_match("|{$format[$fname]['regexp']}|", $node->content))
+        if(isset($formTree[$fname]['regexp'])){
+            // echo "XXX {$formTree[$fname]['regexp']} / ".$node->content."\n";
+            if(!preg_match("|{$formTree[$fname]['regexp']}|", $node->content))
                 return $this->_err(VAL_CONTENT, $fname);
         }
         // validate attributes:
@@ -141,7 +174,7 @@ class Validator{
      */
     function validateAttributes(&$node, $fname)
     {
-        $format =& $this->format;
+        $formTree =& $this->formTree;
         $attrs = array();
         // check if all attrs are permitted here:
         foreach($node->attrs as $i=>$attr){
@@ -151,15 +184,15 @@ class Validator{
                 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))
+            if(isset($formTree[$aname]['regexp'])){
+                // echo "XAR {$formTree[$fname]['regexp']} / ".$node->content."\n";
+                if(!preg_match("|{$formTree[$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($formTree[$fname]['attrs'])){
+            $fattrs =& $formTree[$fname]['attrs'];
             if(isset($fattrs['required'])){
                 foreach($fattrs['required'] as $i=>$attr){
                     if(!isset($attrs[$attr]))
@@ -179,7 +212,7 @@ class Validator{
      */
     function validateChildren(&$node, $fname)
     {
-        $format =& $this->format;
+        $formTree =& $this->formTree;
         $childs = array();
         // check if all children are permitted here:
         foreach($node->children as $i=>$ch){
@@ -193,8 +226,8 @@ class Validator{
             $childs[$chname] = TRUE;
         }
         // check if all required children are here:
-        if(isset($format[$fname]['childs'])){
-            $fchilds =& $format[$fname]['childs'];
+        if(isset($formTree[$fname]['childs'])){
+            $fchilds =& $formTree[$fname]['childs'];
             if(isset($fchilds['required'])){
                 foreach($fchilds['required'] as $i=>$ch){
                     if(!isset($childs[$ch])) return $this->_err(VAL_NOREQE, $ch);
@@ -260,10 +293,10 @@ class Validator{
      */
     function isInFormatAs($fname, $chname, $nType='childs', $reqType='required')
     {
-        $format =& $this->format;
+        $formTree =& $this->formTree;
         $listed = (
-            isset($format[$fname][$nType][$reqType]) ?
-            array_search($chname, $format[$fname][$nType][$reqType]) :
+            isset($formTree[$fname][$nType][$reqType]) ?
+            array_search($chname, $formTree[$fname][$nType][$reqType]) :
             FALSE
         );
         return $listed;
@@ -290,6 +323,7 @@ class Validator{
             118=>'Invalid content',
             119=>'Required attribute missing',
             120=>'Invalid attribute format',
+            121=>'Invalid predicate type',
         );
         return PEAR::raiseError(
             "Validator: {$msg[$errno]} #$errno ($par, gunid={$this->gunid})",
diff --git a/livesupport/modules/storageServer/var/conf.php b/livesupport/modules/storageServer/var/conf.php
index 2ba8315fa..a838a8721 100644
--- a/livesupport/modules/storageServer/var/conf.php
+++ b/livesupport/modules/storageServer/var/conf.php
@@ -23,7 +23,7 @@
  
  
     Author   : $Author: tomas $
-    Version  : $Revision: 1.14 $
+    Version  : $Revision: 1.15 $
     Location : $Source: /home/paul/cvs2svn-livesupport/newcvsrepo/livesupport/modules/storageServer/var/conf.php,v $
 
 ------------------------------------------------------------------------------*/
@@ -40,17 +40,22 @@
  *   
dsn
datasource setting *
tblNamePrefix
prefix for table names in the database *
authCookieName
secret token cookie name + *
StationPrefsGr
name of station preferences group + *
AllGr
name of 'all users' group *
storageDir
main directory for storing binary media files *
bufferDir
directory for temporary files *
transDir
directory for incomplete transferred files *
accessDir
directory for symlinks to accessed files *
isArchive
local/central flag + *
validate
enable/disable validator *
storageUrlPath
path-URL-part of storageServer base dir *
storageXMLRPC
XMLRPC server script address relative to storageUrlPath *
storageUrlHost, storageUrlPort
host and port of storageServer *
archiveUrlPath
path-URL-part of archiveServer base dir *
archiveXMLRPC
XMLRPC server script address relative to archiveUrlPath *
archiveUrlHost, archiveUrlPort
host and port of archiveServer + *
archiveAccountLogin, archiveAccountPass
account info + * for login to archive * */ $config = array( @@ -71,6 +76,7 @@ $config = array( 'transDir' => dirname(__FILE__).'/../../storageServer/var/trans', 'accessDir' => dirname(__FILE__).'/../../storageServer/var/access', 'isArchive' => FALSE, + 'validate' => TRUE, /* ==================================================== URL configuration */ 'storageUrlPath' => '/livesupportStorageServer',