_usrAcl = $usrAcl;
$this->_typeConverter = new Api_WfsGeomTypeConverter();
$this->_apiBaseUri = '';
}
public function setBaseUri($uri) {
$this->_apiBaseUri = $uri;
}
public function getBaseUri() {
return $this->_apiBaseUri;
}
public function getBaseNamespaceUri() {
$baseNsUri = $this->_apiBaseUri;
$protocolType = '';
if (!empty($baseNsUri)) {
if ('https://' == substr($baseNsUri, 0, 8)) {
$protocolType = 'https';
$baseNsUri = substr($baseNsUri, 8);
} else if ('http://' == substr($baseNsUri, 0, 7)) {
$protocolType = 'http';
$baseNsUri = substr($baseNsUri, 6);
}
}
if (!empty($baseNsUri)) {
if (false !== ($pos = strpos($baseNsUri, '/'))) {
$baseNsUri = substr($baseNsUri, 0, $pos);
}
}
return "{$protocolType}://{$baseNsUri}/wfs";
}
public function isAllowedFeatureType($nsPrefix, $type) {
if ('p5_' != substr($nsPrefix, 0, 3)) return false;
if ('p5_default_db' == $nsPrefix) {
$typeName = "p5_default_db:{$type}";
try {
$acl = $this->getAclFromTypeName($typeName);
} catch (Exception $e) {
return false;
}
if ($acl) {
return true;
}
} else if ('p5_objects' == $nsPrefix && 'File' == $type) {
return true;
}
return false;
}
/**
* @param string $typeName - 'p5_default_db:TEST_PERMS'
*/
public function getAclFromTypeName($typeName) {
$typeEx = explode(':', $typeName);
if (2 != count($typeEx)) throw new Api_WfsException("Could not get acl for '{$typeName}' - syntax error");
if ('p5_' != substr($typeEx[0], 0, 3)) throw new Api_WfsException("Could not get acl for '{$typeName}' - prefix error");
$sourceName = substr($typeEx[0], 3);
$objName = $typeEx[1];
$acl = $this->_usrAcl->getObjectAcl($sourceName, $objName);
if (!$acl) throw new Api_WfsException("Could not get acl for '{$typeName}'");
$forceTblAclInit = 0;//('1' == V::get('_force', '', $_GET));
$acl->init($forceTblAclInit);
return $acl;
}
public function _getCapabilities($wfsServerUrl, $serviceTitle, $serviceDescription) {
echo '';
?>
_getXmlNamespaceList(); ?>
_getXmlSchemaLocation(); ?>
version="1.0.0">
WFS
WFS, WMS
NONE
NONE
_printGetCapabilitiesXml($wfsServerUrl); ?>
_printDescribeFeatureTypeXml($wfsServerUrl); ?>
_printGetFeatureXml($wfsServerUrl); ?>
_printTransactionXml($wfsServerUrl); ?>
_printLockFeatureXml($wfsServerUrl); ?>
_printGetFeatureWithLockXml($wfsServerUrl); ?>
_printFeatureTypeListXml(); ?>
abs
abs_2
abs_3
abs_4
acos
AddCoverages
Aggregate
Area
area2
AreaGrid
asin
atan
atan2
BarnesSurface
between
boundary
boundaryDimension
Bounds
buffer
BufferFeatureCollection
bufferWithSegments
Categorize
ceil
Centroid
classify
Clip
CollectGeometries
Collection_Average
Collection_Bounds
Collection_Count
Collection_Max
Collection_Median
Collection_Min
Collection_Sum
Collection_Unique
Concatenate
contains
Contour
convert
convexHull
cos
Count
CropCoverage
crosses
dateFormat
dateParse
difference
dimension
disjoint
disjoint3D
distance
distance3D
double2bool
endAngle
endPoint
env
envelope
EqualInterval
equalsExact
equalsExactTolerance
equalTo
exp
exteriorRing
Feature
floor
geometryType
geomFromWKT
geomLength
getGeometryN
getX
getY
getz
greaterEqualThan
greaterThan
Grid
Heatmap
id
IEEEremainder
if_then_else
in10
in2
in3
in4
in5
in6
in7
in8
in9
InclusionFeatureCollection
int2bbool
int2ddouble
interiorPoint
interiorRingN
Interpolate
intersection
IntersectionFeatureCollection
intersects
intersects3D
isClosed
isCoverage
isEmpty
isLike
isNull
isometric
isRing
isSimple
isValid
isWithinDistance
isWithinDistance3D
Jenks
length
lessEqualThan
lessThan
list
log
LRSGeocode
LRSMeasure
LRSSegment
max
max_2
max_3
max_4
min
min_2
min_3
min_4
mincircle
minimumdiameter
minrectangle
modulo
MultiplyCoverages
Nearest
not
notEqualTo
numberFormat
numberFormat2
numGeometries
numInteriorRing
numPoints
octagonalenvelope
offset
overlaps
parameter
parseBoolean
parseDouble
parseInt
parseLong
pi
PointBuffers
pointN
PointStacker
PolygonExtraction
pow
property
PropertyExists
Quantile
Query
random
RangeLookup
RasterAsPointCollection
RasterZonalStatistics
Recode
RectangularClip
relate
relatePattern
Reproject
rint
round
round_2
roundDouble
ScaleCoverage
sdo_nn
setCRS
Simplify
sin
Snap
sqrt
StandardDeviation
startAngle
startPoint
strCapitalize
strConcat
strEndsWith
strEqualsIgnoreCase
strIndexOf
strLastIndexOf
strLength
strMatches
strPosition
strReplace
strStartsWith
strSubstring
strSubstringStart
strToLowerCase
strToUpperCase
strTrim
strTrim2
StyleCoverage
symDifference
tan
toDegrees
toRadians
touches
toWKT
Transform
union
UnionFeatureCollection
Unique
UniqueInterval
VectorToRaster
VectorZonalStatistics
vertices
within
getBaseNamespaceUri();
$listNs = array();
$listNs[] = 'xmlns:p5_default_db="' . $baseNsUri . '/default_db"';
$listNs[] = 'xmlns:p5_objects="' . $baseNsUri . '/objects"';
return implode("\n", $listNs);
}
public function _getXmlNamespaceList__OLD() {
$baseNsUri = $this->getBaseNamespaceUri();
$namespaceList = $this->_getSourceNsList();
$namespaceListOut = array();
foreach ($namespaceList as $nsObj) {
$ns = "p5_{$nsObj[0]}_{$nsObj[1]}";
$uri = "{$baseNsUri}/{$nsObj[0]}/{$nsObj[1]}";
$namespaceListOut[] = 'xmlns:' . $ns . '="' . $uri . '"';
}
return implode(' ', $namespaceListOut);
}
public function _getSourceNsList() {
$usrObjList = array();
$tblsAcl = $this->_usrAcl->getTablesAcl();
foreach ($tblsAcl as $tblAcl) {
$dataSourceName = 'default_db';// TODO: getSourceName
$tblName = $tblAcl->getName();
$usrObjList[] = array($dataSourceName, $tblName);
}
$usrObjList[] = array('objects', 'File');
return $usrObjList;
}
public function _printGetCapabilitiesXml($wfsServerUrl) {
?>
_getTableAclList();
foreach ($tblsAcl as $tblAcl) {
$dataSourceName = 'default_db';// TODO: getSourceName
$tblName = $tblAcl->getName();
$usrObjList[] = array($dataSourceName, $tblName);
$featureType = array();
$featureType['ns'] = "p5_{$dataSourceName}";
$featureType['Title'] = $tblAcl->getRawLabel();
$featureType['Abstract'] = $tblAcl->getRawOpis();
$featureType['Keywords'] = array();
$featureType['Keywords'][] = $tblAcl->getID();
$featureType['Keywords'][] = $tblName;
$featureType['Keywords'][] = $tblAcl->getRawLabel();
$featureType['Keywords'] = implode(", ", $featureType['Keywords']);
$featureType['SRS'] = "EPSG:4326";
$featureType['LatLongBoundingBox'] = array();// TODO: feature LatLongBoundingBox
$featureType['LatLongBoundingBox']['minx'] = "8.12328509871721";
$featureType['LatLongBoundingBox']['miny'] = "38.8575126897477";
$featureType['LatLongBoundingBox']['maxx'] = "9.838674658246807";
$featureType['LatLongBoundingBox']['maxy'] = "41.31378404137082";
$featureTypes[$tblName] = $featureType;
}
{// add p5_objects:File
Lib::loadClass('FileStorage');
$featureType = array();
$featureType['ns'] = "p5_objects";
$featureType['Title'] = "Pliki";
$featureType['Abstract'] = "Pliki";
$featureType['Keywords'] = "Pliki";
$featureType['SRS'] = "EPSG:4326";
// $featureType['LatLongBoundingBox'] = array();// TODO: feature LatLongBoundingBox
// $featureType['LatLongBoundingBox']['minx'] = "8.12328509871721";
// $featureType['LatLongBoundingBox']['miny'] = "38.8575126897477";
// $featureType['LatLongBoundingBox']['maxx'] = "9.838674658246807";
// $featureType['LatLongBoundingBox']['maxy'] = "41.31378404137082";
$featureTypes['File'] = $featureType;
}
/*
ppr06:AMBITIPAESAGGIO
AMBITIPAESAGGIO
features, AMBITIPAESAGGIO
EPSG:4326
*/
$featureTypesXml = '';
foreach ($featureTypes as $tblName => $feature) {
$featureTypesXml .= " " . '' . "\n";
$featureTypesXml .= " " . '' . "{$feature['ns']}:{$tblName}" . '' . "\n";
$featureTypesXml .= " " . '' . "{$feature['Title']}" . '' . "\n";
if (!empty($feature['Abstract'])) {
$featureTypesXml .= " " . '' . "{$feature['Abstract']}" . '' . "\n";
} else {
$featureTypesXml .= " " . '' . "\n";
}
if (!empty($feature['Keywords'])) {
$featureTypesXml .= " " . '' . "{$feature['Keywords']}" . '' . "\n";
} else {
$featureTypesXml .= " " . '' . "\n";
}
$featureTypesXml .= " " . '' . "{$feature['SRS']}" . '' . "\n";
if (!empty($feature['LatLongBoundingBox'])) {
$latLongBoundingBoxOut = array();
$latLongBoundingBoxOut[] = 'minx="' . $feature['LatLongBoundingBox']['minx'] . '"';
$latLongBoundingBoxOut[] = 'miny="' . $feature['LatLongBoundingBox']['miny'] . '"';
$latLongBoundingBoxOut[] = 'maxx="' . $feature['LatLongBoundingBox']['maxx'] . '"';
$latLongBoundingBoxOut[] = 'maxy="' . $feature['LatLongBoundingBox']['maxy'] . '"';
$featureTypesXml .= " " . '' . "\n";
}
$featureTypesXml .= " " . '' . "\n";
}
echo $featureTypesXml;
}
public function _parseTransactionXmlStruct($requestXml, $requestXmlTags) {
$DBG = (V::get('DBG_XML', '', $_GET) > 0);// TODO: Profiler
$rootTagName = V::get('tag', '', $requestXmlTags[0]);
if ('Transaction' != $rootTagName) {
throw new Api_WfsException("Parse Request XML Error - Missing Transaction as root xml tag", __LINE__, null, 'TransactionParseError', 'request');
}
// 1. convert request: wfs.transaction.convert-wfs-request.xsl
// 2. validate converted request: wfs.transaction-converted-request.xsd
// 3. execute request in data source
// ? acl check?
$usedSourceNsList = array();
$sourceNsList = $this->_getSourceNsList();
//$sourceNsList = array();
//foreach ($requestXmlTags[0]['attributes'] as $attrName => $attrValue) {
// if ('xmlns:p5_' == substr($attrName, 0, 9)) {
// $sourceNsList[substr($attrName, 6)] = $attrValue;
// }
//}
{// get used typeNames
$usedTypeNames = array();
//
foreach ($requestXmlTags as $tag) {
if ('Update' == $tag['tag'] && 'open' == $tag['type']) {
$typeName = $tag['attributes']['typeName'];
foreach ($sourceNsList as $nsInd => $ns) {
if ("p5_{$ns[0]}:{$ns[1]}" == $typeName) {
$usedSourceNsList[$nsInd] = $ns;
}
}
}
}
// TODO: check:
//
$lastTagName = '';
foreach ($requestXmlTags as $tag) {
if ('Insert' == $lastTagName) {
$typeName = $tag['tag'];
foreach ($sourceNsList as $nsInd => $ns) {
if ("{$ns[1]}" == $typeName) {
$usedSourceNsList[$nsInd] = $ns;
}
}
}
$lastTagName = $tag['tag'];
}
//
foreach ($requestXmlTags as $tag) {
if ('Delete' == $tag['tag'] && 'open' == $tag['type']) {
$typeName = $tag['attributes']['typeName'];
foreach ($sourceNsList as $nsInd => $ns) {
if ("p5_{$ns[0]}:{$ns[1]}" == $typeName) {
$usedSourceNsList[$nsInd] = $ns;
}
}
}
}
}
if (empty($usedSourceNsList)) {
throw new Api_WfsException("Parse Request XML Error - Empty source NS list", __LINE__, null, 'TransactionParseError', 'request');
}
$convertedTransaction = $this->_convertTransactionXml($requestXml, $usedSourceNsList);
if($DBG){echo 'L.' . __LINE__ . ' $convertedTransaction:';print_r($convertedTransaction);echo "\n";}
if (empty($convertedTransaction)) {
throw new Api_WfsException("Parse Request XML Error - Empty transaction", __LINE__, null, 'TransactionParseError', 'request');
}
if (!$this->_validateConvertedTransactionXml($convertedTransaction, $usedSourceNsList)) {
//
//
// 41
// 3
//
//
$transXml = @simplexml_load_string($convertedTransaction);
foreach ($transXml->children() as $funcXml) {
$funcName = substr($funcXml->getName(), 0, 6);// Insert... , Update... , Delete...
if (empty($funcXml['typeName'][0])) throw new Api_WfsException("Missing typeName for function '{$funcName}'", __LINE__, null, 'MissingTypeName', 'request');
$typeName = $funcXml['typeName'][0];
$acl = $this->getAclFromTypeName("p5_default_db:{$typeName}");
$primaryKey = $acl->getPrimaryKeyField();
$pkObject = null;
foreach ($funcXml->children() as $fieldXml) {
if ($primaryKey == $fieldXml->getName()) $pkObject = $fieldXml[0];
}
if ('Insert' == $funcName && $pkObject) $funcName = 'Update';
if ('Update' == $funcName) {// check perm W - skip $primaryKey
if (!$pkObject) throw new Api_WfsException("Missing primary key ({$primaryKey}) for action Update", __LINE__, null, 'MissingPrimaryKey', 'request');
$toUpdateFields = array();
foreach ($funcXml->children() as $fieldXml) {
if ($primaryKey == $fieldXml->getName()) continue;// skip primary key
$toUpdateFields[] = $fieldXml->getName();
}
if (empty($toUpdateFields)) throw new Api_WfsException("Missing fields to update", __LINE__, null, 'MissingFieldToUpdate', 'request');
$oldObject = $acl->getItem($pkObject);
if (!$oldObject) throw new Api_WfsException("Object '{$typeName}.{$pkObject}' not exists", __LINE__, null, 'ObjectNotExists', 'request');
if (!$acl->canWriteRecord($oldObject) && !$acl->hasPermSuperWrite()) {
throw new Api_WfsException("Access Denied to Update object '{$typeName}.{$pkObject}'", __LINE__, null, 'MissingObjectPermUpdate', 'request');
}
foreach ($toUpdateFields as $fieldName) {
$aclIdFld = $acl->getFieldIdByName($fieldName);
if (!$acl->isAllowed($aclIdFld, 'W', $oldObject)) {
throw new Api_WfsException("Access Denied to Update field '{$fieldName}' in object '{$typeName}.{$pkObject}'", __LINE__, null, 'MissingFieldPermWrite', 'request');
}
}
} else if ('Insert' == $funcName) {// check perm C
foreach ($funcXml->children() as $fieldXml) {
$fieldName = $fieldXml->getName();
$aclIdFld = $acl->getFieldIdByName($fieldXml->getName());
if (!$acl->isAllowed($aclIdFld, 'C')) {
throw new Api_WfsException("Access Denied to Create field '{$fieldName}' in object '{$typeName}.{$pkObject}'", __LINE__, null, 'MissingFieldPermCreate', 'request');
}
}
} else {
// TODO: Delete, ... ?
}
}
throw new Exception("Parse Request xml error #" . __LINE__ . ": schema validation failed");
}
$parserXml = xml_parser_create();
xml_parser_set_option($parserXml, XML_OPTION_CASE_FOLDING, 0);
xml_parser_set_option($parserXml, XML_OPTION_SKIP_WHITE, 1);
if (0 == xml_parse_into_struct($parserXml, $convertedTransaction, $tags)) {
throw new Exception("Parse Request xml error #" . __LINE__ . ": parse converted transaction failed");
}
xml_parser_free($parserXml);
if (empty($tags)) {
throw new Exception("Parse Request xml error #" . __LINE__ . ": parse converted transaction returns empty structure");
}
// [{"tag":"Transaction","type":"open","level":1,"attributes":{"version":"1.0.0","service":"WFS"}},
// {"tag":"Update","type":"open","level":2,"attributes":
// {"typeName":"p5_default_db_13051:TEST_PERMS","featureId":"TEST_PERMS.25"}},
// {"tag":"PARENT_ID","type":"complete","level":3,"value":"0"},
// {"tag":"Update","type":"close","level":2},
// {"tag":"Transaction","type":"close","level":1}]
if($DBG){echo "\ntags L." . __LINE__ . ":\n"; print_r($tags);echo "\n";}
$actionTag = null;
$prevTagName = '';
$theGeomField = 'the_geom';// TODO: get the geom field name from acl
$itemPatchs = array();
foreach ($tags as $tag) {
switch (substr($tag['tag'], 0, 6)) {
case 'Transa': continue; break;// Transaction
case 'Update':
case 'Insert':
case 'Delete':
case 'Native':
if ('open' == $tag['type'] // Insert, Update
|| 'complete' == $tag['type'] // Delete
) {
if($DBG){echo "\ntags loop 1 - tag: L." . __LINE__ . ":\n"; print_r($tag);echo "\n";}
$actionTag = array();
$actionTag['tag'] = substr($tag['tag'], 0, 6);
$actionTag['typeName'] = $tag['attributes']['typeName'];
if ('Insert' == substr($tag['tag'], 0, 6)) {
$typeNsPrefix = 'p5_default_db';
if (!empty($tag['attributes']['typeNsUri'])) {
$baseNsUri = $this->getBaseNamespaceUri();
if ("{$baseNsUri}/objects" == $tag['attributes']['typeNsUri']) {
$typeNsPrefix = 'p5_objects';
}
}
$actionTag['typeName'] = "{$typeNsPrefix}:{$tag['attributes']['typeName']}";
}
$featureEx = explode('.', $tag['attributes']['featureId'], 2);
$actionTag['featureId'] = $featureEx[1];
if ('Update' == substr($tag['tag'], 0, 6) && empty($actionTag['featureId'])) {
throw new Api_WfsException("Syntax error - could not read feature id!");
}
if ('Delete' == substr($tag['tag'], 0, 6) && empty($actionTag['featureId'])) {
throw new Api_WfsException("Syntax error - could not read feature id!");
}
if ('complete' == $tag['type']) {
$itemPatchs[] = $actionTag;
$actionTag = null;
} else {
$actionTag['itemPatch'] = array();
}
} else {
$itemPatchs[] = $actionTag;
$actionTag = null;
}
break;
default: {// fields
if($DBG){echo "\ntags loop 2 - tag: L." . __LINE__ . ":\n"; print_r($tag);echo "\n";}
if (3 != $tag['level'] && 'close' == $tag['type']) {
$actionTag = null;
}
if (3 != $tag['level']) continue;
if (empty($actionTag)) continue;
if ('Update' == $actionTag['tag']) {
if ($theGeomField == $tag['tag']) {
$actionTag['itemPatch'][$tag['tag']] = $this->_typeConverter->convertGmlCoordinatesToWkt($tag['value']);
} else {
$actionTag['itemPatch'][$tag['tag']] = $tag['value'];
}
}
else if ('Insert' == $actionTag['tag']) {
if ($theGeomField == $tag['tag']) {
$actionTag['itemPatch'][$tag['tag']] = $this->_typeConverter->convertGmlCoordinatesToWkt($tag['value']);
} else {
$actionTag['itemPatch'][$tag['tag']] = $tag['value'];
}
}
else if ('Delete' == $actionTag['tag']) {
}
}
}
if (empty($prevTagName)) $prevTagName = $tag['tag'];
}
if($DBG){echo "\nTODO: itemPatchs L." . __LINE__ . ":\n"; print_r($itemPatchs);echo "\n";}
if($DBG){echo "\nTODO: _user_id L." . __LINE__ . " '{$this->_usrAcl->_user_id}'" . "\n";}
$changesList = array();
if (!empty($itemPatchs)) {
foreach ($itemPatchs as $itemPatchInfo) {
if($DBG){echo "L." . __LINE__ . " itemPatchInfo: {typeName:'{$itemPatchInfo['typeName']}'}:\n";print_r($itemPatchInfo);}
$acl = $this->getAclFromTypeName($itemPatchInfo['typeName']);
if ('Delete' == $itemPatchInfo['tag']) {
$itemPatch = array();
$itemPatch[$acl->getPrimaryKeyField()] = $itemPatchInfo['featureId'];
$itemPatch['the_geom'] = 'NULL';
} else {
if (empty($itemPatchInfo['itemPatch'])) continue;
$itemPatch = $itemPatchInfo['itemPatch'];
if ('Update' == $itemPatchInfo['tag']) {
$itemPatch[$acl->getPrimaryKeyField()] = $itemPatchInfo['featureId'];
}
else if ('Insert' == $itemPatchInfo['tag']) {
if (!empty($itemPatch[$acl->getPrimaryKeyField()])) {
$itemPatchInfo['featureId'] = $itemPatch[$acl->getPrimaryKeyField()];
}
else {
//throw new Exception("TODO: Insert #" . __LINE__ . ": Create new record");
}
}
}
if($DBG){echo "L." . __LINE__ . " TODO '" . ($itemPatchInfo['tag'])? 'Insert' : 'Update' . "' itemPatch:\n";print_r($itemPatch);}
if ('Insert' == $itemPatchInfo['tag'] && empty($itemPatch[$acl->getPrimaryKeyField()])) {
$newId = $acl->addItem($itemPatch);
$changesList[$newId] = array('Status'=>(($newId > 0)? 'SUCCESS' : 'FAILED'), 'Message'=>"created {$newId}.");
if ($newId > 0) {
$changesList[$newId]['fid'] = $acl->getName() . '.' . $newId;
}
if($DBG){echo "created {$newId}.\n";}
} else {
$affected = $acl->updateItem($itemPatch);
$changesList[$itemPatchInfo['featureId']] = array('Status'=>(($affected >= 0)? 'SUCCESS' : 'FAILED'), 'Message'=>"affected {$affected}.");
if($DBG){echo "affected {$affected}.\n";}
}
}
//throw new Exception("TODO: run query #" . __LINE__ . " \nitemPatchs:\n" . json_encode($itemPatchs) . " \ntags:\n" . json_encode($tags) . "\n");
}
else {
throw new Exception("Parse Request xml error #" . __LINE__ . ": Nothing to change");
}
return $this->_transactionResponse($changesList);
}
public function _transactionResponse($changesList) {
//
//
// : SUCCESS / FAILED / PARTIAL
// [ $change) {
if ('FAILED' == $change['Status']) {
$statusIsFailed = true;
}
if ('SUCCESS' == $change['Status'] && !empty($change['fid'])) {
$createdFetureId[] = $change['fid'];
}
if (!empty($change['Message'])) $messageTag .= "Feature '{$featureId}' {$change['Status']}: {$change['Message']}\n";
}
$statusTag = ($statusIsFailed)? 'FAILED' : 'SUCCESS';
$statusTag = "";
$messageTag = '';//"{$messageTag}";
/* Example:
*/
// TODO: build xml by DOMDocument
// TODO: xsi:schemaLocation="http://www.opengis.net/wfs http://localhost:8080/geoserver/schemas/wfs/1.0.0/WFS-transaction.xsd"
$wfsInsertResult = '';
if (!empty($createdFetureId)) {
$wfsInsertResult = "\n\n";
foreach ($createdFetureId as $fid) {
$wfsInsertResult .= '' . "\n";
}
$wfsInsertResult .= "\n\n";
EOF;
}
$tranRes = <<
{$wfsInsertResult}
{$statusTag}
{$messageTag}
EOF;
return $tranRes;
}
public function _convertTransactionXml($requestXmlString, $sourceNsList) {
$DBG = (V::get('DBG_XSL', '', $_GET) > 0);// TODO: Profiler
if($DBG){echo 'L.' . __LINE__ . ' sourceNsList:';print_r($sourceNsList);echo "\n";}
$updateActionsXsd = array();
$insertActionsXsd = array();
$deleteActionsXsd = array();
//
foreach ($sourceNsList as $nsInd => $sourceNs) {
//
$theGeomField = 'the_geom';// TODO: get from fields list
$typeName = "p5_{$sourceNs[0]}:{$sourceNs[1]}";
if($DBG){echo 'L.' . __LINE__ . ' typeName:';print_r($typeName);echo "\n";}
$updateElementName = "UpdateNs{$nsInd}";
$geomCoordsUpdateXpath = "//wfs:Value/*/gml:outerBoundaryIs/gml:LinearRing/gml:coordinates";
$geomCoordsInsertXpath = "//*/gml:outerBoundaryIs/gml:LinearRing/gml:coordinates";
$acl = $this->getAclFromTypeName($typeName);
$geomType = $acl->getGeomFieldType($theGeomField);
if ('polygon' == $geomType) {
$geomCoordsUpdateXpath = ".//wfs:Value/*/gml:outerBoundaryIs/gml:LinearRing/gml:coordinates";
$geomCoordsUpdateXpath = "(())";
$geomCoordsInsertXpath = ".//*/gml:outerBoundaryIs/gml:LinearRing/gml:coordinates";
$geomCoordsInsertXpath = "(())";
} else if ('linestring' == $geomType) {
$geomCoordsUpdateXpath = ".//wfs:Value/*/gml:coordinates";
$geomCoordsUpdateXpath = "()";
$geomCoordsInsertXpath = ".//*/gml:coordinates";
$geomCoordsInsertXpath = "()";
} else if ('point' == $geomType) {
$geomCoordsUpdateXpath = ".//wfs:Value/*/gml:coordinates";
$geomCoordsUpdateXpath = "()";
$geomCoordsInsertXpath = ".//*/gml:coordinates";
$geomCoordsInsertXpath = "()";
}
$actionXsd = <<
{$geomCoordsUpdateXpath}
EOF;
$updateActionsXsd[] = $actionXsd;
$typeName = "{$sourceNs[1]}";//"p5_{$sourceNs[0]}:{$sourceNs[1]}";
$insertElementName = "InsertNs{$nsInd}";
$actionXsd = <<
{$geomCoordsInsertXpath}
EOF;
$insertActionsXsd[] = $actionXsd;
$deleteElementName = "DeleteNs{$nsInd}";
$typeName = "p5_{$sourceNs[0]}:{$sourceNs[1]}";
$actionXsd = <<
EOF;
$deleteActionsXsd[] = $actionXsd;
}
if (!empty($updateActionsXsd)) {
$updateActionsXsd = implode("\n", $updateActionsXsd);
$updateActionsXsd = <<
{$updateActionsXsd}
EOF;
} else {
$updateActionsXsd = '';
}
if (!empty($insertActionsXsd)) {
$insertActionsXsd = implode("\n", $insertActionsXsd);
$insertActionsXsd = <<
{$insertActionsXsd}
EOF;
} else {
$insertActionsXsd = '';
}
if (!empty($deleteActionsXsd)) {
$deleteActionsXsd = implode("\n", $deleteActionsXsd);
$deleteActionsXsd = <<
{$deleteActionsXsd}
EOF;
} else {
$deleteActionsXsd = '';
}
$convertTransactionXslString = '';
$convertTransactionXslString .= <<
{$updateActionsXsd}
{$insertActionsXsd}
{$deleteActionsXsd}
EOF;
if($DBG){echo 'L.' . __LINE__ . ' $convertTransactionXslString:' . $convertTransactionXslString . "\n";}
$requestXml = new DOMDocument();
$requestXml->loadXml($requestXmlString);
$convertTransactionXsl = new DOMDocument();
$convertTransactionXsl->loadXml($convertTransactionXslString);
$proc = new XSLTProcessor();
$proc->importStylesheet($convertTransactionXsl);
return $proc->transformToXML($requestXml);
}
public function _validateConvertedTransactionXml($convertedTransaction, $sourceNsList) {
$DBG = (V::get('DBG_XSD', '', $_GET) > 0);// TODO: Profiler
if($DBG){echo 'L.' . __LINE__ . ' sourceNsList:';print_r($sourceNsList);echo "\n";}
$dom = new DOMDocument('1.0', 'utf-8');
$dom->formatOutput = true;
$dom->preserveWhiteSpace = false;
$rootNode = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:schema');
$dom->appendChild($rootNode);
// $rootNode->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:gml', 'http://www.opengis.net/gml');
// $rootNode->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:' . $wfsNs, $wfsNsUri);
$rootNode->setAttribute('elementFormDefault', 'qualified');
// $rootNode->setAttribute('targetNamespace', $wfsNsUri);
$rootNode->setAttribute('version', '1.0');
{//
$elNode = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:element');
$rootNode->appendChild($elNode);
$elNode->setAttribute('name', 'Transaction');
$elNode->setAttribute('type', 'TransactionType');
$cTypeNode = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:complexType');
$rootNode->appendChild($cTypeNode);
$cTypeNode->setAttribute('name', 'TransactionType');
$seqNode = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:sequence');
$cTypeNode->appendChild($seqNode);
$choiceNode = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:choice');
$seqNode->appendChild($choiceNode);
$choiceNode->setAttribute('minOccurs', '0');
$choiceNode->setAttribute('maxOccurs', 'unbounded');
//
foreach ($sourceNsList as $nsInd => $sourceNs) {
$typeName = "p5_{$sourceNs[0]}:{$sourceNs[1]}";
$updateElementName = "UpdateNs{$nsInd}";
$updateElementType = "UpdateNs{$nsInd}ElementType";
$updateElemNode = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:element');
$choiceNode->appendChild($updateElemNode);
$updateElemNode->setAttribute('name', $updateElementName);
$updateElemNode->setAttribute('type', $updateElementType);
}
//
foreach ($sourceNsList as $nsInd => $sourceNs) {
$typeName = "p5_{$sourceNs[0]}:{$sourceNs[1]}";
$insertElementName = "InsertNs{$nsInd}";
$insertElementType = "InsertNs{$nsInd}ElementType";
$insertElemNode = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:element');
$choiceNode->appendChild($insertElemNode);
$insertElemNode->setAttribute('name', $insertElementName);
$insertElemNode->setAttribute('type', $insertElementType);
}
//
foreach ($sourceNsList as $nsInd => $sourceNs) {
$typeName = "p5_{$sourceNs[0]}:{$sourceNs[1]}";
$deleteElementName = "DeleteNs{$nsInd}";
$deleteElementType = "DeleteNs{$nsInd}ElementType";
$deleteElemNode = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:element');
$choiceNode->appendChild($deleteElemNode);
$deleteElemNode->setAttribute('name', $deleteElementName);
$deleteElemNode->setAttribute('type', $deleteElementType);
}
//
$attrNode = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:attribute');
$cTypeNode->appendChild($attrNode);
$attrNode->setAttribute('name', 'version');
$attrNode->setAttribute('type', 'xsd:string');
$attrNode->setAttribute('use', 'required');
$attrNode->setAttribute('fixed', '1.0.0');
$attrNode = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:attribute');
$cTypeNode->appendChild($attrNode);
$attrNode->setAttribute('name', 'service');
$attrNode->setAttribute('type', 'xsd:string');
$attrNode->setAttribute('use', 'required');
$attrNode->setAttribute('fixed', 'WFS');
}
foreach ($sourceNsList as $nsInd => $sourceNs) {
$transactionTypesList = array();
$transactionTypesList[] = 'Update';
$transactionTypesList[] = 'Insert';
foreach ($transactionTypesList as $transactionType) {
$typeName = "p5_{$sourceNs[0]}:{$sourceNs[1]}";
if($DBG){echo 'L.' . __LINE__ . ' TODO: get acl typeName:';print_r($typeName);echo "\n";}
$acl = $this->getAclFromTypeName($typeName);
$updateElementName = "{$transactionType}Ns{$nsInd}";
$updateElementType = "{$transactionType}Ns{$nsInd}ElementType";
/*
*/
$updateTypeNode = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:complexType');
$rootNode->appendChild($updateTypeNode);
$updateTypeNode->setAttribute('name', $updateElementType);
{
$seqNode = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:all');
$updateTypeNode->appendChild($seqNode);
{
$pKeyField = $acl->getPrimaryKeyField();
$fldList = $this->_getFieldListFromAcl($acl);
// fields without geometry fields
foreach ($fldList as $fldName) {
if ($acl->isGeomField($fldName)) continue;
$elNode = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:element');
$seqNode->appendChild($elNode);
$elNode->setAttribute('name', $fldName);
$minOccurs = 0;
if ($pKeyField == $fldName) {
$minOccurs = '1';
} else {
$minOccurs = '0';
}
$elNode->setAttribute('minOccurs', $minOccurs);
$fldType = null;
if ($acl->isIntegerField($fldName)) {
$fldType = 'xsd:integer';
}
else if ($acl->isDecimalField($fldName)) {
$fldType = 'xsd:decimal';
}
else if ($acl->isDateField($fldName)) {
$fldType = 'xsd:date';
}
else if ($acl->isDateTimeField($fldName)) {
// $fldType = 'xsd:dateTime';
$fldType = null;// 'xsd:string';
$patternDataTime = "(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2})(:(\d{2}))?";
//
//
//
//
//
//
//
$simpleTypeNode = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:simpleType');
$restrictionNode = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:restriction');
$patternNode = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:pattern');
$restrictionNode->setAttribute('base', 'xsd:string');
$patternNode->setAttribute('value', $patternDataTime);
$restrictionNode->appendChild($patternNode);
$simpleTypeNode->appendChild($restrictionNode);
$elNode->appendChild($simpleTypeNode);
// continue;// TODO: ? below added nillable = true, minOccurs = 0, type = $fldType
}
else if ($acl->isBinaryField($fldName)) {
$fldType = 'xsd:base64Binary';
}
else {
$fldType = 'xsd:string';
}
if ($fldType) $elNode->setAttribute('type', $fldType);
$elNode->setAttribute('nillable', 'true');
$elNode->setAttribute('minOccurs', '0');
}
// only geometry fields
foreach ($fldList as $fldName) {
if (!$acl->isGeomField($fldName)) continue;
$elNode = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:element');
$seqNode->appendChild($elNode);
$elNode->setAttribute('name', $fldName);
$minOccurs = 0;
if ($pKeyField == $fldName) {
$minOccurs = '1';
} else {
$minOccurs = '0';
}
$elNode->setAttribute('minOccurs', $minOccurs);
if ($acl->isGeomField($fldName)) {
//$fldType = 'gml:GeometryPropertyType';
// TODO: use geom types from gml to wkt
// TODO: pattern wg atrybutów gml:coordinates decimal="." cs="," ts=" "
$patternWkt = '';// TODO: error if empty - unsupported geom type
$patternNum = '\-?\d+\.?\d*';
$patternPoint = $patternNum . ',' . $patternNum;
$patternPoints = '(' . $patternPoint . ')( ' . $patternPoint . ')+';
$geomType = $acl->getGeomFieldType($fldName);
if ('polygon' == $geomType) {
// [a-zA-Z]+\(\((\-?\d+\.?\d*,\-?\d+\.?\d*)( (\-?\d+\.?\d*,\-?\d+\.?\d*))+\)\)
$patternWkt = '[a-zA-Z]+\(\(' . $patternPoints . '\)\)';
} else if ('linestring' == $geomType) {
// [a-zA-Z]+\((\-?\d+\.?\d*,\-?\d+\.?\d*)( (\-?\d+\.?\d*,\-?\d+\.?\d*))+\)
$patternWkt = '[a-zA-Z]+\(' . $patternPoints . '\)';
} else if ('point' == $geomType) {
// [a-zA-Z]+\(\-?\d\.?\d*,\-?\d\.?\d*\)
$patternWkt = '[a-zA-Z]+\(' . $patternPoint . '\)';
}
$simpleTypeNode = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:simpleType');
$restrictionNode = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:restriction');
$patternNode = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:pattern');
$restrictionNode->setAttribute('base', 'xsd:string');
$patternNode->setAttribute('value', $patternWkt);
$restrictionNode->appendChild($patternNode);
$simpleTypeNode->appendChild($restrictionNode);
$elNode->appendChild($simpleTypeNode);
}
$elNode->setAttribute('nillable', 'true');
$elNode->setAttribute('minOccurs', '0');
}
}
}
$attrNode = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:attribute');
$updateTypeNode->appendChild($attrNode);
$attrNode->setAttribute('name', 'typeName');
$attrNode->setAttribute('type', 'xsd:token');
$attrNode->setAttribute('use', 'required');
if ($transactionType == 'Insert') {
$attrNode = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:attribute');
$updateTypeNode->appendChild($attrNode);
$attrNode->setAttribute('name', 'typeNsUri');
$attrNode->setAttribute('type', 'xsd:anyURI');
$attrNode->setAttribute('use', 'required');
}
if ($transactionType == 'Update') {
$attrNode = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:attribute');
$updateTypeNode->appendChild($attrNode);
$attrNode->setAttribute('name', 'featureId');
$attrNode->setAttribute('use', 'required');
$sTypeNode = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:simpleType');
$attrNode->appendChild($sTypeNode);
$resNode = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:restriction');
$sTypeNode->appendChild($resNode);
$resNode->setAttribute('base', 'xsd:string');
$patternNode = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:pattern');
$resNode->appendChild($patternNode);
$patternNode->setAttribute('value', '[a-zA-Z_][a-zA-Z0-9_]*\.[0-9]*');
}
}
{// 'Delete'
$typeName = "p5_{$sourceNs[0]}:{$sourceNs[1]}";
$acl = $this->getAclFromTypeName($typeName);
$deleteElementType = "DeleteNs{$nsInd}ElementType";
$deleteTypeNode = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:complexType');
$rootNode->appendChild($deleteTypeNode);
$deleteTypeNode->setAttribute('name', $deleteElementType);
/* */
$attrNode = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:attribute');
$deleteTypeNode->appendChild($attrNode);
$attrNode->setAttribute('name', 'typeName');
$attrNode->setAttribute('type', 'xsd:token');
$attrNode->setAttribute('use', 'required');
/* */
$attrNode = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:attribute');
$deleteTypeNode->appendChild($attrNode);
$attrNode->setAttribute('name', 'featureId');
$attrNode->setAttribute('use', 'required');
$sTypeNode = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:simpleType');
$attrNode->appendChild($sTypeNode);
$resNode = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:restriction');
$sTypeNode->appendChild($resNode);
$resNode->setAttribute('base', 'xsd:string');
$patternNode = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:pattern');
$resNode->appendChild($patternNode);
$patternNode->setAttribute('value', '[a-zA-Z_][a-zA-Z0-9_]*\.[0-9]*');
}
}
$validateConvertedTransactionXsdString = $dom->saveXml();
if($DBG){echo 'L.' . __LINE__ . ' $validateConvertedTransactionXsdString:';print_r($validateConvertedTransactionXsdString);echo "\n";}
$reqXml = new DOMDocument();
$reqXml->loadXml($convertedTransaction);
// TODO: fetch PHP Warning: DOMDocument::schemaValidateSource(): Element 'PARENT_ID': 'abc' is not a valid value of the atomic type 'xs:integer'.
return $reqXml->schemaValidateSource($validateConvertedTransactionXsdString);
}
public function _getDescribeFeatureType($nsPrefix, $type, $simple = true) {
return $this->_getDescribeFeatureTypes(array(array($nsPrefix, $type)), $simple);
}
public function _parseDescribeFeatureTypeRequest($reqContent, $simple = true) {
$parserXml = xml_parser_create();
xml_parser_set_option($parserXml, XML_OPTION_CASE_FOLDING, 0);
xml_parser_set_option($parserXml, XML_OPTION_SKIP_WHITE, 1);
if (0 == xml_parse_into_struct($parserXml, $reqContent, $tags)) {
throw new Exception("Error parsing xml");
}
xml_parser_free($parserXml);
if (empty($tags)) {
throw new Exception("Empty structure from request");
}
$rootTagName = V::get('tag', '', $tags[0]);
if ('DescribeFeatureType' != $rootTagName) {
throw new Api_WfsException("Wrong xml root tag '{$rootTagName}' #" . __LINE__, 501);
}
$requestXmlTags = $tags;
$DBG = (V::get('DBG_XML', '', $_GET) > 0);// TODO: Profiler
$rootTagName = V::get('tag', '', $requestXmlTags[0]);
if ('DescribeFeatureType' != $rootTagName) {
throw new Exception("Parse Request xml error #" . __LINE__);
}
/*[1] => Array(
[tag] => TypeName
[type] => complete
[level] => 2
[value] => p5_default_db:Rozdzielcza_rurociag_wsg84)
*/
$typeNames = array();
$totalTypes = count($requestXmlTags) - 1;
for ($i = 1; $i < $totalTypes; $i++) {
if($DBG){echo "TAG[{$i}]:" . json_encode($requestXmlTags[$i]) . "\n";}
$typeNames[] = explode(':', $requestXmlTags[$i]['value'], 2);
}
//echo "typeNames: " . json_encode($typeNames) . "\n";
return $this->_getDescribeFeatureTypes($typeNames, $simple);
}
public function _getDescribeFeatureAllTypes($simple = true) {
$db = DB::getDB();
$idDefaultDB = $db->_zasob_id;
$tblsAcl = $this->_getTableAclList();
foreach ($tblsAcl as $tblAcl) {
$dataSourceName = 'default_db';// TODO: getSourceName
$tblName = $tblAcl->getName();
$typeNames[] = array("p5_{$dataSourceName}", $tblName);
}
$typeNames[] = array("p5_objects", 'File');
return $this->_getDescribeFeatureTypes($typeNames, $simple);
}
// @param $typeNames = array( array( $nsPrefix, $type ) )
public function _getDescribeFeatureTypes($typeNames, $simple = true) {
if (empty($typeNames)) throw new HttpException("Feature Type Names not defined", 400);
$this->DBG("types:" . json_encode($typeNames), __LINE__, __FUNCTION__, __CLASS__);
$baseNsUri = $this->getBaseNamespaceUri();
$rootWfsNs = 'p5';
$rootWfsNsUri = "{$baseNsUri}";
$wfsNs = 'p5_default_db';
$wfsNsUri = "{$baseNsUri}/default_db";
$featureTypeUri = $this->getBaseUri() . "?SERVICE=WFS&VERSION=1.0.0&REQUEST=DescribeFeatureType";
header('Content-type: application/xml');
//
//
$dom = new DOMDocument('1.0', 'utf-8');
$dom->formatOutput = true;
$dom->preserveWhiteSpace = false;
$rootNode = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:schema');
$dom->appendChild($rootNode);
$rootNode->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:gml', 'http://www.opengis.net/gml');
$rootNode->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:' . $wfsNs, $wfsNsUri);
$rootNode->setAttributeNS('http://www.w3.org/2000/xmlns/', "xmlns:{$rootWfsNs}", $rootWfsNsUri);
$rootNode->setAttribute('elementFormDefault', 'qualified');
$rootNode->setAttribute('targetNamespace', $wfsNsUri);
{//
$elNode = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:import');
$rootNode->appendChild($elNode);
$elNode->setAttribute('namespace', "http://www.opengis.net/gml");
$elNode->setAttribute('schemaLocation', $this->getBaseUri() . "/../../../schema/gml/2.1.2/feature.xsd");
}
foreach ($typeNames as $typeNameEx) {
$nsPrefix = $typeNameEx[0];
$type = $typeNameEx[1];
$typeName = "{$nsPrefix}:{$type}";
$acl = $this->getAclFromTypeName($typeName);
if (!$this->isAllowedFeatureType($nsPrefix, $type)) {
throw new Api_WfsException("Could not find type: " . htmlspecialchars($type));
}
$typeName = $type . 'Type';
$fldList = $this->_getFieldListFromAcl($acl);
$cTypeNode = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:complexType');
$rootNode->appendChild($cTypeNode);
$cTypeNode->setAttribute('name', $typeName);
if (!$simple) {
$idZasob = $acl->getID();
$cTypeNode->setAttributeNS($rootWfsNsUri, "{$rootWfsNs}:web_link", Request::getPathUri() . "index.php?MENU_INIT=VIEWTABLE_AJAX&ZASOB_ID={$idZasob}");
}
$cConNode = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:complexContent');
$cTypeNode->appendChild($cConNode);
$extNode = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:extension');
$cConNode->appendChild($extNode);
$extNode->setAttribute('base', 'gml:AbstractFeatureType');
$seqNode = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:sequence');
$extNode->appendChild($seqNode);
//
$pKeyField = $acl->getPrimaryKeyField();
$p5Attributes = ($simple)? array() : $acl->getAttributesFromZasoby();
foreach ($fldList as $idZasob => $fldName) {
$elNode = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:element');
$seqNode->appendChild($elNode);
$elNode->setAttribute('name', $fldName);
$minOccurs = 0;
if ($pKeyField == $fldName) {
$minOccurs = '1';
} else {
$minOccurs = '0';
}
$elNode->setAttribute('minOccurs', $minOccurs);
$elNode->setAttribute('maxOccurs', '1');
$elNode->setAttribute('nillable', 'true');
$fldType = 'xsd:string';
if ($acl->isIntegerField($fldName)) {
$fldType = 'xsd:integer';
}
else if ($acl->isDecimalField($fldName)) {
$fldType = 'xsd:decimal';
}
else if ($acl->isDateField($fldName)) {
$fldType = 'xsd:date';
}
else if ($acl->isDateTimeField($fldName)) {
$fldType = 'xsd:dateTime';
}
else if ($acl->isGeomField($fldName)) {
//$fldType = 'gml:GeometryPropertyType';
$geomType = $acl->getGeomFieldType($fldName);
if ('polygon' == $geomType) {
$fldType = 'gml:PolygonPropertyType';
} else if ('point' == $geomType) {
$fldType = 'gml:PointPropertyType';
} else if ('linestring' == $geomType) {
$fldType = 'gml:LineStringPropertyType';
} else {
$fldType = 'gml:GeometryPropertyType';
}
}
else if ($acl->isEnumerationField($fldName)) {
$fldType = ($simple)? 'xsd:string' : "{$nsPrefix}:{$fldName}Type";
}
else if ($acl->isBinaryField($fldName)) {
$fldType = 'xsd:base64Binary';
}
$elNode->setAttribute('type', $fldType);
if (!$simple) {
if (!empty($p5Attributes[$fldName])) {
$p5attrs = $p5Attributes[$fldName];
if (!empty($p5attrs['id_zasob'])) $elNode->setAttributeNS($rootWfsNsUri, "{$rootWfsNs}:id_zasob", $p5attrs['id_zasob']);
if (!empty($p5attrs['label'])) $elNode->setAttributeNS($rootWfsNsUri, "{$rootWfsNs}:label", $p5attrs['label']);
if (!empty($p5attrs['description'])) $elNode->setAttributeNS($rootWfsNsUri, "{$rootWfsNs}:description", $p5attrs['description']);
}
if ($acl->hasFieldPerm($idZasob, 'W')) $elNode->setAttributeNS($rootWfsNsUri, "{$rootWfsNs}:allow_write", "true");
if ($acl->hasFieldPerm($idZasob, 'C')) $elNode->setAttributeNS($rootWfsNsUri, "{$rootWfsNs}:allow_create", "true");
if (!$acl->hasFieldPerm($idZasob, 'R')) $elNode->setAttributeNS($rootWfsNsUri, "{$rootWfsNs}:allow_read", "false");
}
}
$elNode = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:element');
$rootNode->appendChild($elNode);
$elNode->setAttribute('name', $type);
$elNode->setAttribute('type', $wfsNs . ':' . $typeName);
if ($simple) {
$elNode->setAttribute('substitutionGroup', 'gml:_Feature');
} else {
$elNode->setAttribute('substitutionGroup', 'gml:AbstractFeature');
}
if (!$simple) {
foreach ($fldList as $fldName) {
if ($acl->isEnumerationField($fldName)) {
$enum = $acl->getEnumerations($fldName);
$stNode = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:simpleType');
$stNode->setAttribute('name', "{$fldName}Type");//"{$nsPrefix}:{$fldName}Type");
$rootNode->appendChild($stNode);
$resNode = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:restriction');
$stNode->appendChild($resNode);
$resNode->setAttribute('base', 'xsd:string');
// TODO: if (!empty($p5Attributes[$fldName]['valuesMap'])) -> show only this values
foreach ($enum as $val => $label) {
$enumNode = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:enumeration');
$resNode->appendChild($enumNode);
$enumNode->setAttribute('value', "{$val}");
if (!empty($p5Attributes[$fldName]['valuesMap'][$val])) {
$enumNode->setAttributeNS($rootWfsNsUri, "{$rootWfsNs}:label", $p5Attributes[$fldName]['valuesMap'][$val]);
}
}
}
}
}
}
return $dom->saveXML();
}
public function _getTableAclList() {// Use only Tables from default_db
$tblAclList = array();
$db = DB::getDB();
$idDefaultDB = $db->_zasob_id;
$fullTblAclList = $this->_usrAcl->getTablesAcl();
foreach ($fullTblAclList as $tblAcl) {
$dataSourceName = 'default_db';// TODO: getSourceName
$tblName = $tblAcl->getName();
if ($idDefaultDB != $tblAcl->getDB()) {// hide non default_db tables
continue;
}
try {
$acl = $this->getAclFromTypeName($typeName = "p5_{$dataSourceName}:{$tblName}");
} catch (Exception $e) {
// TODO: error log $e->getMessage();
}
if (!$acl) {
// TODO: error log msg
continue;
}
$tblAclList[] = $tblAcl;
}
return $tblAclList;
}
public function _getFieldListFromAcl($acl) {
$fldList = $acl->getRealFieldListByIdZasob();
return $fldList;
}
public function setLogger($logger) {
$this->_logger = $logger;
}
public function DBG($reqLog, $lineNr = null, $funName = null, $className = null) {
if (!$this->_logger) return;
$this->_logger->DBG($reqLog, $lineNr, $funName, $className);
}
public function convertOgcFilterFromRequestBody($requestOgcFilter) {
$ogcFilter = '';
if (empty($requestOgcFilter)) return '';
{
$convertOgcFilterXslString .= <<
EOF;
DBG::_('DBG_XML', '>2', "convertOgcFilterXslString", $convertOgcFilterXslString, __CLASS__, __FUNCTION__, __LINE__);
$convertTransactionXsl = new DOMDocument();
$convertTransactionXsl->loadXml($convertOgcFilterXslString);
$requestXml = new DOMDocument();
$requestXml->loadXml($requestOgcFilter);
$proc = new XSLTProcessor();
$proc->importStylesheet($convertTransactionXsl);
$ogcFilter = $proc->transformToXML($requestXml);
DBG::_('DBG_XML', '>2', "ogcFilter", $ogcFilter, __CLASS__, __FUNCTION__, __LINE__);
}
return $ogcFilter;
}
}