![]() |
Xataface 2.0
Xataface Application Framework
|
00001 <?php 00002 class Dataface_XMLTool { 00003 00004 var $ns="df"; 00005 var $perms_ns = "dfp"; 00006 var $atts_ns = "dfa"; 00007 var $http_ns = "http"; 00008 00009 var $required_tables_loaded = array(); 00010 00016 var $ifModifiedSince=array(); 00017 00018 00019 public static function &getOutputCache(){ 00020 static $cache =0; 00021 if ( !is_object($cache) ){ 00022 import('Dataface/OutputCache.php'); 00023 $cache = new Dataface_OutputCache(); 00024 } 00025 return $cache; 00026 } 00027 00028 00029 function setIfModifiedSince($type, $name, $timestamp){ 00030 $this->ifModifiedSince[$type][$name] = $timestamp; 00031 } 00032 00033 function getIfModifiedSince($type, $name){ 00034 if ( isset($this->ifModifiedSince[$type][$name]) ) { 00035 return $this->ifModifiedSince[$type][$name]; 00036 } else { 00037 return null; 00038 } 00039 } 00040 00041 function isModified($type, $name, $timestamp){ 00042 $since = $this->getIfModifiedSince($type, $name); 00043 if ( $since < $timestamp ){ 00044 return true; 00045 } else { 00046 return false; 00047 } 00048 } 00049 00055 function tableIsModified($name){ 00056 $cache =& $this->getOutputCache(); 00057 $time = $this->getIfModifiedSince('tables',$name); 00058 if ( $time == null ) return true; 00059 00060 return $cache->isModified($time, $name); 00061 } 00062 00063 function valuelistIsModified($table, $name){ 00064 00065 } 00066 00067 00068 function toXML(&$arg){ 00069 $class = get_class($arg); 00070 if ( is_array($arg) ){ 00071 return toXML_array($arg); 00072 } 00073 eval('$result = $this->toXML_'.$class.'($arg);'); 00074 return $result; 00075 } 00076 00077 function toXML_array($arg){ 00078 trigger_error("Not implemented yet.", E_USER_ERROR); 00079 00080 00081 } 00082 00083 function markRequiredTableLoaded($name){ 00084 00085 $this->required_tables_loaded[$name] = true; 00086 } 00087 00088 function addRequiredTable($name){ 00089 if ( !isset($this->required_tables_loaded[$name]) ) $this->required_tables_loaded[$name] = false; 00090 } 00091 00092 function requiredTablesToXML(){ 00093 $out = array(); 00094 foreach ( $this->required_tables_loaded as $tablename=>$loaded){ 00095 if (!$loaded){ 00096 $t =& Dataface_Table::loadTable($tablename); 00097 $out[] = $this->toXML($t); 00098 unset($t); 00099 } 00100 } 00101 return implode("\n", $out); 00102 } 00103 00104 function toXML_Dataface_Table(&$table){ 00105 00106 $ns = $this->ns; 00107 $pns = $this->perms_ns; 00108 $ans = $this->atts_ns; 00109 list($tablename, $tablelabel) = array_map(array(&$this,'xmlentities'), array($table->tablename, $table->getLabel())); 00110 $out = array(); 00111 00112 if ( !$this->tableIsModified($table->tablename) ){ 00113 $out[] = "<$ns:table id=\"tables.{$tablename}\" name=\"$tablename\" http:status-code=\"304\" http:status-message=\"Not Modified\"></$ns:table>"; 00114 00115 } else { 00116 00117 $out[] = <<<END 00118 <$ns:table id="tables.{$tablename}" name="$tablename" label="$tablelabel"> 00119 END; 00120 $perms = $table->getPermissions(); 00121 $patts = array(); 00122 foreach ($perms as $pname=>$pval){ 00123 $pname = str_replace(' ', '_', $pname); 00124 $patts[] = $pns.':'.$pname.'="'.$pval.'"'; 00125 } 00126 $patts = implode(' ',$patts); 00127 $out[] = "\t<$ns:permissions $patts/>"; 00128 foreach ( $table->fields() as $field ){ 00129 $atts = array(); 00130 foreach ($field as $key=>$val){ 00131 if ( is_scalar($val) ){ 00132 $atts[] = $ans.':'.$key.'="'.$this->xmlentities($val).'"'; 00133 } 00134 } 00135 $atts = implode(' ', $atts); 00136 $out[] = "\t<$ns:field id=\"tables.{$tablename}.fields.{$field['name']}\" $atts>"; 00137 00138 $fperms = $table->getPermissions(array('field'=>$field['name'])); 00139 $fpatts = array(); 00140 foreach ($fperms as $fpkey=>$fpval){ 00141 $fpkey = str_replace(' ', '_', $fpkey); 00142 $fpatts[] = $ans.':'.$fpkey.'="'.$fpval.'"'; 00143 } 00144 $fpatts = implode(' ',$fpatts); 00145 $out[] = "\t\t<$ns:permissions $fpatts/>"; 00146 00147 $widget = $field['widget']; 00148 $watts = array(); 00149 foreach ($widget as $wkey=>$wval){ 00150 00151 if ( is_scalar($wval) ){ 00152 $watts[] = $ans.':'.$wkey.'="'.$this->xmlentities($wval).'"'; 00153 } 00154 00155 } 00156 $watts = implode(' ',$watts); 00157 $out[] = "\t\t<$ns:widget $watts>"; 00158 if ( isset($widget['atts']) ){ 00159 $aatts = array(); 00160 foreach ($widget['atts'] as $akey=>$aval){ 00161 if (is_scalar($aval) ){ 00162 $aatts[] = $ans.':'.$akey.'="'.$this->xmlentities($aval).'"'; 00163 } 00164 00165 00166 } 00167 $aatts = implode(' ',$aatts); 00168 $out[] = "\t\t\t<$ns:html_atts $aatts />"; 00169 } 00170 $out[] = "\t\t</$ns:widget>"; 00171 $out[] = "\t</$ns:field>"; 00172 00173 } 00174 00175 foreach ($table->relationships() as $relationship){ 00176 $out[] = $this->toXML_Dataface_Relationship($relationship); 00177 } 00178 $out[] = "</$ns:table>"; 00179 } 00180 $this->markRequiredTableLoaded($table->tablename); 00181 return implode("\n", $out); 00182 } 00183 00184 00185 function toXML_Dataface_Relationship(&$relationship){ 00186 $ns = $this->ns; 00187 $ans = $this->atts_ns; 00188 $out = array(); 00189 $atts = array(); 00190 $name = $this->xmlentities($relationship->getName()); 00191 foreach ($relationship->_schema as $key=>$val){ 00192 if ( is_scalar($val) ){ 00193 $atts[] = $ans.':'.$key.'="'.$this->xmlentities($val).'"'; 00194 } 00195 } 00196 $sourceTable =& $relationship->getSourceTable(); 00197 $tablename = $sourceTable->tablename; 00198 $atts = implode(' ',$atts); 00199 $out[] = "\t<$ns:relationship id=\"tables.{$tablename}.relationships.{$name}\" name=\"$name\" $atts />"; 00200 return implode("\n", $out); 00201 } 00202 00203 function toXML_Dataface_Record(&$record){ 00204 00205 $ns = $this->ns; 00206 $ans = $this->atts_ns; 00207 $pns = $this->perms_ns; 00208 00209 $out = array(); 00210 $out[] = "\t\t<$ns:record id=\"".$this->xmlentities($record->getId())."\" table=\"".$record->_table->tablename."\">"; 00211 00212 $perms = $record->getPermissions(); 00213 $patts = array(); 00214 foreach ($perms as $pkey=>$pval){ 00215 $pkey = str_replace(' ', '_', $pkey); 00216 $patts[] = "$pns:$pkey=\"".$this->xmlentities($pval)."\""; 00217 } 00218 $patts = implode(' ', $patts); 00219 $out[] = "\t\t\t<$ns:permissions $patts/>"; 00220 00221 foreach ( $record->_table->fields() as $field){ 00222 $value = $record->val($field['name']); 00223 $dispVal = $record->display($field['name']); 00224 $this->addRequiredTable($field['table']); 00225 // Make sure that the table definition for this field is loaded. 00226 $out[] = "\t\t\t<$ns:record_value field=\"".$this->xmlentities($field['name'])."\">"; 00227 $perms = $record->getPermissions(array('field'=>$field['name'])); 00228 $patts = array(); 00229 foreach ($perms as $pkey=>$pval){ 00230 $pkey = str_replace(' ', '_', $pkey); 00231 $patts[] = "$pns:$pkey=\"".$this->xmlentities($pval)."\""; 00232 } 00233 $patts = implode(' ', $patts); 00234 $out[] = "\t\t\t\t<$ns:permissions $patts/>"; 00235 if ( $record->_table->isDate($field['name']) ){ 00236 $value= $dispVal; 00237 } 00238 00239 if ( @$field['vocabulary'] ) $valuelist =& $record->_table->getValuelist($field['vocabulary']); 00240 00241 if ( !is_array($value) ) $value = array($value); 00242 00243 foreach ($value as $vkey=>$vval){ 00244 // $vkey will be the value that is actually stored in the database. 00245 // $vval Will be the resulting value after joins and valuelists are factored in. 00246 // We output both to save from having to publish the entire valuelist to the client. 00247 $vkey=$vval; // Only fields that use vocabularies should have different key than value. 00248 if ( isset($valuelist) and isset($valuelist[$vval]) ){ 00249 00250 $vval = $valuelist[$vval]; 00251 } 00252 $out[] = "\t\t\t\t<$ns:value key=\"".$this->xmlentities($vkey)."\">".$this->xmlentities($vval)."</$ns:value>"; 00253 } 00254 unset($valuelist); 00255 00256 $out[] = "\t\t\t\t<$ns:display_value>".$this->xmlentities($dispVal)."</$ns:display_value>"; 00257 $out[] = "\t\t\t\t<$ns:html_value>".$this->xmlentities( $record->htmlValue($field['name']))."</$ns:html_value>"; 00258 $out[] = "\t\t\t</$ns:record_value>"; 00259 00260 00261 } 00262 00263 $out[] = "\t\t</$ns:record>"; 00264 $out = implode("\n", $out); 00265 return $out; 00266 00267 00268 } 00269 00270 function toXML_Dataface_QueryTool(&$tool){ 00271 $ns = $this->ns; 00272 $ans = $this->atts_ns; 00273 $out = array(); 00274 $tablename = $tool->_tablename; 00275 $tool->loadSet(); 00276 00277 00278 00279 $out[] = "<$ns:results source=\"".$this->xmlentities($tablename)."\" start=\"".$this->xmlentities($tool->start())."\" end=\"".$this->xmlentities($tool->end())."\" limit=\"".$this->xmlentities($tool->limit())."\" cursor=\"".$this->xmlentities($tool->cursor())."\" cardinality=\"".$this->xmlentities($tool->cardinality())."\" found=\"".$this->xmlentities($tool->found())."\" >"; 00280 $table =& Dataface_Table::loadTable($tablename); 00281 foreach ($table->fields() as $field){ 00282 if ( Dataface_PermissionsTool::checkPermission('view', $table, array('field'=>$field['name']))){ 00283 $this->addRequiredTable($tablename); 00284 $out[] = "\t<$ns:column table=\"".$this->xmlentities($tablename)."\">".$this->xmlentities($field['name'])."</$ns:column>"; 00285 } 00286 } 00287 00288 $it =& $tool->iterator(); 00289 while ($it->hasNext()){ 00290 $nex =& $it->next(); 00291 $out[] = $this->toXML_Dataface_Record($nex); 00292 unset($nex); 00293 } 00294 $out[] = "</$ns:results>"; 00295 return implode("\n", $out); 00296 } 00297 00298 function getInfo(){ 00299 $ns = $this->ns; 00300 $app =& Dataface_Application::getInstance(); 00301 00302 $allowed_fields = array('_auth/auth_type'=>true); 00303 if ( isset($app->_conf["xml_public_info"]) ){ 00304 $allowed_fields = array_merge($app->_conf['xml_public_info'], $allowed_fields); 00305 } 00306 $af = array(); 00307 foreach ($allowed_fields as $key=>$value){ 00308 $path = explode('/', $key); 00309 if ( count($path) == 1 ){ 00310 $af[$key] = $value; 00311 } else { 00312 $af[$path[0]][$path[1]] = $value; 00313 } 00314 00315 } 00316 00317 $out = array(); 00318 $out[] = "<$ns:config>"; 00319 foreach ( $app->_conf as $key=>$value){ 00320 if ( !@$af[$key] ) continue; 00321 $out[] = "\t<$ns:param><$ns:key>".$this->xmlentities($key)."</$ns:key>"; 00322 if ( is_scalar($value) ){ 00323 $out[] = "\t\t<$ns:value>".$this->xmlentities($value)."</$ns:value>"; 00324 } else { 00325 $out[] = "\t\t<$ns:value>"; 00326 foreach ($value as $vkey=>$vval){ 00327 if ( !@$af[$key][$vkey] ) continue; 00328 if ( strcasecmp($vkey,'password') === 0 ) continue; 00329 $out[] = "\t\t\t<$ns:param><$ns:key>".$this->xmlentities($vkey)."</$ns:key><$ns:value>".$this->xmlentities($vval)."</$ns:value></$ns:param>"; 00330 } 00331 $out[] = "\t\t</$ns:value>"; 00332 00333 } 00334 00335 $out[] = "\t</$ns:param>"; 00336 } 00337 $out[] = "</$ns:config>"; 00338 return implode("\n", $out); 00339 } 00340 00341 function header(){ 00342 $ns = $this->ns; 00343 $ans = $this->atts_ns; 00344 $pns = $this->perms_ns; 00345 $out = array(); 00346 $app =& Dataface_Application::getInstance(); 00347 header('Content-type: text/xml; charset='.$app->_conf['oe']); 00348 $out[] = "<?xml version=\"1.0\"?>"; 00349 $out[] = "<dataface_document xmlns:$ns=\"http://www.weblite.ca/dataface/2007/df\" xmlns:$ans=\"http://www.weblite.ca/dataface/2007/dfatts\" xmlns:$pns=\"http://www.weblite.ca/dataface/2007/dfperms\" xmlns:http=\"http://www.weblite.ca/dataface/2007/http\">"; 00350 return implode("\n", $out); 00351 00352 } 00353 00354 function footer(){ 00355 00356 return $this->requiredTablesToXML()."\n</dataface_document>"; 00357 } 00358 00359 function xmlentities($string) { 00360 return str_replace ( array ( '&', '"', "'", '<', '>', '' ), array ( '&' , '"', ''' , '<' , '>', ''' ), $string ); 00361 } 00362 }