_usrAcl = $usrAcl; $this->_typeConverter = new Api_WfsGeomTypeConverter(); $this->_apiBaseUri = ''; } public function setBaseUri($uri) { $this->_apiBaseUri = $uri; } public function getBaseUri() {// TODO: RMME return $this->_apiBaseUri; } /** * @param string $typeName - 'p5_default_db:TEST_PERMS' */ public function getAclFromTypeName($typeName) { $typeEx = explode(':', $typeName); $sourceName = $typeEx[0]; $objName = $typeEx[1]; if (2 != count($typeEx)) throw new Api_WfsException("Could not get acl for '{$typeName}' - syntax error"); if ('p5_' == substr($sourceName, 0, 3)) $sourceName = substr($sourceName, 3);// remove prefix 'p5_' $acl = $this->_usrAcl->getObjectAcl($sourceName, $objName); $forceTblAclInit = 0;//('1' == V::get('_force', '', $_GET)); $acl->init($forceTblAclInit); return $acl; } /** * @param $_GET [ , POST Body - XML file ] * @return array $args * TODO: get $acl and check more restrictions */ public function parseGetFeatureArgsFromRequest() { $rawArgs = $_GET;// $_REQUEST; ($_POST values not allowed, only xml in post body) $args = array(); $args['xsd:type'] = null;// @from: TYPENAME, typeName (typename) $args['typePrefix'] = null;// @from: TYPENAME, typeName (typename) $args['typeName'] = null;// @from: TYPENAME, typeName (typename) $args['srsname'] = null;// @from: SRSNAME (srsname) $args['limit'] = 0;// @from: MAXFEATURES, maxFeatures, COUNT (maxfeatures, count) $args['offset'] = 0;// @from: startIndex (startindex, count) $args['ogc:filter'] = null;// @from: FILTER, Filter (filter) $args['sortBy'] = null;// @from: sortBy (sortby) $args['wfs:propertyName'] = null;// @from: propertyName (propertyname) $args['filterFields'] = array();// array of field names to show - @from: propertyName $args['resultType'] = null;// @from: resultType (resulttype) $args['bbox'] = null;// @from: BBOX (bbox) $args['wfs:featureID'] = null;// @from: featureID, featureId (featureid) $args['primaryKey'] = null;// primaryKey type - @from: featureID $lowerArgs = array(); foreach ($rawArgs as $name => $value) $lowerArgs[ strtolower($name) ] = trim($value); $args['xsd:type'] = V::get('typename', '', $lowerArgs); $exType = explode(':', $args['xsd:type']); if (count($exType) != 2) throw new HttpException("Wrong param TYPENAME", 400); $args['typePrefix'] = $exType[0]; $args['typeName'] = $exType[1]; $args['srsname'] = V::get('SRSNAME', '', $lowerArgs);// eg. EPSG:4326 $args['limit'] = V::get('maxfeatures', $args['limit'], $lowerArgs, 'int'); $args['limit'] = V::get('count', $args['limit'], $lowerArgs, 'int'); $defaultFeaturesLimit = ('biuro.biall-net.pl' == V::get('SERVER_NAME', '', $_SERVER)) ? 50000 : 10000; if ($args['limit'] <= 0) $args['limit'] = $defaultFeaturesLimit;// default limit $args['offset'] = V::get('startindex', 0, $lowerArgs, 'int'); $args['ogc:filter'] = urldecode(V::get('filter', '', $lowerArgs)); if (empty($args['ogc:filter'])) {// read ogc:Filter from POST body if not defined in GET $reqBody = Request::getRequestBody(); if (!empty($reqBody)) { $args['ogc:filter'] = $this->convertOgcFilterFromRequestBody($reqBody); if (empty($args['ogc:filter'])) throw new Api_WfsException("Error Processing ogc:Filter", 501); } } $args['sortBy'] = V::get('sortby', '', $lowerArgs);// TODO: split to array of array(fieldName, (asc | desc)) $args['wfs:propertyName'] = trim(V::get('propertyname', '', $lowerArgs));// TODO: fields to show - split by ',' if (strlen($args['wfs:propertyName']) > 0) { $args['filterFields'] = array(); $exFields = explode(',', $args['wfs:propertyName']); foreach ($exFields as $fieldName) { $fieldName = trim($fieldName); if (!empty($fieldName)) $args['filterFields'][] = $fieldName; } } $args['resultType'] = V::get('resulttype', '', $lowerArgs); $args['bbox'] = V::get('bbox', '', $lowerArgs); if (!empty($args['bbox'])) { // BBOX may have EPSG at then end - example: ",EPSG:4326" $num = "\d+.?\d*?";// "\d+(.\d+)?" if (!preg_match("/^({$num}),({$num}),({$num}),({$num})(\,EPSG:\d+)?$/", $args['bbox'], $matches)) throw new Exception("Illegal BBOX format"); // QGIS send BBOX in correct order: 54.23580872176457,18.46844302390853,54.25220902538883,18.492990600812696 // first number should not be smaller then second // example $matches: // [0] => 18.492990600812696,54.23580872176457,18.46844302390853,54.25220902538883 // [1] => 18.492990600812696 // [2] => 54.23580872176457 // [3] => 18.46844302390853 // [4] => 54.25220902538883 // (optional) EPGS $bboxPoints = ($matches[1] > $matches[2]) ? [ $matches[1], $matches[2], $matches[3], $matches[4] ] : [ $matches[2], $matches[3], $matches[4], $matches[1] ]; $args['bbox'] = implode(",", $bboxPoints); } $args['wfs:featureID'] = V::get('featureid', null, $lowerArgs);// TODO: allow multiply feature id (csv) if ($args['wfs:featureID']) { $dotPos = strpos($args['wfs:featureID'], '.'); if (!$dotPos) throw new Exception("Wrong param fetureID"); if ($args['typeName'] != substr($args['wfs:featureID'], 0, $dotPos)) throw new Exception("Wrong typeName in param fetureID"); $args['primaryKey'] = substr($args['wfs:featureID'], $dotPos + 1); } if(DBG::isActive() && V::get('DBG', 0, $_GET)){ echo "\$lowerArgs:";print_r($lowerArgs); } if(DBG::isActive() && V::get('DBG', 0, $_GET)){ echo "\$args:";print_r($args); } return $args; } public function _getCapabilities($wfsServerUrl, $serviceTitle, $serviceDescription) { if (V::get('DBG_ACL', '', $_GET)) { { echo "Core_AclHelper::getAclList = [" . "\n"; foreach (Core_AclHelper::getAclList() as $typeName) { echo "|\t{$typeName}" . "\n"; } echo "]// .EOF Core_AclHelper::getAclList" . "\n"; } $fullTblAclList = $this->_usrAcl->getTablesAcl(); print_r($fullTblAclList); die("\n" . '.EOF - DBG_ACL'); } $xmlWriter = new Core_XMLWriter(); if (!$xmlWriter) throw new HttpException("Error no XMLWriter", 404); $xmlWriter->openUri('php://output'); $xmlWriter->setIndent(true); $xmlWriter->startDocument('1.0','UTF-8'); $xmlWriter->startElement('WFS_Capabilities'); $xmlWriter->writeAttribute('xmlns', 'http://www.opengis.net/wfs'); $xmlWriter->writeAttribute('xmlns:ogc', 'http://www.opengis.net/ogc'); $xmlWriter->writeAttribute('xmlns:xsi', 'http://www.w3.org/2001/XMLSchema-instance'); foreach (Api_WfsNs::getNsList() as $uri => $prefix) { $xmlWriter->writeAttribute("xmlns:{$prefix}", $uri); } $schemaLocations = []; //$schemaLocations[] = 'http://www.opengis.net/wfs http://webgis.regione.sardegna.it:80/geoserver/schemas/wfs/1.0.0/WFS-capabilities.xsd';// @from http://webgis.regione.sardegna.it/geoserver/ows?service=WFS&request=GetCapabilities if (!empty($schemaLocations)) $xmlWriter->writeAttribute('xsi:schemaLocation', implode(' ', $schemaLocations)); $xmlWriter->writeAttribute('version', "1.0.0"); $xmlWriter->h('Service', [ ['Name', "WFS"], ['Title', $serviceTitle], ['Abstract', $serviceDescription], ['Keywords', "WFS, WMS"], ['OnlineResource', $wfsServerUrl], ['Fees', "NONE"], ['AccessConstraints', "NONE"], ]); $xmlWriter->h('Capability', [ [ 'Request', [ [ 'GetCapabilities', [ [ 'DCPType', [ [ 'HTTP', [ [ 'Get', [ 'onlineResource' => "{$wfsServerUrl}?REQUEST=GetCapabilities" ], null ] ] ] ] ], [ 'DCPType', [ [ 'HTTP', [ [ 'Post', [ 'onlineResource' => "{$wfsServerUrl}" ], null ] ] ] ] ], ] ] ] ] ]); $xmlWriter->h('DescribeFeatureType', [ [ 'SchemaDescriptionLanguage', [ [ 'XMLSCHEMA', null ] ] ], [ 'DCPType', [ [ 'HTTP', [ [ 'Get', ['onlineResource' => "{$wfsServerUrl}?REQUEST=DescribeFeatureType"], null ] ] ] ] ], [ 'DCPType', [ [ 'HTTP', [ [ 'Post', ['onlineResource' => "{$wfsServerUrl}"], null ] ] ] ] ], ]); $xmlWriter->h('GetFeature', [// $this->_printGetFeatureXml($wfsServerUrl); [ 'ResultFormat', [ 'WFSKMLOutputFormat', 'GML2', 'GML3', 'SHAPE-ZIP', 'CSV', 'JSON', ] ], [ 'DCPType', [ [ 'HTTP', [ [ 'Get', ['onlineResource' => "{$wfsServerUrl}?REQUEST=GetFeature"], null ] ] ] ] ], [ 'DCPType', [ [ 'HTTP', [ [ 'Post', ['onlineResource' => "{$wfsServerUrl}"], null ] ] ] ] ], ]); $xmlWriter->h('Transaction', [ [ 'DCPType', [ [ 'HTTP', [ [ 'Get', ['onlineResource' => "{$wfsServerUrl}?REQUEST=Transaction"], null ] ] ] ] ], [ 'DCPType', [ [ 'HTTP', [ [ 'Post', ['onlineResource' => "{$wfsServerUrl}"], null ] ] ] ] ], ]); $xmlWriter->h('LockFeature', [ [ 'DCPType', [ [ 'HTTP', [ [ 'Get', ['onlineResource' => "{$wfsServerUrl}?REQUEST=LockFeature"], null ] ] ] ] ], [ 'DCPType', [ [ 'HTTP', [ [ 'Post', ['onlineResource' => "{$wfsServerUrl}"], null ] ] ] ] ], ]); $xmlWriter->h('GetFeatureWithLock', [ [ 'ResultFormat', [ 'GML2' ] ], [ 'DCPType', [ [ 'HTTP', [ [ 'Get', ['onlineResource' => "{$wfsServerUrl}?REQUEST=GetFeatureWithLock"], null ] ] ] ] ], [ 'DCPType', [ [ 'HTTP', [ [ 'Post', ['onlineResource' => "{$wfsServerUrl}"], null ] ] ] ] ], ]); $featureTypeNodes = []; foreach ($this->_getTableAclList() as $tblAcl) { $dataSourceName = 'default_db';// TODO: $tblAcl->getSourceName() $prefix = "p5_{$dataSourceName}"; $featureTypeNodes[] = [ 'FeatureType', [ "xmlns:{$prefix}" => Api_WfsNs::getNsUri($prefix) ], [ [ 'Name', $prefix . ':' . $tblAcl->getName() ], [ 'Title', $tblAcl->getRawLabel() ], [ 'Abstract', $tblAcl->getRawOpis() ], [ 'Keywords', implode(', ', [ $tblAcl->getID(), $tblAcl->getName(), $tblAcl->getRawLabel() ]) ], [ 'SRS', 'EPSG:4326' ], [ 'LatLongBoundingBox', [ 'minx' => "8.12328509871721", 'miny' => "38.8575126897477", 'maxx' => "9.838674658246807", 'maxy' => "41.31378404137082"], null ] ]]; } foreach (Core_AclHelper::getAclList() as $typeName) { list($prefix, $name) = explode(':', $typeName); $featureTypeNodes[] = [ 'FeatureType', [ "xmlns:{$prefix}" => Api_WfsNs::getNsUri($prefix) ], [ [ 'Name', $name ], [ 'Title', $name ], [ 'Abstract', $name ], [ 'Keywords', $name ], [ 'SRS', 'EPSG:4326' ], ]]; } $xmlWriter->startElement('FeatureTypeList'); $xmlWriter->h('Operations', ['Query', 'Insert', 'Update', 'Delete', 'Lock']); foreach ($featureTypeNodes as $node) { $xmlWriter->h($node); } $xmlWriter->endElement();// FeatureTypeList $xmlWriter->h('ogc:Filter_Capabilities', [ [ 'ogc:Spatial_Capabilities', [ [ 'ogc:Spatial_Operators', [ 'ogc:Disjoint', 'ogc:Equals', 'ogc:DWithin', 'ogc:Beyond', 'ogc:Intersect', 'ogc:Touches', 'ogc:Crosses', 'ogc:Within', 'ogc:Contains', 'ogc:Overlaps', 'ogc:BBOX', ] ] ] ], [ 'ogc:Scalar_Capabilities', [ 'ogc:Logical_Operators', [ 'ogc:Comparison_Operators', [ 'ogc:Simple_Comparisons', 'ogc:Between', 'ogc:Like', 'ogc:NullCheck', ] ], [ 'ogc:Arithmetic_Operators', [ 'ogc:Simple_Arithmetic', [ 'ogc:Functions', [ [ 'ogc:Function_Names', [ [ 'ogc:Function_Name', ['nArgs'=>"1"], "abs" ], [ 'ogc:Function_Name', ['nArgs'=>"1"], "abs_2" ], [ 'ogc:Function_Name', ['nArgs'=>"1"], "abs_3" ], [ 'ogc:Function_Name', ['nArgs'=>"1"], "abs_4" ], [ 'ogc:Function_Name', ['nArgs'=>"1"], "acos" ], [ 'ogc:Function_Name', ['nArgs'=>"2"], "AddCoverages" ], [ 'ogc:Function_Name', ['nArgs'=>"4"], "Aggregate" ], [ 'ogc:Function_Name', ['nArgs'=>"1"], "Area" ], [ 'ogc:Function_Name', ['nArgs'=>"1"], "area2" ], [ 'ogc:Function_Name', ['nArgs'=>"3"], "AreaGrid" ], [ 'ogc:Function_Name', ['nArgs'=>"1"], "asin" ], [ 'ogc:Function_Name', ['nArgs'=>"1"], "atan" ], [ 'ogc:Function_Name', ['nArgs'=>"2"], "atan2" ], [ 'ogc:Function_Name', ['nArgs'=>"14"], "BarnesSurface" ], [ 'ogc:Function_Name', ['nArgs'=>"3"], "between" ], [ 'ogc:Function_Name', ['nArgs'=>"1"], "boundary" ], [ 'ogc:Function_Name', ['nArgs'=>"1"], "boundaryDimension" ], [ 'ogc:Function_Name', ['nArgs'=>"1"], "Bounds" ], [ 'ogc:Function_Name', ['nArgs'=>"2"], "buffer" ], [ 'ogc:Function_Name', ['nArgs'=>"3"], "BufferFeatureCollection" ], [ 'ogc:Function_Name', ['nArgs'=>"3"], "bufferWithSegments" ], [ 'ogc:Function_Name', ['nArgs'=>"7"], "Categorize" ], [ 'ogc:Function_Name', ['nArgs'=>"1"], "ceil" ], [ 'ogc:Function_Name', ['nArgs'=>"1"], "Centroid" ], [ 'ogc:Function_Name', ['nArgs'=>"2"], "classify" ], [ 'ogc:Function_Name', ['nArgs'=>"2"], "Clip" ], [ 'ogc:Function_Name', ['nArgs'=>"1"], "CollectGeometries" ], [ 'ogc:Function_Name', ['nArgs'=>"1"], "Collection_Average" ], [ 'ogc:Function_Name', ['nArgs'=>"1"], "Collection_Bounds" ], [ 'ogc:Function_Name', ['nArgs'=>"0"], "Collection_Count" ], [ 'ogc:Function_Name', ['nArgs'=>"1"], "Collection_Max" ], [ 'ogc:Function_Name', ['nArgs'=>"1"], "Collection_Median" ], [ 'ogc:Function_Name', ['nArgs'=>"1"], "Collection_Min" ], [ 'ogc:Function_Name', ['nArgs'=>"1"], "Collection_Sum" ], [ 'ogc:Function_Name', ['nArgs'=>"1"], "Collection_Unique" ], [ 'ogc:Function_Name', ['nArgs'=>"1"], "Concatenate" ], [ 'ogc:Function_Name', ['nArgs'=>"2"], "contains" ], [ 'ogc:Function_Name', ['nArgs'=>"7"], "Contour" ], [ 'ogc:Function_Name', ['nArgs'=>"2"], "convert" ], [ 'ogc:Function_Name', ['nArgs'=>"1"], "convexHull" ], [ 'ogc:Function_Name', ['nArgs'=>"1"], "cos" ], [ 'ogc:Function_Name', ['nArgs'=>"1"], "Count" ], [ 'ogc:Function_Name', ['nArgs'=>"2"], "CropCoverage" ], [ 'ogc:Function_Name', ['nArgs'=>"2"], "crosses" ], [ 'ogc:Function_Name', ['nArgs'=>"2"], "dateFormat" ], [ 'ogc:Function_Name', ['nArgs'=>"2"], "dateParse" ], [ 'ogc:Function_Name', ['nArgs'=>"2"], "difference" ], [ 'ogc:Function_Name', ['nArgs'=>"1"], "dimension" ], [ 'ogc:Function_Name', ['nArgs'=>"2"], "disjoint" ], [ 'ogc:Function_Name', ['nArgs'=>"2"], "disjoint3D" ], [ 'ogc:Function_Name', ['nArgs'=>"2"], "distance" ], [ 'ogc:Function_Name', ['nArgs'=>"2"], "distance3D" ], [ 'ogc:Function_Name', ['nArgs'=>"1"], "double2bool" ], [ 'ogc:Function_Name', ['nArgs'=>"1"], "endAngle" ], [ 'ogc:Function_Name', ['nArgs'=>"1"], "endPoint" ], [ 'ogc:Function_Name', ['nArgs'=>"1"], "env" ], [ 'ogc:Function_Name', ['nArgs'=>"1"], "envelope" ], [ 'ogc:Function_Name', ['nArgs'=>"2"], "EqualInterval" ], [ 'ogc:Function_Name', ['nArgs'=>"2"], "equalsExact" ], [ 'ogc:Function_Name', ['nArgs'=>"3"], "equalsExactTolerance" ], [ 'ogc:Function_Name', ['nArgs'=>"2"], "equalTo" ], [ 'ogc:Function_Name', ['nArgs'=>"1"], "exp" ], [ 'ogc:Function_Name', ['nArgs'=>"1"], "exteriorRing" ], [ 'ogc:Function_Name', ['nArgs'=>"3"], "Feature" ], [ 'ogc:Function_Name', ['nArgs'=>"1"], "floor" ], [ 'ogc:Function_Name', ['nArgs'=>"1"], "geometryType" ], [ 'ogc:Function_Name', ['nArgs'=>"1"], "geomFromWKT" ], [ 'ogc:Function_Name', ['nArgs'=>"1"], "geomLength" ], [ 'ogc:Function_Name', ['nArgs'=>"2"], "getGeometryN" ], [ 'ogc:Function_Name', ['nArgs'=>"1"], "getX" ], [ 'ogc:Function_Name', ['nArgs'=>"1"], "getY" ], [ 'ogc:Function_Name', ['nArgs'=>"1"], "getz" ], [ 'ogc:Function_Name', ['nArgs'=>"2"], "greaterEqualThan" ], [ 'ogc:Function_Name', ['nArgs'=>"2"], "greaterThan" ], [ 'ogc:Function_Name', ['nArgs'=>"5"], "Grid" ], [ 'ogc:Function_Name', ['nArgs'=>"7"], "Heatmap" ], [ 'ogc:Function_Name', ['nArgs'=>"0"], "id" ], [ 'ogc:Function_Name', ['nArgs'=>"2"], "IEEEremainder" ], [ 'ogc:Function_Name', ['nArgs'=>"3"], "if_then_else" ], [ 'ogc:Function_Name', ['nArgs'=>"11"], "in10" ], [ 'ogc:Function_Name', ['nArgs'=>"3"], "in2" ], [ 'ogc:Function_Name', ['nArgs'=>"4"], "in3" ], [ 'ogc:Function_Name', ['nArgs'=>"5"], "in4" ], [ 'ogc:Function_Name', ['nArgs'=>"6"], "in5" ], [ 'ogc:Function_Name', ['nArgs'=>"7"], "in6" ], [ 'ogc:Function_Name', ['nArgs'=>"8"], "in7" ], [ 'ogc:Function_Name', ['nArgs'=>"9"], "in8" ], [ 'ogc:Function_Name', ['nArgs'=>"10"], "in9" ], [ 'ogc:Function_Name', ['nArgs'=>"2"], "InclusionFeatureCollection" ], [ 'ogc:Function_Name', ['nArgs'=>"1"], "int2bbool" ], [ 'ogc:Function_Name', ['nArgs'=>"1"], "int2ddouble" ], [ 'ogc:Function_Name', ['nArgs'=>"1"], "interiorPoint" ], [ 'ogc:Function_Name', ['nArgs'=>"2"], "interiorRingN" ], [ 'ogc:Function_Name', ['nArgs'=>"3"], "Interpolate" ], [ 'ogc:Function_Name', ['nArgs'=>"2"], "intersection" ], [ 'ogc:Function_Name', ['nArgs'=>"7"], "IntersectionFeatureCollection" ], [ 'ogc:Function_Name', ['nArgs'=>"2"], "intersects" ], [ 'ogc:Function_Name', ['nArgs'=>"2"], "intersects3D" ], [ 'ogc:Function_Name', ['nArgs'=>"1"], "isClosed" ], [ 'ogc:Function_Name', ['nArgs'=>"0"], "isCoverage" ], [ 'ogc:Function_Name', ['nArgs'=>"1"], "isEmpty" ], [ 'ogc:Function_Name', ['nArgs'=>"2"], "isLike" ], [ 'ogc:Function_Name', ['nArgs'=>"1"], "isNull" ], [ 'ogc:Function_Name', ['nArgs'=>"2"], "isometric" ], [ 'ogc:Function_Name', ['nArgs'=>"1"], "isRing" ], [ 'ogc:Function_Name', ['nArgs'=>"1"], "isSimple" ], [ 'ogc:Function_Name', ['nArgs'=>"1"], "isValid" ], [ 'ogc:Function_Name', ['nArgs'=>"3"], "isWithinDistance" ], [ 'ogc:Function_Name', ['nArgs'=>"3"], "isWithinDistance3D" ], [ 'ogc:Function_Name', ['nArgs'=>"2"], "Jenks" ], [ 'ogc:Function_Name', ['nArgs'=>"1"], "length" ], [ 'ogc:Function_Name', ['nArgs'=>"2"], "lessEqualThan" ], [ 'ogc:Function_Name', ['nArgs'=>"2"], "lessThan" ], [ 'ogc:Function_Name', ['nArgs'=>"1"], "list" ], [ 'ogc:Function_Name', ['nArgs'=>"1"], "log" ], [ 'ogc:Function_Name', ['nArgs'=>"4"], "LRSGeocode" ], [ 'ogc:Function_Name', ['nArgs'=>"5"], "LRSMeasure" ], [ 'ogc:Function_Name', ['nArgs'=>"5"], "LRSSegment" ], [ 'ogc:Function_Name', ['nArgs'=>"2"], "max" ], [ 'ogc:Function_Name', ['nArgs'=>"2"], "max_2" ], [ 'ogc:Function_Name', ['nArgs'=>"2"], "max_3" ], [ 'ogc:Function_Name', ['nArgs'=>"2"], "max_4" ], [ 'ogc:Function_Name', ['nArgs'=>"2"], "min" ], [ 'ogc:Function_Name', ['nArgs'=>"2"], "min_2" ], [ 'ogc:Function_Name', ['nArgs'=>"2"], "min_3" ], [ 'ogc:Function_Name', ['nArgs'=>"2"], "min_4" ], [ 'ogc:Function_Name', ['nArgs'=>"1"], "mincircle" ], [ 'ogc:Function_Name', ['nArgs'=>"1"], "minimumdiameter" ], [ 'ogc:Function_Name', ['nArgs'=>"1"], "minrectangle" ], [ 'ogc:Function_Name', ['nArgs'=>"2"], "modulo" ], [ 'ogc:Function_Name', ['nArgs'=>"2"], "MultiplyCoverages" ], [ 'ogc:Function_Name', ['nArgs'=>"3"], "Nearest" ], [ 'ogc:Function_Name', ['nArgs'=>"1"], "not" ], [ 'ogc:Function_Name', ['nArgs'=>"2"], "notEqualTo" ], [ 'ogc:Function_Name', ['nArgs'=>"2"], "numberFormat" ], [ 'ogc:Function_Name', ['nArgs'=>"5"], "numberFormat2" ], [ 'ogc:Function_Name', ['nArgs'=>"1"], "numGeometries" ], [ 'ogc:Function_Name', ['nArgs'=>"1"], "numInteriorRing" ], [ 'ogc:Function_Name', ['nArgs'=>"1"], "numPoints" ], [ 'ogc:Function_Name', ['nArgs'=>"1"], "octagonalenvelope" ], [ 'ogc:Function_Name', ['nArgs'=>"3"], "offset" ], [ 'ogc:Function_Name', ['nArgs'=>"2"], "overlaps" ], [ 'ogc:Function_Name', ['nArgs'=>"1"], "parameter" ], [ 'ogc:Function_Name', ['nArgs'=>"1"], "parseBoolean" ], [ 'ogc:Function_Name', ['nArgs'=>"1"], "parseDouble" ], [ 'ogc:Function_Name', ['nArgs'=>"1"], "parseInt" ], [ 'ogc:Function_Name', ['nArgs'=>"1"], "parseLong" ], [ 'ogc:Function_Name', ['nArgs'=>"0"], "pi" ], [ 'ogc:Function_Name', ['nArgs'=>"4"], "PointBuffers" ], [ 'ogc:Function_Name', ['nArgs'=>"2"], "pointN" ], [ 'ogc:Function_Name', ['nArgs'=>"7"], "PointStacker" ], [ 'ogc:Function_Name', ['nArgs'=>"6"], "PolygonExtraction" ], [ 'ogc:Function_Name', ['nArgs'=>"2"], "pow" ], [ 'ogc:Function_Name', ['nArgs'=>"1"], "property" ], [ 'ogc:Function_Name', ['nArgs'=>"1"], "PropertyExists" ], [ 'ogc:Function_Name', ['nArgs'=>"2"], "Quantile" ], [ 'ogc:Function_Name', ['nArgs'=>"3"], "Query" ], [ 'ogc:Function_Name', ['nArgs'=>"0"], "random" ], [ 'ogc:Function_Name', ['nArgs'=>"5"], "RangeLookup" ], [ 'ogc:Function_Name', ['nArgs'=>"1"], "RasterAsPointCollection" ], [ 'ogc:Function_Name', ['nArgs'=>"4"], "RasterZonalStatistics" ], [ 'ogc:Function_Name', ['nArgs'=>"5"], "Recode" ], [ 'ogc:Function_Name', ['nArgs'=>"2"], "RectangularClip" ], [ 'ogc:Function_Name', ['nArgs'=>"2"], "relate" ], [ 'ogc:Function_Name', ['nArgs'=>"3"], "relatePattern" ], [ 'ogc:Function_Name', ['nArgs'=>"3"], "Reproject" ], [ 'ogc:Function_Name', ['nArgs'=>"1"], "rint" ], [ 'ogc:Function_Name', ['nArgs'=>"1"], "round" ], [ 'ogc:Function_Name', ['nArgs'=>"1"], "round_2" ], [ 'ogc:Function_Name', ['nArgs'=>"1"], "roundDouble" ], [ 'ogc:Function_Name', ['nArgs'=>"6"], "ScaleCoverage" ], [ 'ogc:Function_Name', ['nArgs'=>"4"], "sdo_nn" ], [ 'ogc:Function_Name', ['nArgs'=>"2"], "setCRS" ], [ 'ogc:Function_Name', ['nArgs'=>"3"], "Simplify" ], [ 'ogc:Function_Name', ['nArgs'=>"1"], "sin" ], [ 'ogc:Function_Name', ['nArgs'=>"3"], "Snap" ], [ 'ogc:Function_Name', ['nArgs'=>"1"], "sqrt" ], [ 'ogc:Function_Name', ['nArgs'=>"2"], "StandardDeviation" ], [ 'ogc:Function_Name', ['nArgs'=>"1"], "startAngle" ], [ 'ogc:Function_Name', ['nArgs'=>"1"], "startPoint" ], [ 'ogc:Function_Name', ['nArgs'=>"1"], "strCapitalize" ], [ 'ogc:Function_Name', ['nArgs'=>"2"], "strConcat" ], [ 'ogc:Function_Name', ['nArgs'=>"2"], "strEndsWith" ], [ 'ogc:Function_Name', ['nArgs'=>"2"], "strEqualsIgnoreCase" ], [ 'ogc:Function_Name', ['nArgs'=>"2"], "strIndexOf" ], [ 'ogc:Function_Name', ['nArgs'=>"2"], "strLastIndexOf" ], [ 'ogc:Function_Name', ['nArgs'=>"1"], "strLength" ], [ 'ogc:Function_Name', ['nArgs'=>"2"], "strMatches" ], [ 'ogc:Function_Name', ['nArgs'=>"3"], "strPosition" ], [ 'ogc:Function_Name', ['nArgs'=>"4"], "strReplace" ], [ 'ogc:Function_Name', ['nArgs'=>"2"], "strStartsWith" ], [ 'ogc:Function_Name', ['nArgs'=>"3"], "strSubstring" ], [ 'ogc:Function_Name', ['nArgs'=>"2"], "strSubstringStart" ], [ 'ogc:Function_Name', ['nArgs'=>"1"], "strToLowerCase" ], [ 'ogc:Function_Name', ['nArgs'=>"1"], "strToUpperCase" ], [ 'ogc:Function_Name', ['nArgs'=>"1"], "strTrim" ], [ 'ogc:Function_Name', ['nArgs'=>"3"], "strTrim2" ], [ 'ogc:Function_Name', ['nArgs'=>"2"], "StyleCoverage" ], [ 'ogc:Function_Name', ['nArgs'=>"2"], "symDifference" ], [ 'ogc:Function_Name', ['nArgs'=>"1"], "tan" ], [ 'ogc:Function_Name', ['nArgs'=>"1"], "toDegrees" ], [ 'ogc:Function_Name', ['nArgs'=>"1"], "toRadians" ], [ 'ogc:Function_Name', ['nArgs'=>"2"], "touches" ], [ 'ogc:Function_Name', ['nArgs'=>"1"], "toWKT" ], [ 'ogc:Function_Name', ['nArgs'=>"2"], "Transform" ], [ 'ogc:Function_Name', ['nArgs'=>"2"], "union" ], [ 'ogc:Function_Name', ['nArgs'=>"2"], "UnionFeatureCollection" ], [ 'ogc:Function_Name', ['nArgs'=>"2"], "Unique" ], [ 'ogc:Function_Name', ['nArgs'=>"2"], "UniqueInterval" ], [ 'ogc:Function_Name', ['nArgs'=>"6"], "VectorToRaster" ], [ 'ogc:Function_Name', ['nArgs'=>"3"], "VectorZonalStatistics" ], [ 'ogc:Function_Name', ['nArgs'=>"1"], "vertices" ], [ 'ogc:Function_Name', ['nArgs'=>"2"], "within" ], ] ], ] ], ] ], ] ], ]); $xmlWriter->endElement();// WFS_Capabilities $xmlWriter->endDocument(); exit; } public function _getXmlSchemaLocation() { $schemaLocations = array(); //$schemaLocations[] = 'http://www.opengis.net/wfs http://webgis.regione.sardegna.it:80/geoserver/schemas/wfs/1.0.0/WFS-capabilities.xsd';// @from http://webgis.regione.sardegna.it/geoserver/ows?service=WFS&request=GetCapabilities return (!empty($schemaLocations))? 'xsi:schemaLocation="' . implode(' ', $schemaLocations) . '"' : ''; } public function _printXmlNamespaceList() { $listNs = array(); foreach (Api_WfsNs::getNsList() as $uri => $prefix) { $listNs[] = 'xmlns:' . $prefix . '="' . $uri . '"'; } 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 _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 } } if ('1' == V::get('DBG_DONT_CHANGE_DB', '', $_REQUEST)) { echo "----------------- action xml tags: ---------------" . "\n"; print_r($actionXmlTags); die(".EOF\n"); } {// 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); } 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'); // // $nsMap = Api_WfsNs::getNsList();// uri => prefix $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->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', Request::getPathUri() . "schema/gml/2.1.2/feature.xsd"); } // TODO: fix namespace BUG for multiple types: // - fetch namespace for first type // - if another object has another namespace then -> import tag foreach ($typeNames as $typeNameEx) {// $typeNameEx = [ nsPrefix , name => $objectName ] $objectName = $typeNameEx[1]; $acl = $this->getAclFromTypeName("{$typeNameEx[0]}:{$objectName}"); {// xmlns and targetNamespace for root element $aclNamespaceUri = Api_WfsNs::getNsUri($acl->getSourceName()); $rootNode->setAttribute('targetNamespace', $aclNamespaceUri); // TODO: if targetNamespace already set then import tag if (!array_key_exists($aclNamespaceUri, $nsMap)) $nsMap[$aclNamespaceUri] = $acl->getSourceName(); } $objectXsdName = "{$objectName}Type"; if ($acl->hasSimpleSchema()) { $simpleSchema = $acl->getSimpleSchema(); foreach ($simpleSchema as $ssName => $schema) { if ('root' == $ssName) $ssName = $objectName; list($nsUri, $prefix, $name) = Api_WfsNs::parseObjectNsUri($schema['@namespace']); if (!array_key_exists($nsUri, $nsMap)) $nsMap[$nsUri] = $prefix; } foreach ($nsMap as $uri => $prefix) { $rootNode->setAttributeNS('http://www.w3.org/2000/xmlns/', "xmlns:{$prefix}", $uri); } $aliasRefMap = array();// fieldName => namespace uri foreach ($simpleSchema as $ssName => $schema) { if ('root' == $ssName) $ssName = $objectName; foreach ($schema as $fieldName => $field) { if (is_array($field) && !empty($field['@ref']) && false !== strpos($field['@ref'], '/') ) {// @ref_uri // $elNode->setAttribute('ref', "{$tnsPrefix}:{$fieldName}"); $aliasRefMap[ "{$ssName}_{$fieldName}" ] = $field['@ref']; } } } if (!empty($aliasRefMap)) { foreach ($aliasRefMap as $fieldName => $aliasNsUri) { list($nsUri, $prefix, $name) = Api_WfsNs::parseObjectNsUri($aliasNsUri); if (!array_key_exists($nsUri, $nsMap)) $nsMap[$nsUri] = $prefix; $elNode = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:import'); $rootNode->appendChild($elNode); $elNode->setAttribute('namespace', $nsUri); $elNode->setAttribute('schemaLocation', "{$nsUri}.xsd");// TODO: real file url -> DescribeFeatureType[Advanced] } } foreach ($simpleSchema as $ssName => $schema) { {// code from Code_AclSimpleSchema if ('root' == $ssName) $ssName = $objectName; // // // // // // // // // // // // // $cTypeNode = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:complexType'); $rootNode->appendChild($cTypeNode); $cTypeNode->setAttribute('name', "{$ssName}Type"); $seqNode = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:sequence'); $cTypeNode->appendChild($seqNode); // [@namespace] => default_db/ZALICZKA_POZYCJA/ZaliczkaPozycja // [id] => xsd:integer // [kwota] => xsd:decimal // [korespondencja] => [ '@ref' => Korespondencja ] // [projekt] => [ '@ref' => Projekt ] $tnsPrefix = $acl->getSourceName(); foreach ($schema as $fieldName => $field) { // TODO: p5:field_name if ('@' == substr($fieldName, 0, 1)) continue;// skip tags // $elNode = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:element'); $seqNode->appendChild($elNode); if (!is_array($field)) throw new Exception("Error Processing simpleSchema: '{$ssName}/{$fieldName}'"); if (!empty($field['@type'])) { $elNode->setAttribute('name', $fieldName); $elNode->setAttribute('type', $field['@type']); $elNode->setAttribute('nillable', "true"); } else if (!empty($field['@ref'])) { if (false !== strpos($field['@ref'], '/')) {// @ref_uri $elNode->setAttribute('ref', "{$tnsPrefix}:{$ssName}_{$fieldName}"); $elNode->setAttributeNS($rootWfsNsUri, "{$rootWfsNs}:name", $fieldName); } else { $elNode->setAttribute('ref', "{$tnsPrefix}:{$field['@ref']}"); if ($fieldName != $field['@ref']) { $elNode->setAttributeNS($rootWfsNsUri, "{$rootWfsNs}:name", $fieldName); } } } else { throw new Exception("Error Processing simpleSchema - missing @type or @ref: '{$ssName}/{$fieldName}'"); } if (array_key_exists('@minOccurs', $field)) $elNode->setAttribute('minOccurs', $field['@minOccurs']); if (array_key_exists('@maxOccurs', $field)) $elNode->setAttribute('maxOccurs', $field['@maxOccurs']); } $elNode = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:element'); $rootNode->appendChild($elNode); $elNode->setAttribute('name', $ssName); $elNode->setAttribute('type', "{$tnsPrefix}:{$ssName}Type"); if (!$simple) { if (!empty($schema['@namespace'])) {// TODO: @namespace is required? list($nsUri, $prefix, $name) = Api_WfsNs::parseObjectNsUri($schema['@namespace']); $elNode->setAttributeNS($rootWfsNsUri, "{$rootWfsNs}:namespace", '{' . $nsUri . '}' . $name); } } } } if (!empty($aliasRefMap)) { foreach ($aliasRefMap as $fieldName => $aliasNsUri) { list($nsUri, $prefix, $name) = Api_WfsNs::parseObjectNsUri($aliasNsUri); $elNode = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:element'); $rootNode->appendChild($elNode); $elNode->setAttribute('name', $fieldName); $elNode->setAttribute('type', "{$prefix}:{$name}Type"); } } if (V::get('DBG_SS', '', $_GET)) echo "\n\n";// TODO: DBG continue; } $fldList = $this->_getFieldListFromAcl($acl); DBG::_('DBG_XSD', '>1', "field list", $fldList, __CLASS__, __FUNCTION__, __LINE__); $cTypeNode = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:complexType'); $rootNode->appendChild($cTypeNode); $cTypeNode->setAttribute('name', $objectXsdName); if (!$simple) $cTypeNode->setAttributeNS($rootWfsNsUri, "{$rootWfsNs}:web_link", Request::getPathUri() . "index.php?_route=ViewTableAjax&namespace=" . $acl->getNamespace()); $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'); $fldType = $acl->getXsdFieldType($fldName); if (!$simple && $acl->isEnumerationField($fldName)) { $fldType = $acl->getSourceName() . ":{$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', $acl->getSourceName() . ":{$fldName}"); $elNode->setAttributeNS($rootWfsNsUri, "{$rootWfsNs}:name", $fldName); } else { $elNode->setAttribute('name', $fldName); $elNode->setAttribute('type', $fldType); $elNode->setAttribute('nillable', 'true');// nillable not allowed in ref } 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"); } } if (!$simple) { $instanceNode = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:attribute'); $extNode->appendChild($instanceNode); $instanceNode->setAttribute('name', 'instance'); $instanceNode->setAttribute('type', $acl->getSourceName() . ':' . "instanceType"); $instanceTypeNode = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:simpleType'); $rootNode->appendChild($instanceTypeNode); $instanceTypeNode->setAttribute('name', "instanceType"); $insResNode = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:restriction'); $instanceTypeNode->appendChild($insResNode); $insResNode->setAttribute('base', "xsd:string"); $insEnumNode = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:enumeration'); $insResNode->appendChild($insEnumNode); $insEnumNode->setAttribute('value', $acl->getName()); if (method_exists($acl, 'getInstanceList')) { foreach ($acl->getInstanceList() as $instanceName) { $insEnumNode = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:enumeration'); $insResNode->appendChild($insEnumNode); $insEnumNode->setAttribute('value', $instanceName); } } } $elNode = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:element'); $rootNode->appendChild($elNode); $elNode->setAttribute('name', $objectName); $elNode->setAttribute('type', $acl->getSourceName() . ':' . $objectXsdName); $elNode->setAttribute('substitutionGroup', 'gml:_Feature');// gml:AbstractFeature in gml 3 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");// $acl->getSourceName() . ":{$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]); } } } } } } foreach ($nsMap as $uri => $prefix) { $rootNode->setAttributeNS('http://www.w3.org/2000/xmlns/', "xmlns:{$prefix}", $uri); } 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) { // echo "Error for table({$tblName}): " . $e->getMessage() . "\n"; } 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; } }