_usrAcl = $usrAcl;
$this->_typeConverter = new Api_WfsGeomTypeConverter();
$this->_apiBaseUri = '';
}
public function setBaseUri($uri) {
$this->_apiBaseUri = $uri;
}
public function getBaseUri() {// TODO: RMME
return $this->_apiBaseUri;
}
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) {
// TODO: generate class name like in: UserAcl->getObjectAcl($sourceName = $nsPrefix, $objName = $type)
$objClassName = "Schema_{$type}StorageAcl";
if (Lib::tryLoadClass($objClassName)) 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 '';
?>
_printXmlNamespaceList(); ?>
_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
$prefix) {
$listNs[] = 'xmlns:' . $prefix . '="' . $uri . '/default_db"';
}
return implode("\n", $listNs);
}
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');
$usrObjList[] = array('objects', 'TestPerms');
$usrObjList[] = array('objects', 'Korespondencja');
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";
$featureTypes['File'] = $featureType;
}
{// add p5_objects:File
$featureType = array();
$featureType['ns'] = "p5_objects";
$featureType['Title'] = "TestPerms";
$featureType['Abstract'] = "TestPerms";
$featureType['Keywords'] = "TestPerms";
$featureType['SRS'] = "EPSG:4326";
$featureTypes['TestPerms'] = $featureType;
}
{// add p5_objects:File
$featureType = array();
$featureType['ns'] = "p5_objects";
$featureType['Title'] = "Korespondencja";
$featureType['Abstract'] = "Korespondencja";
$featureType['Keywords'] = "Korespondencja";
$featureType['SRS'] = "EPSG:4326";
$featureTypes['Korespondencja'] = $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', 0, $_GET, 'int');// 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');
// TODO: special actions if action on nested objects
// 1. convert request: wfs.transaction.convert-wfs-request.xsl
// 2. validate converted request: wfs.transaction-converted-request.xsd
// 3. execute request in data source
// if($DBG){echo 'L.' . __LINE__ . ' $requestXmlTags:';print_r($requestXmlTags);echo "\n";}
/*
blank-wfs.gif
R0lGODlhAQABAIAAAP///////yH+EUNyZWF0ZWQgd2l0aCBHSU1QACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==
*/
$actionXmlTags = array();// // [ 0 => [ 'action'=>Insert, 'typeName'=>str, 'tags'=>[] ]
{// split xml for action tags (Insert, Update, Delete)
$tagsCount = count($requestXmlTags);
for ($i = 1, $actionTagName = null, $actionIdx = -1, $tagLvl = 0; $i < $tagsCount - 1; $i++) {// skip Transaction open/close tag
$tag = $requestXmlTags[$i];
if (null == $actionTagName) {
$actionTagName = $tag['tag'];
$tagLvl = $tag['level'];
$actionIdx += 1;
$actionXmlTags[$actionIdx] = array();
$actionXmlTags[$actionIdx]['action'] = $actionTagName;
$actionXmlTags[$actionIdx]['typeName'] = V::get('typeName', '', $tag['attributes']);
$actionXmlTags[$actionIdx]['isDeepObject'] = null;// null - unknown, false - not seed, true - deep
$actionXmlTags[$actionIdx]['tags'] = array();
} else if ($tag['tag'] == $actionTagName && 'close' == $tag['type'] && $tagLvl == $tag['level']) {
$actionTagName = null;
} else {
$actionXmlTags[$actionIdx]['tags'][] = $tag;
}
}
}
{// Validate Request: WFS allow multiple tags inside Insert tag
// TODO: implement multiple tags in Insert tag if reauired. Use array_splice($actionXmlTags, $actionIdx, 0, $insertTags);
{// throw (Not Implemented, 501) if found multiple tags in Insert tag
foreach ($actionXmlTags as $actionIdx => $action) {
if ('Insert' !== $action['action']) continue;
$lvl = $action['tags'][0]['level'];
for ($i = 1, $cnt = count($action['tags']); $i < $cnt - 1; $i++) {
$tag = $action['tags'][$i];
// if($DBG){echo 'L.' . __LINE__ . " actionXmlTags loop({$i}) \$tag:";print_r($tag);echo "\n";}
if ($tag['level'] == $lvl) throw new Exception("Error Processing Request - multiple tags inside Insert tag is not implemented", 501);
}
}
}
}
{// Insert tag - fix typeName from first tag, remove first and last tag - leave only fields
foreach ($actionXmlTags as $actionIdx => $action) {
if ('Insert' !== $action['action']) continue;
array_pop($action['tags']);// remove last tag (close tag)
$tag = array_shift($action['tags']);// remove last tag (close tag)
$typeName = $tag['tag'];// eg. with prefix 'p5_objects:File' or without prefix but with @xmlns
if (false === strpos($typeName, ':')) {
$nsType = V::get('xmlns', '', $tag['attributes']);
if (!$nsType) throw new Exception("Error Processing Request - Missing object namespace '{$tag['tag']}'");
$prefix = Api_WfsNs::getNsPrefix($nsType);
if (!$prefix) {
if ($typeName == substr(rtrim($nsType, '/'), -1 * strlen($typeName))) {// typeName may be added to ns uri
$nsBaseForType = substr(rtrim($nsType, '/'), 0, -1 * strlen($typeName) - 1);
$prefix = Api_WfsNs::getNsPrefix($nsBaseForType);
}
}
if (!$prefix) throw new Exception("Error Processing Request - Unrecognized namespace uri '{$nsType}' for object '{$tag['tag']}'");
$typeName = "{$prefix}:{$typeName}";
}
$action['typeName'] = $typeName;
$actionXmlTags[$actionIdx] = $action;
}
}
{// validate
// if($DBG){echo 'L.' . __LINE__ . ' before validate $actionXmlTags:';print_r($actionXmlTags);echo "\n";}
foreach ($actionXmlTags as $actionIdx => $action) {
if ('Insert' == $action['action']) {
if (empty($action['typeName'])) throw new Exception("Error Processing Request - unknown object typeName to Insert");
$acl = $this->getAclFromTypeName($action['typeName']);
$actionXmlTags[$actionIdx] = $acl->validateInsertXml($action);
} else if ('Update' == $action['action']) {
$acl = $this->getAclFromTypeName($action['typeName']);
$actionXmlTags[$actionIdx] = $acl->validateUpdateXml($action);
} else if ('Delete' == $action['action']) {
if($DBG>1){echo'
$action: ';print_r($action);echo'
';}
$acl = $this->getAclFromTypeName($action['typeName']);
$actionXmlTags[$actionIdx] = $acl->validateDeleteXml($action);
} else {
if($DBG>1){echo'$action: ';print_r($action);echo'
';}
throw new Exception("{$action['action']} action not implemented", 501);
}
// continue;// TODO: validate all by type
}
}
{// execute
$returnIds = array();
$changesList = array();
foreach ($actionXmlTags as $actionIdx => $action) {
if ('Insert' == $action['action']) {
if (empty($action['typeName'])) throw new Exception("Error Processing Request - unknown object typeName to Insert");
$acl = $this->getAclFromTypeName($action['typeName']);
$newId = $acl->insertXml($action);
$returnIds[$actionIdx] = $newId;
$changesList[$actionIdx] = array('Status'=>(($newId > 0)? 'SUCCESS' : 'FAILED'), 'Message'=>"created {$newId}.", 'Action' => $action['action']);
if ($newId > 0) $changesList[$actionIdx]['fid'] = $acl->getName() . '.' . $newId;
} else if ('Update' == $action['action']) {
if($DBG>1){echo'$action: ';print_r($action);echo'
';}
$acl = $this->getAclFromTypeName($action['typeName']);
$affected = $acl->updateXml($action);
$changesList[$actionIdx] = array('Status'=>(($affected >= 0)? 'SUCCESS' : 'FAILED'), 'Message'=>"affected {$affected}.", 'Action' => $action['action']);
} else if ('Delete' == $action['action']) {
$acl = $this->getAclFromTypeName($action['typeName']);
$affected = $acl->deleteXml($action);
$changesList[$actionIdx] = array('Status'=>(($affected >= 0)? 'SUCCESS' : 'FAILED'), 'Message'=>"deleted {$affected}.", 'Action' => $action['action']);
} else throw new Exception("TODO: {$action['action']} action not implemented", 501);
}
if($DBG){echo 'L.' . __LINE__ . ' $changesList:';print_r($changesList);echo "\n";}
}
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->setAttribute('elementFormDefault', 'qualified');
$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 = Api_WfsNs::getBaseWfsUri();
$rootWfsNs = 'p5';
$rootWfsNsUri = "{$baseNsUri}";
$featureTypeUri = Api_WfsNs::getBaseWfsUri() . "?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');
foreach (Api_WfsNs::getNsList() as $uri => $prefix) {
$rootNode->setAttributeNS('http://www.w3.org/2000/xmlns/', "xmlns:{$prefix}", $uri);
}
$rootNode->setAttribute('elementFormDefault', 'qualified');
$rootNode->setAttribute('targetNamespace', Api_WfsNs::getNsUri('p5_default_db'));// TODO:? what targetNamespace if showing types from p5_objects and p5_default_db
{//
$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) {
$sourceName = $acl->getSourceName();
if ('default_db' == $sourceName) {
$tblName = $acl->getName();
$cTypeNode->setAttributeNS($rootWfsNsUri, "{$rootWfsNs}:web_link", Request::getPathUri() . "index.php?_route=ViewTableAjax&typeName=p5_{$sourceName}:{$tblName}");
}
}
$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 $fldName) {
$elNode = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:element');
$seqNode->appendChild($elNode);
$minOccurs = 0;
if ($pKeyField == $fldName) {
$minOccurs = '1';
} else {
$minOccurs = '0';
}
$elNode->setAttribute('minOccurs', $minOccurs);
$elNode->setAttribute('maxOccurs', '1');
$elNode->setAttribute('nillable', 'true');
$fldType = $acl->getXsdFieldType($fldName);
if (!$simple && $acl->isEnumerationField($fldName)) {
$fldType = "{$nsPrefix}:{$fldName}Type";
}
if ('ref:' == substr($fldType, 0, 4)) {
$elNode->setAttribute('ref', substr($fldType, 4));
$elNode->setAttributeNS($rootWfsNsUri, "{$rootWfsNs}:name", $fldName);
} else if ('local_ref:' == substr($fldType, 0, 10)) {
$elNode->setAttribute('type', "{$fldName}Type");
$elNode->setAttributeNS($rootWfsNsUri, "{$rootWfsNs}:name", $fldName);
} else if ('alias_ref:' == substr($fldType, 0, 10)) {
$elNode->setAttribute('ref', "p5_" . $acl->getSourceName() . ":{$fldName}");
$elNode->setAttributeNS($rootWfsNsUri, "{$rootWfsNs}:name", $fldName);
} else {
$elNode->setAttribute('name', $fldName);
$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->canWriteField($fldName)) $elNode->setAttributeNS($rootWfsNsUri, "{$rootWfsNs}:allow_write", "true");
if ($acl->canCreateField($fldName)) $elNode->setAttributeNS($rootWfsNsUri, "{$rootWfsNs}:allow_create", "true");
if (!$acl->canReadField($fldName)) $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', $acl->getSourceName() . ':' . $typeName);
if ($simple) {
$elNode->setAttribute('substitutionGroup', 'gml:_Feature');
} else {
$elNode->setAttribute('substitutionGroup', 'gml:AbstractFeature');
}
foreach ($fldList as $fldName) {
$fldType = $acl->getXsdFieldType($fldName);
if ('alias_ref:' == substr($fldType, 0, 10)) {
$localRefType = substr($fldType, 10);
//
$ctNode = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:element');
$rootNode->appendChild($ctNode);
$ctNode->setAttribute('name', $fldName);
$ctNode->setAttribute('type', $localRefType);
} else if ('local_ref:' == substr($fldType, 0, 10)) {
$localRefType = substr($fldType, 10);
//
//
//
//
//
//
//
$ctNode = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:complexType');
$rootNode->appendChild($ctNode);
$ctNode->setAttribute('name', "{$fldName}Type");
$seqNode = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:sequence');
$ctNode->appendChild($seqNode);
$elNode = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:element');
$seqNode->appendChild($elNode);
$elNode->setAttribute('name', "test_id");
$elNode->setAttribute('type', "xsd:integer");
$elNode = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:element');
$seqNode->appendChild($elNode);
$elNode->setAttribute('name', "test_opis");
$elNode->setAttribute('type', "xsd:string");
$elNode = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:element');
$seqNode->appendChild($elNode);
$elNode->setAttribute('name', "test_decimal");
$elNode->setAttribute('type', "xsd:decimal");
}
}
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;
}
}