Browse Source

updated wfs api for AutoCAD Map 3D

Piotr Labudda 10 năm trước cách đây
mục cha
commit
ff984bfc1a

+ 10 - 5
SE/se-lib/Api/WfsDataServer.php

@@ -82,11 +82,13 @@ class Api_WfsDataServer extends Api_WfsServerBase {
 		$DBG = (V::get('DBG_GEO', '', $_GET) > 0);// TODO: Profiler
 		$DBG = (V::get('DBG_GEO', '', $_GET) > 0);// TODO: Profiler
 		$typeName = "{$nsPrefix}:{$type}";
 		$typeName = "{$nsPrefix}:{$type}";
 		$acl = $this->getAclFromTypeName($typeName);
 		$acl = $this->getAclFromTypeName($typeName);
-		$fldList = $acl->getRealFieldList();
+		$fldList = $this->_getFieldListFromAcl($acl);
 
 
 		$baseNsUri = $this->getBaseNamespaceUri();
 		$baseNsUri = $this->getBaseNamespaceUri();
-		$wfsNs = 'p5_default_db_' . $type;//$nsPrefix;
-		$wfsNsUri = "{$baseNsUri}/" . substr($nsPrefix, 3) . '/' . $type;
+		//$wfsNs = 'p5_default_db_' . $type;//$nsPrefix;
+		$wfsNs = 'p5_default_db';//$nsPrefix;
+		$wfsNsUri = "{$baseNsUri}/" . substr($nsPrefix, 3);
+		$featureTypeUri = $this->getBaseUri() . "?SERVICE=WFS&VERSION=1.0.0&TYPENAME={$typeName}&REQUEST=DescribeFeatureType";
 
 
 		// get BBox from geom_field (only one geom fld is allowed)
 		// get BBox from geom_field (only one geom fld is allowed)
 		$geomFld = null;
 		$geomFld = null;
@@ -131,7 +133,8 @@ if($DBG){echo 'getItems:';print_r($searchParams);echo "\n";}
 		$rootNode->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:gml', 'http://www.opengis.net/gml');
 		$rootNode->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:gml', 'http://www.opengis.net/gml');
 		$rootNode->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:xsi', 'http://www.w3.org/2001/XMLSchema-instance');
 		$rootNode->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:xsi', 'http://www.w3.org/2001/XMLSchema-instance');
 		$rootNode->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:' . $wfsNs, $wfsNsUri);
 		$rootNode->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:' . $wfsNs, $wfsNsUri);
-		$rootNode->setAttribute('xsi:schemaLocation', 'http://www.opengis.net/wfs');// TODO: add DescribeFeatureType xsd uri
+		//$rootNode->setAttribute('xsi:schemaLocation', 'http://www.opengis.net/wfs');
+		$rootNode->setAttribute('xsi:schemaLocation', "{$wfsNsUri} {$featureTypeUri}");
 
 
 if($DBG){echo '(geomFld: '.$geomFld.'):';print_r($acl->getFieldType($geomFld));echo "\n";}
 if($DBG){echo '(geomFld: '.$geomFld.'):';print_r($acl->getFieldType($geomFld));echo "\n";}
 		if (empty($items)) {
 		if (empty($items)) {
@@ -174,8 +177,10 @@ if($DBG){echo 'item['.$itemKey.'] ('.$geomFld.')isEmpty('.empty($item->{$geomFld
 			$reqContent = Request::getRequestBody();
 			$reqContent = Request::getRequestBody();
 			if (!empty($reqContent)) {
 			if (!empty($reqContent)) {
 				return $this->_parseDescribeFeatureTypeRequest($reqContent);
 				return $this->_parseDescribeFeatureTypeRequest($reqContent);
+			} else {
+				return $this->_getDescribeFeatureAllTypes();
 			}
 			}
-			throw new HttpException("Wrong param TYPENAME", 400);
+			//throw new HttpException("Wrong param TYPENAME", 400);
 		}
 		}
 		$typeEx = explode(':', $type);
 		$typeEx = explode(':', $type);
 		if (count($typeEx) != 2) {
 		if (count($typeEx) != 2) {

+ 0 - 3
SE/se-lib/Api/WfsQgis.php

@@ -109,9 +109,6 @@ class Api_WfsQgis extends ApiRouteBase {// TODO: extends Api_WfsBase which exten
 
 
 		header('Content-type: application/xml');
 		header('Content-type: application/xml');
 		echo $document; exit;// TODO: return $document;
 		echo $document; exit;// TODO: return $document;
-
-		exit;
-		// TODO: return $document;
 	}
 	}
 
 
 	public function mainWpsAction($request) {
 	public function mainWpsAction($request) {

+ 50 - 6
SE/se-lib/Api/WfsQgisServer.php

@@ -57,11 +57,15 @@ class Api_WfsQgisServer extends Api_WfsServerBase {
 		$DBG = (V::get('DBG_GEO', '', $_GET) > 0);// TODO: Profiler
 		$DBG = (V::get('DBG_GEO', '', $_GET) > 0);// TODO: Profiler
 		$typeName = "{$nsPrefix}:{$type}";
 		$typeName = "{$nsPrefix}:{$type}";
 		$acl = $this->getAclFromTypeName($typeName);
 		$acl = $this->getAclFromTypeName($typeName);
-		$fldList = $acl->getRealFieldList();
+		$fldList = $this->_getFieldListFromAcl($acl);
 
 
 		$baseNsUri = $this->getBaseNamespaceUri();
 		$baseNsUri = $this->getBaseNamespaceUri();
-		$wfsNs = 'p5_default_db_' . $type;//$nsPrefix;
-		$wfsNsUri = "{$baseNsUri}/" . substr($nsPrefix, 3) . '/' . $type;
+		//$wfsNs = 'p5_default_db_' . $type;//$nsPrefix;
+		$wfsNs = 'p5_default_db';//$nsPrefix;
+		$wfsNsUri = "{$baseNsUri}/" . substr($nsPrefix, 3);
+		$featureTypeUri = $this->getBaseUri() . "?SERVICE=WFS&VERSION=1.0.0&TYPENAME={$typeName}&REQUEST=DescribeFeatureType";
+		// https://biuro.biall-net.pl/dev-pl/se-master/wfs-qgis.php/default_db/
+		// https://biuro.biall-net.pl/dev-pl/se-master/wfs-data.php/default_db/TEST_PERMS/?SERVICE=WFS&VERSION=1.0.0&TYPENAME=p5_default_db:TEST_PERMS&REQUEST=DescribeFeatureType
 
 
 		// get BBox from geom_field (only one geom fld is allowed)
 		// get BBox from geom_field (only one geom fld is allowed)
 		$geomFld = null;
 		$geomFld = null;
@@ -95,7 +99,7 @@ if($DBG){echo 'getItems:';print_r($searchParams);echo "\n";}
 		$rootNode->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:gml', 'http://www.opengis.net/gml');
 		$rootNode->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:gml', 'http://www.opengis.net/gml');
 		$rootNode->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:xsi', 'http://www.w3.org/2001/XMLSchema-instance');
 		$rootNode->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:xsi', 'http://www.w3.org/2001/XMLSchema-instance');
 		$rootNode->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:' . $wfsNs, $wfsNsUri);
 		$rootNode->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:' . $wfsNs, $wfsNsUri);
-		$rootNode->setAttribute('xsi:schemaLocation', 'http://www.opengis.net/wfs');// TODO: add DescribeFeatureType xsd uri
+		$rootNode->setAttribute('xsi:schemaLocation', "{$wfsNsUri} {$featureTypeUri}");
 
 
 if(0){// TODO: get BBOX for add features
 if(0){// TODO: get BBOX for add features
 			$boundedByNode = $dom->createElementNS('http://www.opengis.net/gml', 'gml:boundedBy');
 			$boundedByNode = $dom->createElementNS('http://www.opengis.net/gml', 'gml:boundedBy');
@@ -127,7 +131,6 @@ if($DBG){echo '(geomFld: '.$geomFld.'):';print_r($acl->getFieldType($geomFld));e
 			$items[0] = $fakeItem;
 			$items[0] = $fakeItem;
 		}
 		}
 		foreach ($items as $itemKey => $item) {
 		foreach ($items as $itemKey => $item) {
-			//if($item->ID == 19)continue;
 
 
 if($DBG){echo 'item['.$itemKey.'] ('.$geomFld.')isEmpty('.empty($item->{$geomFld}).'):';print_r($item->{$geomFld});echo "\n";}
 if($DBG){echo 'item['.$itemKey.'] ('.$geomFld.')isEmpty('.empty($item->{$geomFld}).'):';print_r($item->{$geomFld});echo "\n";}
 			if ($geomFld) {
 			if ($geomFld) {
@@ -180,8 +183,10 @@ if(0){// TODO: get BBOX
 			$reqContent = Request::getRequestBody();
 			$reqContent = Request::getRequestBody();
 			if (!empty($reqContent)) {
 			if (!empty($reqContent)) {
 				return $this->_parseDescribeFeatureTypeRequest($reqContent);
 				return $this->_parseDescribeFeatureTypeRequest($reqContent);
+			} else {
+				return $this->_getDescribeFeatureAllTypes();
 			}
 			}
-			throw new HttpException("Wrong param TYPENAME", 400);
+			//throw new HttpException("Wrong param TYPENAME", 400);
 		}
 		}
 		$typeEx = explode(':', $type);
 		$typeEx = explode(':', $type);
 		if (count($typeEx) != 2) {
 		if (count($typeEx) != 2) {
@@ -198,6 +203,45 @@ if(0){// TODO: get BBOX
 		//header('Content-type: application/xml; charset="utf-8"');
 		//header('Content-type: application/xml; charset="utf-8"');
 		header('Content-type: application/xml');
 		header('Content-type: application/xml');
 		$this->_getCapabilities($wfsServerUrl, $serviceTitle, $serviceDescription);
 		$this->_getCapabilities($wfsServerUrl, $serviceTitle, $serviceDescription);
+		exit;
+	}
+
+	public function _getTableAclList() {// Use only Tables from default_db with the_geom field
+		$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;
+			}
+			$fldList = $acl->getRealFieldList();
+			if (!in_array('the_geom', $fldList)) {
+				continue;
+			}
+			$tblAclList[] = $tblAcl;
+		}
+		return $tblAclList;
+	}
+
+	public function _getFieldListFromAcl($acl) {
+		$fldList = $acl->getRealFieldList();
+		{// mv the_geom to the first place
+			array_unshift($fldList, 'the_geom');
+			$fldList = array_unique($fldList);
+		}
+		return $fldList;
 	}
 	}
 
 
 }
 }

+ 94 - 215
SE/se-lib/Api/WfsServerBase.php

@@ -84,12 +84,13 @@ class Api_WfsServerBase {
 	public function _getCapabilities($wfsServerUrl, $serviceTitle, $serviceDescription) {
 	public function _getCapabilities($wfsServerUrl, $serviceTitle, $serviceDescription) {
 		echo '<?xml version="1.0" encoding="UTF-8"?>';
 		echo '<?xml version="1.0" encoding="UTF-8"?>';
 		?>
 		?>
-<WFS_Capabilities version="1.0.0"
+<WFS_Capabilities
 				  xmlns="http://www.opengis.net/wfs"
 				  xmlns="http://www.opengis.net/wfs"
 				  xmlns:ogc="http://www.opengis.net/ogc"
 				  xmlns:ogc="http://www.opengis.net/ogc"
 				  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 				  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 				  <?php echo $this->_getXmlNamespaceList(); ?>
 				  <?php echo $this->_getXmlNamespaceList(); ?>
-				  xsi:schemaLocation="http://www.opengis.net/wfs <?php echo $this->_getSchemaLocationString(); ?>">
+				  <?php echo $this->_getXmlSchemaLocation(); ?>
+					version="1.0.0">
   <Service>
   <Service>
     <Name>WFS</Name>
     <Name>WFS</Name>
     <Title><?php echo $serviceTitle; ?></Title>
     <Title><?php echo $serviceTitle; ?></Title>
@@ -117,7 +118,7 @@ class Api_WfsServerBase {
       <Delete />
       <Delete />
       <Lock />
       <Lock />
     </Operations>
     </Operations>
-	<?php echo $this->_printFeatureTypeListXml(); ?>
+	<?php $this->_printFeatureTypeListXml(); ?>
   </FeatureTypeList>
   </FeatureTypeList>
   <ogc:Filter_Capabilities>
   <ogc:Filter_Capabilities>
     <ogc:Spatial_Capabilities>
     <ogc:Spatial_Capabilities>
@@ -369,13 +370,20 @@ class Api_WfsServerBase {
 		<?php
 		<?php
 	}
 	}
 
 
-	public function _getSchemaLocationString() {
+	public function _getXmlSchemaLocation() {
 		$schemaLocations = array();
 		$schemaLocations = array();
-		// $schemaLocations[] = '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 implode(' ', $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
+		return (!empty($schemaLocations))? 'xsi:schemaLocation="' . implode(' ', $schemaLocations) . '"' : '';
 	}
 	}
 
 
 	public function _getXmlNamespaceList() {
 	public function _getXmlNamespaceList() {
+		$baseNsUri = $this->getBaseNamespaceUri();
+		$ns = 'p5_default_db';
+		$uri = "{$baseNsUri}/default_db";
+		return 'xmlns:' . $ns . '="' . $uri . '"';
+	}
+
+	public function _getXmlNamespaceList__OLD() {
 		$baseNsUri = $this->getBaseNamespaceUri();
 		$baseNsUri = $this->getBaseNamespaceUri();
 		$namespaceList = $this->_getSourceNsList();
 		$namespaceList = $this->_getSourceNsList();
 		$namespaceListOut = array();
 		$namespaceListOut = array();
@@ -516,7 +524,7 @@ class Api_WfsServerBase {
 
 
 	public function _printFeatureTypeListXml() {
 	public function _printFeatureTypeListXml() {
 		$featureTypes = array();
 		$featureTypes = array();
-		$tblsAcl = $this->_usrAcl->getTablesAcl();
+		$tblsAcl = $this->_getTableAclList();
 		foreach ($tblsAcl as $tblAcl) {
 		foreach ($tblsAcl as $tblAcl) {
 			$dataSourceName = 'default_db';// TODO: getSourceName
 			$dataSourceName = 'default_db';// TODO: getSourceName
 			$tblName = $tblAcl->getName();
 			$tblName = $tblAcl->getName();
@@ -550,31 +558,31 @@ class Api_WfsServerBase {
 		*/
 		*/
 		$featureTypesXml = '';
 		$featureTypesXml = '';
 		foreach ($featureTypes as $tblName => $feature) {
 		foreach ($featureTypes as $tblName => $feature) {
-			$featureTypesXml .= '<FeatureType>' . "\n";
-				$featureTypesXml .= '<Name>' . "{$feature['ns']}:{$tblName}" . '</Name>' . "\n";
-				$featureTypesXml .= '<Title>' . "{$feature['Title']}" . '</Title>' . "\n";
+			$featureTypesXml .= "    " . '<FeatureType>' . "\n";
+				$featureTypesXml .= "      " . '<Name>' . "{$feature['ns']}:{$tblName}" . '</Name>' . "\n";
+				$featureTypesXml .= "      " . '<Title>' . "{$feature['Title']}" . '</Title>' . "\n";
 				if (!empty($feature['Abstract'])) {
 				if (!empty($feature['Abstract'])) {
-					$featureTypesXml .= '<Abstract>' . "{$feature['Abstract']}" . '</Abstract>' . "\n";
+					$featureTypesXml .= "      " . '<Abstract>' . "{$feature['Abstract']}" . '</Abstract>' . "\n";
 				} else {
 				} else {
-					$featureTypesXml .= '<Abstract/>' . "\n";
+					$featureTypesXml .= "      " . '<Abstract/>' . "\n";
 				}
 				}
 				if (!empty($feature['Keywords'])) {
 				if (!empty($feature['Keywords'])) {
-					$featureTypesXml .= '<Keywords>' . "{$feature['Keywords']}" . '</Keywords>' . "\n";
+					$featureTypesXml .= "      " . '<Keywords>' . "{$feature['Keywords']}" . '</Keywords>' . "\n";
 				} else {
 				} else {
-					$featureTypesXml .= '<Keywords/>' . "\n";
+					$featureTypesXml .= "      " . '<Keywords/>' . "\n";
 				}
 				}
-				$featureTypesXml .= '<SRS>' . "{$feature['SRS']}" . '</SRS>' . "\n";
+				$featureTypesXml .= "      " . '<SRS>' . "{$feature['SRS']}" . '</SRS>' . "\n";
 				if (!empty($feature['LatLongBoundingBox'])) {
 				if (!empty($feature['LatLongBoundingBox'])) {
 					$latLongBoundingBoxOut = array();
 					$latLongBoundingBoxOut = array();
 					$latLongBoundingBoxOut[] = 'minx="' . $feature['LatLongBoundingBox']['minx'] . '"';
 					$latLongBoundingBoxOut[] = 'minx="' . $feature['LatLongBoundingBox']['minx'] . '"';
 					$latLongBoundingBoxOut[] = 'miny="' . $feature['LatLongBoundingBox']['miny'] . '"';
 					$latLongBoundingBoxOut[] = 'miny="' . $feature['LatLongBoundingBox']['miny'] . '"';
 					$latLongBoundingBoxOut[] = 'maxx="' . $feature['LatLongBoundingBox']['maxx'] . '"';
 					$latLongBoundingBoxOut[] = 'maxx="' . $feature['LatLongBoundingBox']['maxx'] . '"';
 					$latLongBoundingBoxOut[] = 'maxy="' . $feature['LatLongBoundingBox']['maxy'] . '"';
 					$latLongBoundingBoxOut[] = 'maxy="' . $feature['LatLongBoundingBox']['maxy'] . '"';
-					$featureTypesXml .= '<LatLongBoundingBox ' . implode(' ', $latLongBoundingBoxOut) . ' />';
+					$featureTypesXml .= "      " . '<LatLongBoundingBox ' . implode(' ', $latLongBoundingBoxOut) . ' />' . "\n";
 				}
 				}
-			$featureTypesXml .= '</FeatureType>' . "\n";
+			$featureTypesXml .= "    " . '</FeatureType>' . "\n";
 		}
 		}
-		return $featureTypesXml;
+		echo $featureTypesXml;
 	}
 	}
 
 
 	public function _parseTransactionXmlStruct($requestXml, $requestXmlTags) {
 	public function _parseTransactionXmlStruct($requestXml, $requestXmlTags) {
@@ -1041,7 +1049,7 @@ if($DBG){echo 'sourceNsList:';print_r($sourceNsList);echo "\n";}
 					$updateTypeNode->appendChild($seqNode);
 					$updateTypeNode->appendChild($seqNode);
 
 
 						$pKeyField = $acl->getPrimaryKeyField();
 						$pKeyField = $acl->getPrimaryKeyField();
-						$fldList = $acl->getRealFieldList();
+						$fldList = $this->_getFieldListFromAcl($acl);
 						foreach ($fldList as $fldName) {
 						foreach ($fldList as $fldName) {
 							if ($acl->isGeomField($fldName)) continue;
 							if ($acl->isGeomField($fldName)) continue;
 
 
@@ -1184,198 +1192,8 @@ if($DBG){echo '$validateConvertedTransactionXsdString:';print_r($validateConvert
 		return $reqXml->schemaValidateSource($validateConvertedTransactionXsdString);
 		return $reqXml->schemaValidateSource($validateConvertedTransactionXsdString);
 	}
 	}
 
 
-	public function _generateXsdTypeNode($ns, $typeName, $dom, $parentNode) {
-		//$fieldsXsd = '';
-		//$fieldsXsd .= '<xsd:element name="PARENT_ID" minOccurs="0" maxOccurs="1" type="xsd:integer" />';
-		$acl = $this->getAclFromTypeName($typeName);
-
-		$cTypeNode = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:complexType');
-		$rootNode = $cTypeNode;
-		$cTypeNode->setAttribute('name', $typeName);
-
-		$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');// or xsd:all ?
-		$extNode->appendChild($seqNode);
-
-		// <xsd:element maxOccurs="1" minOccurs="0" name="{$fldName}" nillable="true" type="xsd:integer"/>
-		$pKeyField = $acl->getPrimaryKeyField();
-		$fldList = $acl->getRealFieldList();
-		foreach ($fldList as $fldName) {
-			$elNode = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:element');
-			$seqNode->appendChild($elNode);
-			$elNode->setAttribute('name', $fldName);
-			$minOccurs = 0;
-			if ($pKeyField == $fldName) {
-				$minOccurs = '1';
-			} else {
-				$minOccurs = '0';
-			}
-			$elNode->setAttribute('minOccurs', $minOccurs);
-			if ($acl->isIntegerField($fldName)) {
-				$fldType = 'xsd:integer';
-			}
-			else if ($acl->isDecimalField($fldName)) {
-				$fldType = 'xsd:decimal';
-			}
-			else if ($acl->isDateField($fldName)) {
-				$fldType = 'xsd:date';
-			}
-			else if ($acl->isDateTimeField($fldName)) {
-				$fldType = 'xsd:dateTime';
-			}
-			else if ($acl->isGeomField($fldName)) {
-				$fldType = 'gml:GeometryPropertyType';
-				//$fldType = 'gml:Polygon';// nie działa musi być gml:GeometryPropertyType
-			}
-			else {
-				$fldType = 'xsd:string';
-			}
-			$elNode->setAttribute('type', $fldType);
-			$elNode->setAttribute('nillable', 'true');
-		}
-
-/*
-			<xsd:attribute name="typeName" type="xsd:token" use="required"/>
-			<xsd:attribute name="featureId" use="required">
-				<xsd:simpleType>
-					<xsd:restriction base="xsd:string">
-						<xsd:pattern value="[a-zA-Z_][a-zA-Z0-9_]*\.[0-9]*"/>
-					</xsd:restriction>
-				</xsd:simpleType>
-			</xsd:attribute>
-*/
-		$cAttrNode = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:attribute');
-		$rootNode->appendChild($cAttrNode);
-		$cAttrNode->setAttribute('name', 'typeName');
-		$cAttrNode->setAttribute('type', 'xsd:token');
-		$cAttrNode->setAttribute('use', 'required');
-
-		$cAttrNode = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:attribute');
-		$rootNode->appendChild($cAttrNode);
-		$cAttrNode->setAttribute('name', 'featureId');
-		$cAttrNode->setAttribute('use', 'required');
-			$sTypeNode = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:simpleType');
-			$cAttrNode->appendChild($sTypeNode);
-				$restrNode = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:restriction');
-				$cAttrNode->appendChild($restrNode);
-				$restrNode->setAttribute('base', 'xsd:string');
-					$patternNode = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:pattern');
-					$restrNode->appendChild($patternNode);
-					$patternNode->setAttribute('value', '[a-zA-Z_][a-zA-Z0-9_]*\.[0-9]*');
-
-		return $dom->saveXml($cTypeNode);
-
-		$typeXsd = <<<EOF
-		<xsd:complexType name="{$typeName}">
-			<xsd:all>
-				{$fieldsXsd}
-			</xsd:all>
-			<xsd:attribute name="typeName" type="xsd:token" use="required"/>
-			<xsd:attribute name="featureId" use="required">
-				<xsd:simpleType>
-					<xsd:restriction base="xsd:string">
-						<xsd:pattern value="[a-zA-Z_][a-zA-Z0-9_]*\.[0-9]*"/>
-					</xsd:restriction>
-				</xsd:simpleType>
-			</xsd:attribute>
-		</xsd:complexType>
-EOF;
-		return $typeXsd;
-	}
-
 	public function _getDescribeFeatureType($nsPrefix, $type) {
 	public function _getDescribeFeatureType($nsPrefix, $type) {
-		$typeName = "{$nsPrefix}:{$type}";
-		$acl = $this->getAclFromTypeName($typeName);
-
-		$baseNsUri = $this->getBaseNamespaceUri();
-		$wfsNs = 'p5_default_db_' . $type;//$nsPrefix;
-		$wfsNsUri = "{$baseNsUri}/" . substr($nsPrefix, 3) . '/' . $type;
-
-		if (empty($type)) {
-			throw new HttpException("Feature Type Name not defined", 400);
-		}
-		if (!$this->isAllowedFeatureType($nsPrefix, $type)) {
-			throw new Api_WfsException("Could not find type: " . htmlspecialchars($type));
-		}
-
-		$typeName = $type . 'Type';
-		$fldList = $acl->getRealFieldList();
-		header('Content-type: application/xml');
-		// <xsd:import namespace="http://www.opengis.net/gml" schemaLocation="http://webgis.regione.sardegna.it:80/geoserver/schemas/gml/2.1.2/feature.xsd"/>
-		//	<xsd:element name="{type}" substitutionGroup="gml:_Feature" type="dbu:{typeName}"/>
-
-		$dom = new DOMDocument('1.0', 'utf-8');
-		$dom->formatOutput = true;
-		$dom->preserveWhiteSpace = false;
-		$rootNode = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:schema');
-		$dom->appendChild($rootNode);
-		$rootNode->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:gml', 'http://www.opengis.net/gml');
-		$rootNode->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:' . $wfsNs, $wfsNsUri);
-		$rootNode->setAttribute('elementFormDefault', 'qualified');
-		$rootNode->setAttribute('targetNamespace', $wfsNsUri);
-
-		$cTypeNode = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:complexType');
-		$rootNode->appendChild($cTypeNode);
-		$cTypeNode->setAttribute('name', $typeName);
-
-		$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);
-
-		// <xsd:element maxOccurs="1" minOccurs="0" name="{$fldName}" nillable="true" type="xsd:integer"/>
-		$pKeyField = $acl->getPrimaryKeyField();
-		foreach ($fldList as $fldName) {
-			$elNode = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:element');
-			$seqNode->appendChild($elNode);
-			$elNode->setAttribute('name', $fldName);
-			$minOccurs = 0;
-			if ($pKeyField == $fldName) {
-				$minOccurs = '1';
-			} else {
-				$minOccurs = '0';
-			}
-			$elNode->setAttribute('minOccurs', $minOccurs);
-			if ($acl->isIntegerField($fldName)) {
-				$fldType = 'xsd:integer';
-			}
-			else if ($acl->isDecimalField($fldName)) {
-				$fldType = 'xsd:decimal';
-			}
-			else if ($acl->isDateField($fldName)) {
-				$fldType = 'xsd:date';
-			}
-			else if ($acl->isDateTimeField($fldName)) {
-				$fldType = 'xsd:dateTime';
-			}
-			else if ($acl->isGeomField($fldName)) {
-				$fldType = 'gml:GeometryPropertyType';
-				//$fldType = 'gml:Polygon';// nie działa musi być gml:GeometryPropertyType
-			}
-			else {
-				$fldType = 'xsd:string';
-			}
-			$elNode->setAttribute('type', $fldType);
-			$elNode->setAttribute('nillable', 'true');
-		}
-
-		$elNode = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:element');
-		$rootNode->appendChild($elNode);
-		$elNode->setAttribute('name', $type);
-		$elNode->setAttribute('type', $wfsNs . ':' . $typeName);
-
-		echo $dom->saveXML();
+		return $this->_getDescribeFeatureTypes(array(array($nsPrefix, $type)));
 	}
 	}
 
 
 	public function _parseDescribeFeatureTypeRequest($reqContent) {
 	public function _parseDescribeFeatureTypeRequest($reqContent) {
@@ -1416,6 +1234,19 @@ EOF;
 		return $this->_getDescribeFeatureTypes($typeNames);
 		return $this->_getDescribeFeatureTypes($typeNames);
 	}
 	}
 
 
+	public function _getDescribeFeatureAllTypes() {
+		$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);
+	}
+
 	// @param $typeNames = array( array( $nsPrefix, $type ) )
 	// @param $typeNames = array( array( $nsPrefix, $type ) )
 	public function _getDescribeFeatureTypes($typeNames) {
 	public function _getDescribeFeatureTypes($typeNames) {
 		if (empty($typeNames)) {
 		if (empty($typeNames)) {
@@ -1425,6 +1256,7 @@ EOF;
 
 
 		$wfsNs = 'p5_default_db';
 		$wfsNs = 'p5_default_db';
 		$wfsNsUri = "{$baseNsUri}/default_db";
 		$wfsNsUri = "{$baseNsUri}/default_db";
+		$featureTypeUri = $this->getBaseUri() . "?SERVICE=WFS&VERSION=1.0.0&REQUEST=DescribeFeatureType";
 
 
 		header('Content-type: application/xml');
 		header('Content-type: application/xml');
 		// <xsd:import namespace="http://www.opengis.net/gml" schemaLocation="http://webgis.regione.sardegna.it:80/geoserver/schemas/gml/2.1.2/feature.xsd"/>
 		// <xsd:import namespace="http://www.opengis.net/gml" schemaLocation="http://webgis.regione.sardegna.it:80/geoserver/schemas/gml/2.1.2/feature.xsd"/>
@@ -1439,6 +1271,12 @@ EOF;
 		$rootNode->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:' . $wfsNs, $wfsNsUri);
 		$rootNode->setAttributeNS('http://www.w3.org/2000/xmlns/', 'xmlns:' . $wfsNs, $wfsNsUri);
 		$rootNode->setAttribute('elementFormDefault', 'qualified');
 		$rootNode->setAttribute('elementFormDefault', 'qualified');
 		$rootNode->setAttribute('targetNamespace', $wfsNsUri);
 		$rootNode->setAttribute('targetNamespace', $wfsNsUri);
+		{// <xsd:import namespace="http://www.opengis.net/gml" schemaLocation="...../gml/2.1.2/feature.xsd"/>
+			$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) {
 		foreach ($typeNames as $typeNameEx) {
 			$nsPrefix = $typeNameEx[0];
 			$nsPrefix = $typeNameEx[0];
@@ -1450,7 +1288,7 @@ EOF;
 				throw new Api_WfsException("Could not find type: " . htmlspecialchars($type));
 				throw new Api_WfsException("Could not find type: " . htmlspecialchars($type));
 			}
 			}
 			$typeName = $type . 'Type';
 			$typeName = $type . 'Type';
-			$fldList = $acl->getRealFieldList();
+			$fldList = $this->_getFieldListFromAcl($acl);
 
 
 			$cTypeNode = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:complexType');
 			$cTypeNode = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:complexType');
 			$rootNode->appendChild($cTypeNode);
 			$rootNode->appendChild($cTypeNode);
@@ -1479,6 +1317,8 @@ EOF;
 					$minOccurs = '0';
 					$minOccurs = '0';
 				}
 				}
 				$elNode->setAttribute('minOccurs', $minOccurs);
 				$elNode->setAttribute('minOccurs', $minOccurs);
+				$elNode->setAttribute('maxOccurs', '1');
+				$elNode->setAttribute('nillable', 'true');
 				if ($acl->isIntegerField($fldName)) {
 				if ($acl->isIntegerField($fldName)) {
 					$fldType = 'xsd:integer';
 					$fldType = 'xsd:integer';
 				}
 				}
@@ -1492,23 +1332,62 @@ EOF;
 					$fldType = 'xsd:dateTime';
 					$fldType = 'xsd:dateTime';
 				}
 				}
 				else if ($acl->isGeomField($fldName)) {
 				else if ($acl->isGeomField($fldName)) {
-					$fldType = 'gml:GeometryPropertyType';
-					//$fldType = 'gml:Polygon';// nie działa musi być gml:GeometryPropertyType
+					//$fldType = 'gml:GeometryPropertyType';
+					$geomType = $acl->getGeomFieldType($fldName);
+					if ('polygon' == $geomType) {
+						$fldType = 'gml:PolygonPropertyType';
+					} else if ('point' == $geomType) {
+						$fldType = 'gml:PointPropertyType';
+					} else if ('linestring' == $geomType) {
+						$fldType = 'gml:LineStringPropertyType';
+					} else {
+						$fldType = 'gml:GeometryPropertyType';
+					}
 				}
 				}
 				else {
 				else {
 					$fldType = 'xsd:string';
 					$fldType = 'xsd:string';
 				}
 				}
 				$elNode->setAttribute('type', $fldType);
 				$elNode->setAttribute('type', $fldType);
-				$elNode->setAttribute('nillable', 'true');
 			}
 			}
 
 
 			$elNode = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:element');
 			$elNode = $dom->createElementNS('http://www.w3.org/2001/XMLSchema', 'xsd:element');
 			$rootNode->appendChild($elNode);
 			$rootNode->appendChild($elNode);
 			$elNode->setAttribute('name', $type);
 			$elNode->setAttribute('name', $type);
 			$elNode->setAttribute('type', $wfsNs . ':' . $typeName);
 			$elNode->setAttribute('type', $wfsNs . ':' . $typeName);
+			$elNode->setAttribute('substitutionGroup', 'gml:_Feature');// substitutionGroup="gml:_Feature"
 		}
 		}
 
 
-		echo $dom->saveXML();
+		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->getRealFieldList();
+		return $fldList;
 	}
 	}
 
 
 }
 }