[Mapbender-commits] r8642 - trunk/mapbender/http/classes

svn_mapbender at osgeo.org svn_mapbender at osgeo.org
Mon Jun 3 01:56:00 PDT 2013


Author: verenadiewald
Date: 2013-06-03 01:56:00 -0700 (Mon, 03 Jun 2013)
New Revision: 8642

Added:
   trunk/mapbender/http/classes/class_wfs_2_0.php
   trunk/mapbender/http/classes/class_wfs_2_0_factory.php
   trunk/mapbender/http/classes/class_xml_parser.php
Modified:
   trunk/mapbender/http/classes/class_gml_2_factory.php
   trunk/mapbender/http/classes/class_gml_3_factory.php
   trunk/mapbender/http/classes/class_gml_factory.php
   trunk/mapbender/http/classes/class_gml_geometry.php
   trunk/mapbender/http/classes/class_gml_line.php
   trunk/mapbender/http/classes/class_gml_multiline.php
   trunk/mapbender/http/classes/class_gml_multipoint.php
   trunk/mapbender/http/classes/class_gml_multipolygon.php
   trunk/mapbender/http/classes/class_gml_point.php
   trunk/mapbender/http/classes/class_gml_polygon.php
   trunk/mapbender/http/classes/class_universal_wfs_factory.php
   trunk/mapbender/http/classes/class_wfs.php
   trunk/mapbender/http/classes/class_wfsToDb.php
   trunk/mapbender/http/classes/class_wfs_1_1_factory.php
   trunk/mapbender/http/classes/class_wfs_conf.php
   trunk/mapbender/http/classes/class_wfs_configuration.php
Log:
changes for wfs 2.0.0 integration and some additional changes for lat lon axis ordering topic

Modified: trunk/mapbender/http/classes/class_gml_2_factory.php
===================================================================
--- trunk/mapbender/http/classes/class_gml_2_factory.php	2013-06-03 08:28:31 UTC (rev 8641)
+++ trunk/mapbender/http/classes/class_gml_2_factory.php	2013-06-03 08:56:00 UTC (rev 8642)
@@ -241,7 +241,7 @@
 	 * @param $domNode DOMNodeObject the feature tag of the GML 
 	 * 								(<gml:featureMember> in the above example)
 	 */
-	protected function parseFeature($domNode, $feature, $wfsConf) {
+	protected function parseFeature($domNode, $feature, $wfsConf, $gmlBoundedBySrs) {
 		$geomFeaturetypeElement = $wfsConf->getGeometryColumnName();
 
 		$currentSibling = $domNode;
@@ -270,6 +270,10 @@
 				if ($geomNode->hasAttribute("srsName")) {
 					$srs = $geomNode->getAttribute("srsName");
 				}
+				//if srsName of featureMember is empty, use the srsName of node //gml:boundedBy/gml:Envelope
+				if($srs == "") {
+					$srs = $gmlBoundedBySrs;
+				}
 				$geomType = $geomNode->nodeName;
 				switch ($geomType) {
 					case "gml:Polygon" :

Modified: trunk/mapbender/http/classes/class_gml_3_factory.php
===================================================================
--- trunk/mapbender/http/classes/class_gml_3_factory.php	2013-06-03 08:28:31 UTC (rev 8641)
+++ trunk/mapbender/http/classes/class_gml_3_factory.php	2013-06-03 08:56:00 UTC (rev 8642)
@@ -342,7 +342,7 @@
 	 * @param $domNode DOMNodeObject the feature tag of the GML 
 	 * 								(<gml:featureMember> in the above example)
 	 */
-	protected function parseFeature($domNode, $feature, $wfsConf) {
+	protected function parseFeature($domNode, $feature, $wfsConf, $gmlBoundedBySrs) {
 		$geomFeaturetypeElement = $wfsConf->getGeometryColumnName();
 
 		$feature->fid = $domNode->getAttribute("gml:id");
@@ -353,7 +353,7 @@
 		
 			$name = $currentSibling->nodeName;
 			$value = $currentSibling->nodeValue;
-			
+
 			$namespace = $this->findNameSpace($name);
 			$ns = $namespace['ns'];
 			$columnName = $namespace['value'];
@@ -366,17 +366,25 @@
 			// sophisticated here...
 			if ($currentSibling->hasChildNodes() && $isGeomColumn){
 				$geomNode = $currentSibling->firstChild;
-                                if($geomNode->nodeType != XML_ELEMENT_NODE){
-                                    while($geomNode = $geomNode->nextSibling){
-                                        if($geomNode->nodeType == XML_ELEMENT_NODE){
-                                            break;
-                                        }
-                                    }
-                                }
+				
+				if($geomNode->nodeType != XML_ELEMENT_NODE){
+                	while($geomNode = $geomNode->nextSibling){
+                		
+                		if($geomNode->nodeType == XML_ELEMENT_NODE){
+                        	break;
+                        }
+                    }
+                }
+               
 				$geomType = $geomNode->nodeName;
+				
 				if ($geomNode->hasAttribute("srsName")) {
 					$srs = $geomNode->getAttribute("srsName");
 				}
+				//if srsName of featureMember is empty, use the srsName of node //gml:boundedBy/gml:Envelope
+				if($srs == "") {
+					$srs = $gmlBoundedBySrs;
+				}
 				switch ($geomType) {
 					case "gml:Polygon" :// untested!
 						$feature->geometry = self::parsePolygon($geomNode);

Modified: trunk/mapbender/http/classes/class_gml_factory.php
===================================================================
--- trunk/mapbender/http/classes/class_gml_factory.php	2013-06-03 08:28:31 UTC (rev 8641)
+++ trunk/mapbender/http/classes/class_gml_factory.php	2013-06-03 08:56:00 UTC (rev 8642)
@@ -69,9 +69,9 @@
 						$geometry = new GMLPolygon();
 						for ($i = 0; $i < count($currentGeometry->coordinates); $i++) {
 							$currentRing = $currentGeometry->coordinates[$i];
-							
+							$isLatLonSrs = $geometry->isLatLonSrs($srs);
 							foreach ($currentRing as $coords) {
-								if (in_array($srs, $geometry->latLonSrs)) {
+								if ($isLatLonSrs) {
 									list($y, $x) = $coords;
 								}
 								else {
@@ -91,7 +91,7 @@
 						break;
 					case "POINT":
 						$geometry = new GMLPoint();
-						if (in_array($srs, $geometry->latLonSrs)) {
+						if ($geometry->isLatLonSrs($srs)) {
 							list($y, $x) = $currentGeometry->coordinates;
 						}
 						else {
@@ -102,9 +102,10 @@
 						break;
 					case "MULTIPOINT":
 						$geometry = new GMLMultiPoint();
+						$isLatLonSrs = $geometry->isLatLonSrs($srs);
 						for ($i = 0; $i < count($currentGeometry->coordinates); $i++) {
 							$currentPoint = $currentGeometry->coordinates[$i];
-							if (in_array($srs, $geometry->latLonSrs)) {
+							if ($isLatLonSrs) {
 								list($y, $x) = $currentPoint;
 							}
 							else {
@@ -115,9 +116,10 @@
 						break;
 					case "LINESTRING":
 						$geometry = new GMLLine();
+						$isLatLonSrs = $geometry->isLatLonSrs($srs);
 						for ($i = 0; $i < count($currentGeometry->coordinates); $i++) {
 							$currentLinePoint = $currentGeometry->coordinates[$i];
-							if (in_array($srs, $geometry->latLonSrs)) {
+							if ($isLatLonSrs) {
 								list($y, $x) = $currentLinePoint;
 							}
 							else {
@@ -130,12 +132,12 @@
 						$geometry = new GMLMultiPolygon();
 						for ($i = 0; $i < count($currentGeometry->coordinates); $i++) {
 							$currentPolygon = $currentGeometry->coordinates[$i];
-								
+							$isLatLonSrs = $geometry->isLatLonSrs($srs);
 							for ($j = 0; $j < count($currentPolygon); $j++) {
 								$currentRing = $currentPolygon[$j];
 								
 								foreach ($currentRing as $coords) {
-									if (in_array($srs, $geometry->latLonSrs)) {
+									if ($isLatLonSrs) {
 										list($y, $x) = $coords;
 									}
 									else {
@@ -158,8 +160,9 @@
 						$geometry = new GMLMultiLine();
 						for ($i = 0; $i < count($currentGeometry->coordinates); $i++) {
 							$currentLine = $currentGeometry->coordinates[$i];
+							$isLatLonSrs = $geometry->isLatLonSrs($srs);
 							foreach ($currentLine as $currentLinePoint) {
-								if (in_array($srs, $geometry->latLonSrs)) {
+								if ($isLatLonSrs) {
 									list($y, $x) = $currentLinePoint;
 								}
 								else {
@@ -238,24 +241,28 @@
 			$gmlDoc->registerXPathNamespace('wfs', 'http://www.opengis.net/wfs');
 			$gmlDoc->registerXPathNamespace('gml', 'http://www.opengis.net/gml');
 			
+			//get srsName of boundedBy node (needed in case of featureMembers having no srsName)
+			$gmlBoundedBySrs = $gmlDoc->xpath("//gml:boundedBy/gml:Envelope/@srsName");
+			$gmlBoundedBySrs = $gmlBoundedBySrs[0]->srsName;
+			
 			// build feature collection
 			$gml->featureCollection = new FeatureCollection();
 			
 			// segments of the featureCollection
 			//
-			// for *non* Mapserver WFS
+			// WFS getFeature results with gml:featureMember
 			$gmlFeatureMembers = $gmlDoc->xpath("//gml:featureMember");
 			if (count($gmlFeatureMembers) > 0) {
 				foreach ($gmlFeatureMembers as $gmlFeatureMember) {
 					$gmlfeatureMember_dom = dom_import_simplexml($gmlFeatureMember);
 					$feature = new Feature();
-					$this->parseFeature($gmlfeatureMember_dom->firstChild, $feature, $wfsConf);
+					$this->parseFeature($gmlfeatureMember_dom->firstChild, $feature, $wfsConf, $gmlBoundedBySrs);
 					if (isset($feature->geometry)) {
 						$gml->featureCollection->addFeature($feature);
 					}
 				}
 			}
-			// for Mapserver WFS
+			// WFS getFeature results with gml:featureMembers
 			else {
 				// segments of the featureCollection
 				$gmlFeatureMembers = $gmlDoc->xpath("//" . $featureType->name);
@@ -264,7 +271,7 @@
 					foreach ($gmlFeatureMembers as $gmlFeatureMember) {
 						$gmlfeatureMember_dom = dom_import_simplexml($gmlFeatureMember);
 						$feature = new Feature();
-						$this->parseFeature($gmlfeatureMember_dom, $feature, $wfsConf);
+						$this->parseFeature($gmlfeatureMember_dom, $feature, $wfsConf, $gmlBoundedBySrs);
 						if (isset($feature->geometry)) {
 							$gml->featureCollection->addFeature($feature);
 						}

Modified: trunk/mapbender/http/classes/class_gml_geometry.php
===================================================================
--- trunk/mapbender/http/classes/class_gml_geometry.php	2013-06-03 08:28:31 UTC (rev 8641)
+++ trunk/mapbender/http/classes/class_gml_geometry.php	2013-06-03 08:56:00 UTC (rev 8642)
@@ -36,7 +36,27 @@
 	
 	public $latLonSrs = array(
 		"urn:x-ogc:def:crs:EPSG:4326",
-		"urn:x-ogc:def:crs:EPSG:31467"
+		"urn:x-ogc:def:crs:EPSG:4258",
+		"urn:x-ogc:def:crs:EPSG:31466",
+		"urn:x-ogc:def:crs:EPSG:31467",
+		"urn:x-ogc:def:crs:EPSG:31468",
+		"urn:x-ogc:def:crs:EPSG:31469"
 	);
+	
+	public function isLatLonSrs ($geomSrs) {
+		//use user defined $latLonSrsArray from file epsg.php for check 
+		include(dirname(__FILE__)."/../../core/epsg.php");
+		
+		$pattern = '/urn/';
+		if(preg_match($pattern, $geomSrs)) {
+			if(in_array($geomSrs, $latLonSrsArray)) {
+				return true;
+			}
+			else {
+				return false;
+			}	
+		}
+		return false;
+	}
 }
 ?>
\ No newline at end of file

Modified: trunk/mapbender/http/classes/class_gml_line.php
===================================================================
--- trunk/mapbender/http/classes/class_gml_line.php	2013-06-03 08:28:31 UTC (rev 8641)
+++ trunk/mapbender/http/classes/class_gml_line.php	2013-06-03 08:56:00 UTC (rev 8642)
@@ -72,13 +72,14 @@
 	public function toGeoJSON () {
 		$numberOfPoints = count($this->pointArray);
 		$str = "";
+		$isLatLonSrs = $this->isLatLonSrs($this->srs);
 		if ($numberOfPoints > 0) {
 			$str .= "{\"type\": \"LineString\", \"coordinates\":[";
 			for ($i=0; $i < $numberOfPoints; $i++) {
 				if ($i > 0) {
 					$str .= ",";
 				}
-				if (in_array($this->srs, $this->latLonSrs)) {
+				if ($isLatLonSrs) {
 					$str .= "[".$this->pointArray[$i]["y"].",".$this->pointArray[$i]["x"]."]";
 				}
 				else {

Modified: trunk/mapbender/http/classes/class_gml_multiline.php
===================================================================
--- trunk/mapbender/http/classes/class_gml_multiline.php	2013-06-03 08:28:31 UTC (rev 8641)
+++ trunk/mapbender/http/classes/class_gml_multiline.php	2013-06-03 08:56:00 UTC (rev 8642)
@@ -75,6 +75,7 @@
 	public function toGeoJSON () {
 		$numberlineArray = count($this->lineArray);
 		$str = "";
+		$isLatLonSrs = $this->isLatLonSrs($this->srs);
 		if ($numberlineArray > 0) {
 			$str .= "{\"type\": \"MultiLineString\", \"coordinates\":[";
 			
@@ -88,7 +89,7 @@
 					if ($i > 0) {
 						$str .= ",";
 					}
-					if (in_array($this->srs, $this->latLonSrs)) {
+					if ($isLatLonSrs) {
 						$str .= "[".$this->lineArray[$cnt][$i]["y"].",".$this->lineArray[$cnt][$i]["x"]."]";
 					}
 					else {

Modified: trunk/mapbender/http/classes/class_gml_multipoint.php
===================================================================
--- trunk/mapbender/http/classes/class_gml_multipoint.php	2013-06-03 08:28:31 UTC (rev 8641)
+++ trunk/mapbender/http/classes/class_gml_multipoint.php	2013-06-03 08:56:00 UTC (rev 8642)
@@ -65,6 +65,7 @@
 	public function toGeoJSON () {
 		$numberlineArray = count($this->pointArray);
 		$str = "";
+		$isLatLonSrs = $this->isLatLonSrs($this->srs);
 		if ($numberlineArray > 0) {
 			$str .= "{\"type\": \"MultiPoint\", \"coordinates\":[";
 			
@@ -72,7 +73,7 @@
 				if ($cnt > 0) {
 					$str .= ",";
 				}
-				if (in_array($this->srs, $this->latLonSrs)) {
+				if ($isLatLonSrs) {
 					$str .= "[" . $this->pointArray[$cnt]["y"] . "," . 
 						$this->pointArray[$cnt]["x"]."]";
 				}

Modified: trunk/mapbender/http/classes/class_gml_multipolygon.php
===================================================================
--- trunk/mapbender/http/classes/class_gml_multipolygon.php	2013-06-03 08:28:31 UTC (rev 8641)
+++ trunk/mapbender/http/classes/class_gml_multipolygon.php	2013-06-03 08:56:00 UTC (rev 8642)
@@ -133,6 +133,7 @@
 	public function toGeoJSON () {
 		$numberPolygonArray = count($this->polygonArray);
 		$str = "";
+		$isLatLonSrs = $this->isLatLonSrs($this->srs);
 		if ($numberPolygonArray > 0) {
 			$str .= "{\"type\": \"MultiPolygon\", \"coordinates\":[";
 			
@@ -147,7 +148,8 @@
 					if ($i > 0) {
 						$str .= ",";
 					}
-					if (in_array($this->srs, $this->latLonSrs)) {
+					//if (in_array($this->srs, $this->latLonSrs)) {
+					if ($isLatLonSrs) {	
 						$str .= "[".$this->polygonArray[$cnt][$i]["y"].",".$this->polygonArray[$cnt][$i]["x"]."]";
 					}
 					else {
@@ -162,7 +164,8 @@
 						if ($j > 0) {
 							$str .= ",";
 						}
-						if (in_array($this->srs, $this->latLonSrs)) {
+						//if (in_array($this->srs, $this->latLonSrs)) {
+						if ($isLatLonSrs) {
 							$str .= "[".$this->innerRingArray[$cnt][$i][$j]["y"].",".$this->innerRingArray[$cnt][$i][$j]["x"]."]";
 						}
 						else {

Modified: trunk/mapbender/http/classes/class_gml_point.php
===================================================================
--- trunk/mapbender/http/classes/class_gml_point.php	2013-06-03 08:28:31 UTC (rev 8641)
+++ trunk/mapbender/http/classes/class_gml_point.php	2013-06-03 08:56:00 UTC (rev 8642)
@@ -57,7 +57,7 @@
 		$str = "";
 		if ($this->point) {
 			$str .= "{\"type\": \"Point\", \"coordinates\":";
-			if (in_array($this->srs, $this->latLonSrs)) {
+			if ($this->isLatLonSrs($this->srs)) {
 				$str .= "[".$this->point["y"].",".$this->point["x"]."]";
 			}
 			else {

Modified: trunk/mapbender/http/classes/class_gml_polygon.php
===================================================================
--- trunk/mapbender/http/classes/class_gml_polygon.php	2013-06-03 08:28:31 UTC (rev 8641)
+++ trunk/mapbender/http/classes/class_gml_polygon.php	2013-06-03 08:56:00 UTC (rev 8642)
@@ -109,15 +109,18 @@
 	}
 	
 	public function toGeoJSON () {
+		
 		$numberOfPoints = count($this->pointArray);
 		$str = "";
+		$isLatLonSrs = $this->isLatLonSrs($this->srs);
 		if ($numberOfPoints > 0) {
 			$str .= "{\"type\": \"Polygon\", \"coordinates\":[[";
 			for ($i=0; $i < $numberOfPoints; $i++) {
 				if ($i > 0) {
 					$str .= ",";
 				}
-				if (in_array($this->srs, $this->latLonSrs)) {
+				#if (in_array($this->srs, $this->latLonSrs)) {
+				if ($isLatLonSrs) {
 					$str .= "[".$this->pointArray[$i]["y"].",".$this->pointArray[$i]["x"]."]";
 				}
 				else {
@@ -132,7 +135,7 @@
 					if ($j > 0) {
 						$str .= ",";
 					}
-					if (in_array($this->srs, $this->latLonSrs)) {
+					if ($isLatLonSrs) {
 						$str .= "[".$this->innerRingArray[$i][$j]["y"].",".$this->innerRingArray[$i][$j]["x"]."]";
 					}
 					else {

Modified: trunk/mapbender/http/classes/class_universal_wfs_factory.php
===================================================================
--- trunk/mapbender/http/classes/class_universal_wfs_factory.php	2013-06-03 08:28:31 UTC (rev 8641)
+++ trunk/mapbender/http/classes/class_universal_wfs_factory.php	2013-06-03 08:56:00 UTC (rev 8642)
@@ -23,6 +23,7 @@
 require_once(dirname(__FILE__)."/../classes/class_wfs_factory.php");
 require_once(dirname(__FILE__)."/../classes/class_wfs_1_0_factory.php");
 require_once(dirname(__FILE__)."/../classes/class_wfs_1_1_factory.php");
+require_once(dirname(__FILE__)."/../classes/class_wfs_2_0_factory.php");
 
 /**
  * 
@@ -71,6 +72,9 @@
 				case "1.1.0":
 					$factory = new Wfs_1_1_Factory();
 					break;
+				case "2.0.0":
+					$factory = new Wfs_2_0_Factory();
+					break;
 				default:
 					throw new Exception("Unknown WFS version " . $version);
 					break;
@@ -100,6 +104,9 @@
 					case "1.1.0":
 						$factory = new Wfs_1_1_Factory();
 						break;
+					case "2.0.0":
+						$factory = new Wfs_2_0_Factory();
+						break;
 					default:
 						throw new Exception("Unknown WFS version " . $version);
 						break;

Modified: trunk/mapbender/http/classes/class_wfs.php
===================================================================
--- trunk/mapbender/http/classes/class_wfs.php	2013-06-03 08:28:31 UTC (rev 8641)
+++ trunk/mapbender/http/classes/class_wfs.php	2013-06-03 08:56:00 UTC (rev 8642)
@@ -27,7 +27,7 @@
 
 /**
  * An abstract Web Feature Service (WFS) class, modelling for example
- * WFS 1.0.0 or WFS 1.1.0
+ * WFS 1.0.0, WFS 1.1.0 or WFS 2.0.0
  */
 abstract class Wfs extends Ows {
 	var $describeFeatureType;
@@ -36,6 +36,8 @@
 	var $transaction;
 	var $overwrite = true;
 	var $featureTypeArray = array();
+	var $operationsArray = array();
+	var $storedQueriesArray = array();
 	
 	/**
 	 * Returns the version of this WFS. Has to be implemented by the subclass.
@@ -99,34 +101,85 @@
 		return $this->get($url);
 	}
 	
-	protected function getFeaturePost ($featureTypeName, $filter, $destSrs) {
-		$postData = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" . 
-			"<wfs:GetFeature service=\"WFS\" version=\"" . $this->getVersion() . "\" " . 
-			"xmlns:wfs=\"http://www.opengis.net/wfs\" " . 
-			"xmlns:gml=\"http://www.opengis.net/gml\" " . 
-			"xmlns:ogc=\"http://www.opengis.net/ogc\">" . 
-			"<wfs:Query ";
-		
-		if($destSrs) {
-			$postData .= "srsName=\"" . $destSrs . "\" ";
+	protected function getFeaturePost ($featureTypeName, $filter, $destSrs, $storedQueryId, $storedQueryParams) {
+		if($storedQueryId && $storedQueryId != "") {
+			$postData = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" .
+					"<wfs:GetFeature service=\"WFS\" version=\"" . $this->getVersion() . "\" " .
+					"xmlns:wfs=\"http://www.opengis.net/wfs/2.0\" " .
+					//"xmlns:xlink=\"http://www.w3.org/1999/xlink\" " .
+					//"xmlns:ogc=\"http://www.opengis.net/ogc\" ".
+					//"xmlns:ows=\"http://www.opengis.net/ows/1.1\" " .
+					"xmlns:gml=\"http://www.opengis.net/gml/3.2\" " .
+					"xmlns:fes=\"http://www.opengis.net/fes/2.0\" " .
+					"xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" " .
+					"xsi:schemaLocation=\"http://www.opengis.net/wfs/2.0 http://schemas.opengis.net/wfs/2.0/wfs.xsd\">";
+			$postData .= "<wfs:StoredQuery id=\"" . $storedQueryId . "\">";
+			$postData .= $storedQueryParams;
+			$postData .= "</wfs:StoredQuery>";
 		}
+		else {
+			if($this->getVersion() == "2.0.0") {
+				$postData = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" .
+					"<wfs:GetFeature service=\"WFS\" version=\"" . $this->getVersion() . "\" " .
+					"xmlns:wfs=\"http://www.opengis.net/wfs/2.0\" ".
+					"xmlns:fes=\"http://www.opengis.net/fes/2.0\" ".
+					"xmlns:gml=\"http://www.opengis.net/gml/3.2\" ".
+					"xmlns:ogc=\"http://www.opengis.net/ogc\" " .
+					"xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" " .
+					"xsi:schemaLocation=\"http://www.opengis.net/wfs/2.0 http://schemas.opengis.net/wfs/2.0/wfs.xsd\">";
+			}
+			else if($this->getVersion() == "1.1.0") {
+				$postData = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" .
+						"<wfs:GetFeature service=\"WFS\" version=\"" . $this->getVersion() . "\" " .
+						"xmlns:wfs=\"http://www.opengis.net/wfs\" " .
+						"xmlns:gml=\"http://www.opengis.net/gml\" " .
+						"xmlns:ogc=\"http://www.opengis.net/ogc\" " .
+						"xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" " .
+						"xsi:schemaLocation=\"http://www.opengis.net/wfs ../wfs/1.1.0/WFS.xsd\">";
+			}
+			else {
+				$postData = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" .
+						"<wfs:GetFeature service=\"WFS\" version=\"" . $this->getVersion() . "\" " .
+						"xmlns:wfs=\"http://www.opengis.net/wfs\" " .
+						"xmlns:gml=\"http://www.opengis.net/gml\" " .
+						"xmlns:ogc=\"http://www.opengis.net/ogc\" " .
+						"xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" " .
+						"xsi:schemaLocation=\"http://www.opengis.net/wfs ../wfs/1.0.0/WFS-basic.xsd\">";
+			}
+			$postData .="<wfs:Query ";
+			if($destSrs) {
+				$postData .= "srsName=\"" . $destSrs . "\" ";
+			}
+			// add namespace
+			if (strpos($featureTypeName, ":") !== false) {
+				$ft = $this->findFeatureTypeByName($featureTypeName);
+				$ns = $this->getNamespace($featureTypeName);
+				$url = $ft->getNamespace($ns);
+				$postData .= "xmlns:" . $ns . "=\"" . $url . "\" ";
+					
+			}
+			if($this->getVersion() == "2.0.0") {
+				//change filter to fes syntax
+				$filter = str_replace("<ogc", "<fes", $filter);
+				$filter = str_replace("/ogc", "/fes", $filter);
+				$filter = str_replace("PropertyName", "ValueReference", $filter);
+				$postData .= "typeNames=\"" . $featureTypeName . "\">" .
+						$filter .
+						"</wfs:Query>";
+			}
+			else {
+				$postData .= "typeName=\"" . $featureTypeName . "\">" .
+						$filter .
+						"</wfs:Query>";
+			}
+		}
 		
-		// add namespace
-		if (strpos($featureTypeName, ":") !== false) {
-			$ft = $this->findFeatureTypeByName($featureTypeName);
-			$ns = $this->getNamespace($featureTypeName);
-			$url = $ft->getNamespace($ns);
-			$postData .= "xmlns:" . $ns . "=\"" . $url . "\" ";
-			
-		}
-		$postData .= "typeName=\"" . $featureTypeName . "\">" . 
-			$filter . 
-			"</wfs:Query></wfs:GetFeature>";		
+		$postData .= "</wfs:GetFeature>";		
 
 		return $this->post($this->getFeature, $postData);
 	}
 	
-	public function getFeature ($featureTypeName, $filter, $destSrs=null) {
+	public function getFeature ($featureTypeName, $filter, $destSrs=null, $storedQueryId=null, $storedQueryParams=null) {
 
 // FOR NOW, WE ONLY DO POST REQUESTS!
 // THE FILTERS ARE CONSTRUCTED ON THE CLIENT SIDE,
@@ -134,7 +187,7 @@
 // WOULD BE TOO MUCH FOR NOW
 //
 //		if (strpos($this->getFeature, "?") === false) {
-			return $this->getFeaturePost($featureTypeName, $filter, $destSrs);
+			return $this->getFeaturePost($featureTypeName, $filter, $destSrs, $storedQueryId, $storedQueryParams);
 //		}
 //		return $this->getFeatureGet($featureTypeName, $filter);
 	}
@@ -356,10 +409,10 @@
 			"\" service=\"WFS\" " . $ns_gml . $ns_ogc . $ns_xsi . 
 			$ns_featureNS . $ns_wfs . 
 			"xsi:schemaLocation=\"http://www.opengis.net/wfs" . 
-			" http://schemas.opengis.net/wfs/1.0.0/WFS-transaction.xsd " . 
+			" http://schemas.opengis.net/wfs/1.0.0/WFS-transaction.xsd" . 
 			$strForSchemaLocation . " " . $this->describeFeatureType . 
 			$this->getConjunctionCharacter($this->describeFeatureType) . 
-			"typename=" . $featureType->name . 
+			"typename=" . $featureType->name . "amp;request=DescribeFeaturetype".
 			"\">" .	$wfsRequest . "</wfs:Transaction>";
 	}
 	
@@ -391,6 +444,34 @@
 			$currentFeatureType = $this->featureTypeArray[$i];
 			$wfsString .= $currentFeatureType->toHtml();
 		}
+		
+		for ($i = 0; $i < count($this->storedQueriesArray); $i++) {
+			$currentQuery = $this->storedQueriesArray[$i];
+			$wfsString .= "<hr>";
+			$wfsString .= "Stored Query ID: ". $currentQuery->description['Id'] . " <br>";
+			$wfsString .= "title: ".$currentQuery->description['Title']. " <br>";
+			$wfsString .= "returnFeaturetype: ".$currentQuery->returnFeaturetype. " <br>";
+			if(gettype($aWfsStoredQuery->description['Parameter'][0]) == "array") {
+				for ($i = 0; $i < count($currentQuery->description['Parameter']); $i++) {
+					$param = $currentQuery->description['Parameter'][$i];
+					$name = $param['name'];
+					$type = $param['type'];
+					$wfsString .= " parameter: " . $name . 
+							" - " . $type . "<br>";
+				}
+			}
+			else {
+				$param = $currentQuery->description['Parameter'];
+			
+				if($param) {
+					$name = $param['name'];
+					$type = $param['type'];
+					$wfsString .= " parameter: " . $name .
+					" - " . $type . "<br>";
+				}
+			}
+		}
+		
 		return $wfsString;
 	}
 

Modified: trunk/mapbender/http/classes/class_wfsToDb.php
===================================================================
--- trunk/mapbender/http/classes/class_wfsToDb.php	2013-06-03 08:28:31 UTC (rev 8641)
+++ trunk/mapbender/http/classes/class_wfsToDb.php	2013-06-03 08:56:00 UTC (rev 8642)
@@ -103,6 +103,15 @@
 		// set the WFS id
 		$aWfs->id = db_insert_id($con, 'wfs', 'wfs_id');
 		
+		// Insert the WFS operations
+		for ($i = 1; $i < count($aWfs->operationsArray); $i++) {
+			$currentOp = $aWfs->operationsArray[$i];
+			if (!WfsToDb::insertOperation($aWfs->id, $currentOp)) {
+				db_rollback();
+				return false;
+			}
+		}
+		
 		// Insert the feature types
 		for ($i = 0; $i < count($aWfs->featureTypeArray); $i++) {
 			$currentFeatureType = $aWfs->featureTypeArray[$i];
@@ -112,6 +121,16 @@
 			}
 		}
 		db_commit();
+		
+		//This can only be done when WFS is already inserted into DB, because we need the db featuretype id for inserting
+		// Insert the WFS StoredQueries as wfs confs into DB
+		for ($i = 0; $i < count($aWfs->storedQueriesArray); $i++) {
+			$currentStoredQuery = $aWfs->storedQueriesArray[$i];
+			if (!WfsToDb::insertStoredQuery($aWfs->id, $currentStoredQuery)) {
+				$e = new mb_exception("class_wfsToDb.php: StoredQuery could not be inserted into DB.");
+			}
+		}
+		
 		return true;		
 	}
 	
@@ -194,6 +213,23 @@
 			db_rollback();
 			return false;
 		}
+		
+		# delete and refill WFS operations
+		$sql = "DELETE FROM wfs_operation WHERE fkey_wfs_id = $1 ";
+		$v = array($aWfs->id);
+		$t = array('i');
+		$res = db_prep_query($sql,$v,$t);
+		if(!$res){
+			db_rollback();
+		}
+		for ($i = 1; $i < count($aWfs->operationsArray); $i++) {
+			$currentOp = $aWfs->operationsArray[$i];
+			if (!WfsToDb::insertOperation($aWfs->id, $currentOp)) {
+				db_rollback();
+				return false;
+			}
+		}
+	
 		if ($updateMetadataOnly) {
 			# delete and refill wfs_termsofuse
 			$sql = "DELETE FROM wfs_termsofuse WHERE fkey_wfs_id = $1 ";
@@ -205,6 +241,7 @@
 			}
 			WfsToDb::insertTermsOfUse($aWfs);
 		}
+	
 		# update TABLE wfs_featuretype
 		$oldFeatureTypeNameArray = array();
 		$v = array($aWfs->id);
@@ -280,6 +317,60 @@
 			return false;
 		}
 		$e = new mb_notice("class_wfsToDb.php: Number of featuretypes not to delete: ".count($featureTypeNameArray));
+		
+		//if WFS has storedQueries, check them for insert and update
+		if(count($aWfs->storedQueriesArray) > 0) {
+			if (!$updateMetadataOnly) {
+				$storedQueryIdArray = array();
+					
+				for ($i = 0; $i < count($aWfs->storedQueriesArray); $i++) {
+					$currentStoredQuery = $aWfs->storedQueriesArray[$i];
+					array_push($storedQueryIdArray, $currentStoredQuery);
+					$storedQueryWfsConfId = WfsToDb::storedQueryExists($aWfs->id, $currentStoredQuery->description['Id']);
+					if ($storedQueryWfsConfId && $storedQueryWfsConfId != "") {
+						// update existing WFS stored query
+						$e = new mb_notice("class_wfsToDb.php: Stored query exists");
+						if (!WfsToDb::updateStoredQuery($storedQueryWfsConfId, $currentStoredQuery)) {
+							db_rollback();
+							return false;
+						}
+					}
+					else {
+						$e = new mb_notice("class_wfsToDb.php: Stored query ne pas exists");
+						// insert new WFS stored query
+						if (!WfsToDb::insertStoredQuery($aWfs->id, $currentStoredQuery)) {
+							db_rollback();
+							return false;
+						}
+					}
+				}
+					
+				// delete obsolete WFS stored queries
+				$v = array($aWfs->id);
+				$t = array("i");
+				$sql = "DELETE FROM wfs_conf WHERE fkey_wfs_id = $1";
+				$sql_in = "";
+				for ($i = 0; $i < count($storedQueryIdArray); $i++) {
+					if ($i > 0) {
+						$sql_in .= ", ";
+					}
+					$sql_in .= "$" . ($i+2);
+					array_push($v, $storedQueryIdArray[$i]->description['Id']);
+					array_push($t, "s");
+				}
+				if ($sql_in !== "") {
+					$sql .=  " AND stored_query_id NOT IN (" . $sql_in . ")";
+				}
+				$res = db_prep_query($sql,$v,$t);
+				if (!$res) {
+					$e = new mb_exception("Error while deleting obsolete WFS stored queries in database.");
+					db_rollback();
+					return false;
+				}
+				$e = new mb_notice("class_wfsToDb.php: Number of stored queries not to delete: ".count($storedQueryIdArray));
+			}
+		}	
+		
 		db_commit();
 		return true;
 	}
@@ -566,6 +657,370 @@
 		
 		return true;
 	}
+	
+	/**
+	 * Inserts a new WFS operation into the database.
+	 *
+	 * @return Boolean
+	 * @param $aWfsOperation
+	 */
+	private static function insertOperation ($aWfsId, $aWfsOperation) {
+		$sql = "INSERT INTO wfs_operation (fkey_wfs_id, op_name, " .
+				"op_http_get, op_http_post) " .
+				"VALUES($1, $2, $3, $4)";
+	
+		$v = array(
+				$aWfsId,
+				$aWfsOperation->name,
+				$aWfsOperation->httpGet,
+				$aWfsOperation->httpPost
+		);
+		$t = array('i','s','s','s');
+	
+		$res = db_prep_query($sql,$v,$t);
+		if (!$res) {
+			$e = new mb_exception("Error while inserting WFS operation into database.");
+			return false;
+		}
+	
+		return true;
+	}
+	
+	/**
+	 * Inserts a new WFS StoredQuery as wfs conf into the database.
+	 *
+	 * @return Boolean
+	 * @param $aWfsStoredQuery 
+	 */
+	private static function insertStoredQuery ($aWfsId, $aWfsStoredQuery) {
+		$wfsFtName = $aWfsStoredQuery->description['QueryExpressionText']['returnFeatureTypes'];
+		if($wfsFtName == "") {
+			$wfsFtName = $aWfsStoredQuery->returnFeaturetype;
+		}
+		
+		//if returnFeaturetype is not defined for storedQuery check for default storedQuery urn:ogc:def:query:OGC-WFS::GetFeatureById 
+		if($wfsFtName == "") {
+			if($aWfsStoredQuery->description['Id'] == 'urn:ogc:def:query:OGC-WFS::GetFeatureById') {
+				//insert this default stored query for every existing featuretype
+				$sql = "SELECT featuretype_id, featuretype_name FROM wfs_featuretype WHERE fkey_wfs_id = $1;";
+				$v = array($aWfsId);
+				$t = array("i");
+				$res = db_prep_query($sql, $v, $t);
+				if (!$res) {
+					$e = new mb_exception("class_wfsToDb.php: Error getting related featuretype_id from DB.");
+					return false;
+				}
+				while ($row = db_fetch_array($res)) {
+					$ftId = $row["featuretype_id"];
+					if($ftId && $ftId != "") {
+						//insert this stored query as new wfs conf
+						$insertWfsConf = WfsToDb::insertStoredQueryAsWfsConf($aWfsId, $aWfsStoredQuery, $ftId, $row["featuretype_name"]);
+						return $insertWfsConf;
+					}
+				}
+				
+			}
+			else {
+				$e = new mb_notice("class_wfsToDb.php: StoredQuery ".$aWfsStoredQuery->description['Id']." does not have a  returnFeaturetype, cannot be matched with featuretype.");
+				return false;
+			}
+		}
+		else {
+			//get Featuretype ID using the returnFeaturetype name
+			$sql = "SELECT featuretype_id FROM wfs_featuretype WHERE fkey_wfs_id = $1 AND featuretype_name = $2;";
+			$v = array($aWfsId, $wfsFtName);
+			$t = array("i", "s");
+			$res = db_prep_query($sql, $v, $t);
+			if (!$res) {
+				$e = new mb_exception("class_wfsToDb.php: Error getting featuretype_id from DB.");
+				return false;
+			}
+			$row = db_fetch_array($res);
+			$ftId = $row["featuretype_id"];
+			
+			if($ftId && $ftId != "") {
+				//insert this stored query as new wfs conf
+				$insertWfsConf = WfsToDb::insertStoredQueryAsWfsConf($aWfsId, $aWfsStoredQuery, $ftId);
+				return $insertWfsConf;
+			}	
+		}
+	}
+	
+	/**
+	 * Updates a WFS StoredQuery as wfs conf into the database.
+	 *
+	 * @return Boolean
+	 * @param $aWfsConfId
+	 * @param $aWfsStoredQuery
+	 */
+	private static function updateStoredQuery ($aWfsConfId, $aWfsStoredQuery) {
+		// delete all query params of this WFS stored query
+		$sql = "DELETE FROM wfs_stored_query_params WHERE ";
+		$sql .= "fkey_wfs_conf_id = $1;";
+		$v = array($aWfsConfId);
+		$t = array("i");
+		$res = db_prep_query($sql, $v, $t);
+		if (!$res) {
+			$e = new mb_exception("Error while deleting WFS stored query params from the database.");
+			return false;
+		}
+		
+		if(gettype($aWfsStoredQuery->description['Parameter'][0]) == "array") {
+			for ($i = 0; $i < count($aWfsStoredQuery->description['Parameter']); $i++) {
+				$param = $aWfsStoredQuery->description['Parameter'][$i];
+			
+				$name = $param['name'];
+				$type = $param['type'];
+			
+				$sql = "INSERT INTO wfs_stored_query_params (
+						fkey_wfs_conf_id,
+						stored_query_id,
+						query_param_name,
+						query_param_type
+					) VALUES (
+					$1, $2, $3, $4);";
+				$v = array(
+					$aWfsConfId, $aWfsStoredQuery->description['Id'], $param['name'], $param['type']
+				);
+				$t = array(
+					"i", "s", "s", "s"
+				);
+				$res = db_prep_query($sql, $v, $t);
+				if (!$res) {
+					$e = new mb_exception("class_wfsToDb.php: StoredQuery Params Insert failed.");
+					db_rollback();
+					return false;
+				}
+			}
+		}
+		else {
+			$param = $aWfsStoredQuery->description['Parameter'];
+	
+			if($param) {
+				$name = $param['name'];
+				$type = $param['type'];
+			
+				$sql = "INSERT INTO wfs_stored_query_params (
+					fkey_wfs_conf_id,
+					stored_query_id,
+					query_param_name,
+							query_param_type
+					) VALUES (
+						$1, $2, $3, $4);";
+				$v = array(
+					$aWfsConfId, $aWfsStoredQuery->description['Id'], $param['name'], $param['type']
+				);
+				$t = array(
+					"i", "s", "s", "s"
+				);
+				$res = db_prep_query($sql, $v, $t);
+				if (!$res) {
+					$e = new mb_exception("class_wfsToDb.php: StoredQuery Params Insert failed.");
+					db_rollback();
+					return false;
+				}
+			}
+		}
+			
+		return true;
+	}
+	
+	private static function insertStoredQueryAsWfsConf ($aWfsId, $aWfsStoredQuery, $aFtId, $aFtName=null) {
+		if($aWfsStoredQuery->description['Title'] && $aWfsStoredQuery->description['Title'] != "") {
+			$title = $aWfsStoredQuery->description['Title']." ".$aFtName;
+		}
+		else {
+			$title = $aWfsStoredQuery->description['Id']." ".$aFtName;
+		}
+			
+		db_begin();
+			
+		$style = "body{
+					 font-family:Verdana,Arial,sans-serif;
+					 font-size: 12px;
+					 line-height:2;
+					}
+		
+					.a{
+					 font-weight:bold;
+					}
+					.b{
+					 font-family:Verdana,Arial,sans-serif;
+					 font-size: 12px;
+					 width:40px;
+					}
+		
+					.c{
+					 width:100px;
+					}
+		
+					.d{
+					 color:#808080;
+				}";
+		
+		$sql = "INSERT INTO wfs_conf (
+					wfs_conf_abstract,
+					fkey_wfs_id,
+					fkey_featuretype_id,
+					g_label,
+					g_button,
+					wfs_conf_description,
+					wfs_conf_type,
+					stored_query_id,
+					g_style,
+					g_label_id,
+					g_button_id
+				) VALUES (
+					$1, $2, $3, $4, 'OK', $5, 0, $6, $7, 'a', 'b');";
+		$v = array(
+				$title, $aWfsId, $aFtId,
+				$aWfsStoredQuery->description['Id']." ".$aFtName, $title,
+				$aWfsStoredQuery->description['Id'],
+				$style
+		);
+		$t = array(
+				"s", "i", "i", "s", "s", "s", "s"
+		);
+		$res = db_prep_query($sql, $v, $t);
+		if (!$res) {
+			$e = new mb_exception("class_wfsToDb.php: StoredQuery Insert as WFS Conf failed.");
+			db_rollback();
+			return false;
+		}
+			
+		//
+		// get ID of this WFS conf
+		//
+		$sql = "SELECT max(wfs_conf_id) AS max_id FROM wfs_conf";
+		$res = db_query($sql);
+		if (!$res) {
+			db_rollback();
+			return false;
+		}
+		$row = db_fetch_array($res);
+		$id = $row["max_id"];
+		if (!$id) {
+			db_rollback();
+			return false;
+		}
+			
+		if(gettype($aWfsStoredQuery->description['Parameter'][0]) == "array") {
+			for ($i = 0; $i < count($aWfsStoredQuery->description['Parameter']); $i++) {
+				$param = $aWfsStoredQuery->description['Parameter'][$i];
+			
+				$name = $param['name'];
+				$type = $param['type'];
+			
+				$sql = "INSERT INTO wfs_stored_query_params (
+						fkey_wfs_conf_id,
+						stored_query_id,
+						query_param_name,
+						query_param_type
+					) VALUES (
+					$1, $2, $3, $4);";
+				$v = array(
+					$id, $aWfsStoredQuery->description['Id'], $param['name'], $param['type']
+				);
+				$t = array(
+					"i", "s", "s", "s"
+				);
+				$res = db_prep_query($sql, $v, $t);
+				if (!$res) {
+					$e = new mb_exception("class_wfsToDb.php: StoredQuery Params Insert failed.");
+					db_rollback();
+					return false;
+				}
+			}
+		}
+		else {
+			$param = $aWfsStoredQuery->description['Parameter'];
+	
+			if($param) {
+				$name = $param['name'];
+				$type = $param['type'];
+			
+				$sql = "INSERT INTO wfs_stored_query_params (
+					fkey_wfs_conf_id,
+					stored_query_id,
+					query_param_name,
+							query_param_type
+					) VALUES (
+						$1, $2, $3, $4);";
+				$v = array(
+					$id, $aWfsStoredQuery->description['Id'], $param['name'], $param['type']
+				);
+				$t = array(
+					"i", "s", "s", "s"
+				);
+				$res = db_prep_query($sql, $v, $t);
+				if (!$res) {
+					$e = new mb_exception("class_wfsToDb.php: StoredQuery Params Insert failed.");
+					db_rollback();
+					return false;
+				}
+			}
+		}
+			
+		//build wfs conf element object
+		$sql = "SELECT * FROM wfs_element WHERE fkey_featuretype_id = $1 ORDER BY element_id";
+		$v = array($aFtId);
+		$t = array("i");
+		$res = db_prep_query($sql, $v, $t);
+		$cnt = 1;
+		$featuretypeElementArray = array();
+		while ($row = db_fetch_array($res)){
+			$e = new mb_notice("class_wfsToDb.php: Inserting this feature type element (" .
+										$aFtId . ") into WFS conf ($id)");
+			
+			//try to find the geom attr for insert
+			$geomCheckArray = array("MultiPolygonPropertyType",
+									"GeometryPropertyType",
+									"MultiSurfacePropertyType",
+									"PolygonPropertyType",
+									"GeometryPropertyType",
+									"SurfacePropertyType",
+									"MultiLineStringPropertyType",
+									"GeometryPropertyType",
+									"MultiCurvePropertyType",
+									"LineStringPropertyType",
+									"GeometryPropertyType",
+									"CurvePropertyType",
+									"PointPropertyType",
+									"MultiPointPropertyType"
+			);
+			if(in_array($row["element_type"], $geomCheckArray)) {
+				$geomAttr = 1;
+			}
+			else {
+				$geomAttr = 0;
+			}
+			
+			// Insert featuretype element in wfs_conf_element
+			$sqlInsertConfElement = "INSERT INTO wfs_conf_element ";
+			$sqlInsertConfElement .= "(fkey_wfs_conf_id, f_id,f_search,f_pos, f_style_id,";
+			$sqlInsertConfElement .= "f_toupper, f_label, f_label_id, f_show,";
+			$sqlInsertConfElement .= "f_respos, f_form_element_html, f_edit,";
+			$sqlInsertConfElement .= "f_mandatory, f_auth_varname, f_show_detail, f_operator,";
+			$sqlInsertConfElement .= "f_detailpos, f_min_input, f_geom) VALUES";
+			$sqlInsertConfElement .= "($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16,$17,$18,$19)";
+			
+			$v = array($id,$row["element_id"],0,$cnt,"c",0,$row["element_name"].": ","d",1,$cnt,"",0,0,"",0,"","0","0",$geomAttr);
+			$t = array("i", "i","i", "s","s", "i","s","s","i","s","s","i","i","s","i","s","s","s","i");
+			
+			$resInsertConfElement = db_prep_query($sqlInsertConfElement, $v, $t);
+			if (!$res) {
+				$e = new mb_exception("Couldn't insert new feature type element in wfs_conf_element!");
+				return false;
+			}
+			
+			$cnt++;
+		}
+			
+		db_commit();
+			
+		return true;
+	}
+	
 
 	/**
 	 * Inserts a new WFS feature type into the database.
@@ -972,6 +1427,27 @@
 		}
 		return false;
 	}
+	
+	/**
+	 * Checks if a stored query exists in the database.
+	 *
+	 * @return Boolean
+	 * @param $aWfsStoredQuery WfsStoredQuery
+	 */
+	private static function storedQueryExists ($aWfsId, $aWfsStoredQueryId) {
+		$sql = "SELECT * FROM wfs_conf WHERE " .
+				"fkey_wfs_id = $1 AND stored_query_id = $2";
+		$v = array(
+				$aWfsId,
+				$aWfsStoredQueryId
+		);
+		$t = array("i", "s");
+		$res = db_prep_query($sql, $v, $t);
+		if ($row = db_fetch_array($res)) {
+			return $row['wfs_conf_id'];
+		}
+		return false;
+	}
 
 	/**
 	 * Gets the ID of a feature type element 

Modified: trunk/mapbender/http/classes/class_wfs_1_1_factory.php
===================================================================
--- trunk/mapbender/http/classes/class_wfs_1_1_factory.php	2013-06-03 08:28:31 UTC (rev 8641)
+++ trunk/mapbender/http/classes/class_wfs_1_1_factory.php	2013-06-03 08:56:00 UTC (rev 8642)
@@ -295,6 +295,7 @@
 					//<DefaultSRS>urn:ogc:def:crs:EPSG::4326</DefaultSRS><OtherSRS>urn:ogc:def:crs:EPSG::4269</OtherSRS><OtherSRS>urn:ogc:def:crs:EPSG::3978</OtherSRS><OtherSRS>urn:ogc:def:crs:EPSG::3857</OtherSRS><OtherSRS>urn:ogc:def:crs:EPSG::31466</OtherSRS><OtherSRS>urn:ogc:def:crs:EPSG::25832</OtherSRS><OtherSRS>urn:ogc:def:crs:EPSG::4258</OtherSRS>
 					$featuretype_srs = $featureType->DefaultSRS[0];
 					$otherSRSArray = $featureType->OtherSRS;
+					$featuretype_crsArray = array();
 					foreach ($otherSRSArray as $otherSRS) {
 						$e = new mb_notice("other srs: ".$otherSRS);
 						$featuretype_crsArray[] = $otherSRS;

Added: trunk/mapbender/http/classes/class_wfs_2_0.php
===================================================================
--- trunk/mapbender/http/classes/class_wfs_2_0.php	                        (rev 0)
+++ trunk/mapbender/http/classes/class_wfs_2_0.php	2013-06-03 08:56:00 UTC (rev 8642)
@@ -0,0 +1,109 @@
+<?php
+# $Id: class_wfs_2_0.php 3094 2008-10-01 13:52:35Z christoph $
+# http://www.mapbender.org/index.php/class_wfs.php
+# Copyright (C) 2002 CCGIS 
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+require_once(dirname(__FILE__)."/../../core/globalSettings.php");
+require_once(dirname(__FILE__)."/class_connector.php");
+require_once(dirname(__FILE__)."/class_administration.php");
+require_once(dirname(__FILE__)."/class_wfs.php");
+
+class Wfs_2_0 extends Wfs {
+	const VERSION = "2.0.0";
+	
+	public function getVersion () {
+		return "2.0.0";
+	}
+
+	public function transaction ($method, $wfsConf, $geoJson) {
+		$gmlFactory = new Gml_3_Factory();
+		$gmlObj = $gmlFactory->createFromGeoJson($geoJson);
+	
+		return parent::transaction ($method, $wfsConf, $gmlObj);
+	}
+	
+	public function parseTransactionResponse ($xml) {
+		$result = new stdClass();
+		$result->success = false;
+		$result->message = "";
+		$result->xml = $xml;
+		
+		$simpleXml = simplexml_load_string($xml);
+		$simpleXml->registerXPathNamespace('wfs', 'http://www.opengis.net/wfs');
+		$simpleXml->registerXPathNamespace('ogc', 'http://www.opengis.net/ogc');
+		
+		//
+		// get error messages
+		//
+		$nodeArray = $simpleXml->xpath("//wfs:TransactionResults/wfs:Action/wfs:Message");
+		$messageArray = array();
+		if ($nodeArray !== false) {
+			foreach ($nodeArray as $node) {
+				$domNode = dom_import_simplexml($node);
+				
+				$result->success = false;
+				$messageArray[] = $domNode->nodeValue;
+			}
+		}
+		if (count($messageArray) > 0) {
+			$result->message = implode(". ", $messageArray);
+			return $result;		
+		}
+
+		//
+		// Get transaction results
+		//
+		$nodeArray = $simpleXml->xpath("//wfs:TransactionSummary/*");
+		$messageArray = array();
+		if ($nodeArray !== false) {
+			foreach ($nodeArray as $node) {
+				$domNode = dom_import_simplexml($node);
+				$tagName = $this->sepNameSpace($domNode->nodeName);
+				$result->success = true;
+				$messageArray[] = $tagName . ": " . $domNode->nodeValue;
+			}		
+		}
+		if (count($messageArray) > 0) {
+			$result->message = implode(". ", $messageArray);
+
+			// get fid
+			$nodeArray = $simpleXml->xpath("//wfs:InsertResults/wfs:Feature/fes:ResourceId");
+			//$e = new mb_exception(print_r($nodeArray, true));
+			if ($nodeArray !== false) {
+				foreach ($nodeArray as $node) {
+					$domNode = dom_import_simplexml($node);
+					if ($domNode->hasAttribute("rid")) {
+						$result->fid = $domNode->getAttribute("rid");
+					}
+				}
+			}
+			return $result;		
+		}
+		
+		//
+		// Unknown error
+		//
+		$result->message = "An unknown error has occured.";
+		return $result;
+	}
+
+	protected function getFeatureIdFilter ($fid) {
+		return "<ogc:GmlObjectId gml:id=\"$fid\"/>";
+	}
+	
+}
+?>
\ No newline at end of file

Added: trunk/mapbender/http/classes/class_wfs_2_0_factory.php
===================================================================
--- trunk/mapbender/http/classes/class_wfs_2_0_factory.php	                        (rev 0)
+++ trunk/mapbender/http/classes/class_wfs_2_0_factory.php	2013-06-03 08:56:00 UTC (rev 8642)
@@ -0,0 +1,537 @@
+<?php
+# $Id: class_wfs.php 3094 2008-10-01 13:52:35Z christoph $
+# http://www.mapbender.org/index.php/class_wfs.php
+# Copyright (C) 2002 CCGIS
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2, or (at your option)
+# any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+require_once(dirname(__FILE__)."/../../core/globalSettings.php");
+require_once(dirname(__FILE__)."/../classes/class_wfs_factory.php");
+require_once(dirname(__FILE__)."/../classes/class_wfs_2_0.php");
+require_once(dirname(__FILE__)."/../classes/class_wfs_featuretype.php");
+require_once(dirname(__FILE__)."/../classes/class_connector.php");
+require_once(dirname(__FILE__)."/../classes/class_administration.php");
+require_once(dirname(__FILE__)."/../classes/class_xml_parser.php");
+
+/**
+ * Creates WFS 2.0 objects from a capabilities documents.
+ *
+ * @return Wfs_2_0
+ */
+class Wfs_2_0_Factory extends WfsFactory {
+
+	protected function createFeatureTypeFromUrl ($aWfs, $featureTypeName, $featureTypeNsArray) {
+		$postData = "<?xml version=\"1.0\"?>\n".
+				"<DescribeFeatureType version=\"" . $aWfs->getVersion() . "\" " .
+				"service=\"WFS\" xmlns=\"http://www.opengis.net/wfs\" ";
+
+		$nsUrl = $featureTypeNsArray["xmlns:" . $key];
+		if (!$nsUrl) {
+			$nsUrl = $featureTypeNsArray[$key];
+		}
+
+		if ($featuretype_name != $this->sepNameSpace($featureTypeName)) {
+			$key = "xmlns:" . $this->getNameSpace($featureTypeName);
+			$postData .= $key . "=\"" . $nsUrl . "\" ";
+		}
+		$postData .= "><TypeName>" . $featureTypeName . "</TypeName>" .
+				"</DescribeFeatureType>";
+
+		$xml = $this->post($aWfs->describeFeatureType, $postData);
+		return $this->createFeatureTypeFromXml ($xml, $aWfs, $featureTypeName);
+	}
+
+	protected function createFeatureTypeFromUrlGet ($aWfs, $featureTypeName, $featureTypeNsArray) {
+
+		$key = $this->getNameSpace($featureTypeName);
+		$nsUrl = $featureTypeNsArray["xmlns:" . $key];
+		if (!$nsUrl) {
+			$nsUrl = $featureTypeNsArray[$key];
+		}
+		$paramArray = array(
+			"SERVICE=WFS",
+			"VERSION=2.0.0",
+			"REQUEST=DescribeFeatureType",
+			"TYPENAME=" . urlencode($featureTypeName),
+			"NAMESPACE=" . urlencode(
+				"xmlns(" . $key . "=" . $nsUrl . ")"
+		));
+
+		$url = $aWfs->describeFeatureType .
+			$aWfs->getConjunctionCharacter($aWfs->describeFeatureType) .
+			implode("&", $paramArray);
+		
+		$xml = $this->get($url);
+		
+		//parse result to see if it is a real featuretype description
+		return $this->createFeatureTypeFromXml ($xml, $aWfs, $featureTypeName);
+	}
+	
+	protected function createStoredQueryFromUrlGet ($aWfs, $listStoredQueries, $describeStoredQueries) {
+		$paramArray = array(
+				"SERVICE=WFS",
+				"VERSION=2.0.0",
+				"REQUEST=ListStoredQueries"
+		);
+	
+		$url = $listStoredQueries .
+			$aWfs->getConjunctionCharacter($listStoredQueries) .
+			implode("&", $paramArray);
+	
+		$xml = $this->get($url);
+		
+		#$e = new mb_notice("class_wfs_2_0_factory.php: Got following StoredQuery XML: ".$xml);
+		
+		$parser = new XMLParser();
+		$parser->loadXMLFromString($xml);
+		$parser->loadJsonSchemaFromString('{
+		    "cmd": {
+		        "addNamespaces": {
+		            "wfs": "http://www.opengis.net/wfs/2.0"
+		        },
+		        "removeEmptyValues" : true
+		    },
+		    "storedQuery": {
+		        "path": "/*/wfs:StoredQuery",
+		        "data": {
+		            "Id": "@id",
+		            "Title" : "wfs:Title/text()",
+		            "ReturnFeatureType" : "wfs:ReturnFeatureType/text()"
+		        }
+		    }
+		}');
+		
+		$array = $parser->parse();
+		
+		$storedQueryArray = array();
+		
+		$m = 0;
+		foreach($array['storedQuery'] as $storedQuery) {
+			$storedQueryArray[$m]->id = $storedQuery['Id'];
+			$storedQueryArray[$m]->title = $storedQuery['Title'];
+			$storedQueryArray[$m]->returnFeaturetype = $storedQuery['ReturnFeatureType'];
+				
+			$storedQueryArray[$m]->description = $this->createSingleStoredQuery($describeStoredQueries, $storedQueryArray[$m]->id, $aWfs);
+				
+			$m++;
+		}
+		
+		return $storedQueryArray;
+	}
+
+	/**
+	 * Given an XSD document (usually from a DescribefeatureType Operation) 
+	 * @returns a WfsFeatureType
+	 * 
+
+	*/
+	protected function createFeatureTypeFromXml ($xml, $myWfs, $featureTypeName) {
+		$newFeatureType = new WfsFeatureType($myWfs);
+
+		$doc = new DOMDocument();
+		$doc->loadXML($xml);
+		$e = new mb_notice("class_wfs_2_0_factory.php: Got following FeatureType XML: ".$xml);
+		$xpath =  new DOMXpath($doc);
+		$xpath->registerNamespace("xs","http://www.w3.org/2001/XMLSchema");
+
+		// populate a Namespaces Hastable where we can use thec namesopace as a lookup for the prefix
+		// and also keep a 
+		$namespaces = array();
+		$namespaceList = $xpath->query("//namespace::*");
+		$targetNamespace = $doc->documentElement->getAttribute("targetNamespace");
+		$targetNamespaceNode = null;
+
+		foreach($namespaceList as $namespaceNode){
+			$namespaces[$namespaceNode->nodeValue] = $namespaceNode->localName;
+			if($namespaceNode->nodeValue == $targetNamespace){
+				$targetNamespaceNode = $namespaceNode;
+			}
+			$newFeatureType->addNamespace($namespaceNode->localName, $namespaceNode->nodeValue);
+		}
+	
+		list($ftLocalname,$ftTypePrefix) = array_reverse(explode(":",$featureTypeName));
+		// for the sake of simplicity we only care about top level elements. Seems to have worked so far
+		$query = sprintf("/xs:schema/xs:element[@name='%s']",$ftLocalname);
+		$elementList = $xpath->query($query);
+
+		foreach ($elementList as $elementNode){
+			$elementName = $elementNode->getAttribute("name");
+			$elementType = $elementNode->getAttribute("type");
+
+            // if Type is empty, we assume an anonymousType, else we go looking for the anmed Type
+            if($elementType == ""){
+                // Just querying for complexTypes containing a Sequence - good enough for Simple Features
+                $query = "xs:complexType//xs:element";
+                $subElementList = $xpath->query($query,$elementNode);
+
+            }else{
+
+                // The elementType is now bound to a prefix e.g. topp:housType
+                // if the prefix is in the targetNamespace, changces are good it's defined in this very document
+                // if the prefiox is not in the targetNamespace, it's likely not defined here, and we bail
+
+                list($elementTypeLocalname,$elementTypePrefix) = array_reverse(explode(":",$elementType));
+                $elementTypeNamespace = $doc->lookupNamespaceURI($elementTypePrefix);
+                if($elementTypeNamespace !== $targetNamespaceNode->nodeValue){
+                    $e = new mb_warning("Tried to parse FeatureTypeName $featureTypeName : $elementType is not in the targetNamespace");	
+                    break;
+                }
+
+                // Just querying for complexTypes containing a Sequence - good enough for Simple Features
+                $query = sprintf("//xs:complexType[@name='%s']//xs:element",$elementTypeLocalname);
+                $subElementList = $xpath->query($query);
+
+            }
+			foreach($subElementList as $subElement){
+                // Since this is a rewrite of the old way, it reproduces it quirks
+                // in this case the namespace of the type was cut off for some reason
+				$name = $subElement->getAttribute('name');
+                $typeParts = explode(":",$subElement->getAttribute('type'));
+                if(count($typeParts) == 1){
+                    $type = $typeParts[0];
+                }else{
+                    $type = $typeParts[1];
+                }
+				$newFeatureType->addElement($name,$type);
+			}
+
+		}
+		return $newFeatureType;
+	}
+	
+	protected function createSingleStoredQuery ($describeStoredQueryUrl, $storedQueryId, $aWfs) {
+		$paramArray = array(
+				"SERVICE=WFS",
+				"VERSION=2.0.0",
+				"REQUEST=DescribeStoredQueries",
+				"STOREDQUERY_ID=" . $storedQueryId
+		);
+	
+		$url = $describeStoredQueryUrl .
+		$aWfs->getConjunctionCharacter($describeStoredQueryUrl) .
+		implode("&", $paramArray);
+	
+		$xml = $this->get($url);
+		
+		//parse result to get storedQuery attributes
+		$e = new mb_notice("class_wfs_2_0_factory.php: Got following StoredQuery DescribeStoredQueries XML: ".$xml);
+		
+		$parser = new XMLParser();
+		$parser->loadXMLFromString($xml);
+		$parser->loadJsonSchemaFromString('{
+		    "cmd": {
+		        "addNamespaces": {
+		            "wfs": "http://www.opengis.net/wfs/2.0",
+					"fes": "http://www.opengis.net/fes/2.0"
+		        },
+			"asArray": true,
+	        "removeEmptyValues" : true
+		    },
+		    "StoredQueryDescription": {
+		        "path": "/*/wfs:StoredQueryDescription",
+		        "data": {
+		            "Id": "@id",
+		            "Title" : "wfs:Title/text()",
+		            "Abstract" : "wfs:Abstract/text()",
+				    "Parameter" : {
+						"path": "wfs:Parameter",
+						"data": {
+							"name": "@name",
+							"type": "@type"
+						}
+					},
+					"QueryExpressionText" : {
+						"path": "wfs:QueryExpressionText",
+						"data": {
+							"isPrivate": "@isPrivate",
+							"language": "@language",
+							"returnFeatureTypes": "@returnFeatureTypes",
+							"query" : {
+								"path": "wfs:Query",
+								"data": {
+									"srsName": "@srsName",
+									"typeNames": "@typeNames",
+									"filter": ["fes:Filter", "raw"]
+								}
+							}
+						}
+					}
+		        }
+		    }
+		}');
+		
+		$array = $parser->parse();
+		$queryAttr = $array['StoredQueryDescription'];
+		
+		return $queryAttr;
+	}
+		
+	/**
+	 * Creates a WFS 2.0 object from a capabilities document.
+	 *
+	 * @return Wfs_2_0
+	 * @param $xml String
+	 */
+	public function createFromXml ($xml) {
+		try {
+
+			$myWfs = new Wfs_2_0();
+
+			$admin = new administration();
+			$myWfs->getCapabilitiesDoc = $admin->char_encode($xml);
+			$myWfs->id = $this->createId();
+
+			$featuretype_crsArray = array();
+
+			try {
+				$xml = str_replace('xlink:href', 'xlinkhref', $xml);
+				#http://forums.devshed.com/php-development-5/simplexml-namespace-attributes-problem-452278.html
+				#http://www.leftontheweb.com/message/A_small_SimpleXML_gotcha_with_namespaces
+
+				$wfs20Cap = new SimpleXMLElement($xml);
+
+				if ($wfs20Cap === false) {
+					foreach(libxml_get_errors() as $error) {
+        					$e = new mb_exception($error->message);
+    					}
+					throw new Exception('Cannot parse WFS 2.0.0 Capabilities!');
+				}
+			}
+			catch (Exception $e) {
+    				$e = new mb_exception($e->getMessage());
+			}	
+
+			if ($wfs20Cap !== false) {
+				//read all relevant information an put them into the mapbender wfs object
+				//xmlns="http://www.opengis.net/wfs"
+				//Setup default namespace
+
+				$wfs20Cap->registerXPathNamespace("wfs", "http://www.opengis.net/wfs");
+				$wfs20Cap->registerXPathNamespace("ows", "http://www.opengis.net/ows");
+				$wfs20Cap->registerXPathNamespace("gml", "http://www.opengis.net/gml");
+				$wfs20Cap->registerXPathNamespace("ogc", "http://www.opengis.net/ogc");
+				$wfs20Cap->registerXPathNamespace("xlink", "http://www.w3.org/1999/xlink");
+				$wfs20Cap->registerXPathNamespace("xsi", "http://www.w3.org/2001/XMLSchema-instance");
+				$wfs20Cap->registerXPathNamespace("default", "http://www.opengis.net/wfs");
+				//some debug
+				//$e = new mb_notice("XML string from memory: ".$wfs20Cap->asXML());
+				$myWfs->version = $wfs20Cap->xpath('/wfs:WFS_Capabilities/@version');
+				$myWfs->version = $myWfs->version[0];
+				//identification part
+				$myWfs->name = $wfs20Cap->xpath('/wfs:WFS_Capabilities/ows:ServiceIdentification/ows:Name');
+				$myWfs->name = $myWfs->name[0];
+				$myWfs->title = $wfs20Cap->xpath('/wfs:WFS_Capabilities/ows:ServiceIdentification/ows:Title');
+				$myWfs->title = $this->stripEndlineAndCarriageReturn($myWfs->title[0]);
+				$myWfs->summary = $wfs20Cap->xpath('/wfs:WFS_Capabilities/ows:ServiceIdentification/ows:Abstract');
+				$myWfs->summary = $this->stripEndlineAndCarriageReturn($myWfs->summary[0]);
+				$myWfs->fees = $wfs20Cap->xpath('/wfs:WFS_Capabilities/ows:ServiceIdentification/ows:Fees');
+				$myWfs->fees = $myWfs->fees[0];
+				$myWfs->accessconstraints = $wfs20Cap->xpath('/wfs:WFS_Capabilities/ows:ServiceIdentification/ows:AccessConstraints');
+				$myWfs->accessconstraints = $myWfs->accessconstraints[0];
+				//provider part
+				$myWfs->individualName = $wfs20Cap->xpath('/wfs:WFS_Capabilities/ows:ServiceProvider/ows:ServiceContact/ows:IndividualName');
+				$myWfs->individualName = $myWfs->individualName[0];
+				
+				$myWfs->positionName = $wfs20Cap->xpath('/wfs:WFS_Capabilities/ows:ServiceProvider/ows:ServiceContact/ows:PositionName');
+				$myWfs->positionName = $myWfs->positionName[0];
+
+				$myWfs->providerName = $wfs20Cap->xpath('/wfs:WFS_Capabilities/ows:ServiceProvider/ows:ProviderName');
+				$myWfs->providerName = $myWfs->providerName[0];
+				
+				$myWfs->city = $wfs20Cap->xpath('/wfs:WFS_Capabilities/ows:ServiceProvider/ows:ServiceContact/ows:ContactInfo/ows:Address/ows:City');
+				$myWfs->city =$myWfs->city[0];
+
+				$myWfs->deliveryPoint = $wfs20Cap->xpath('/wfs:WFS_Capabilities/ows:ServiceProvider/ows:ServiceContact/ows:ContactInfo/ows:Address/ows:DeliveryPoint');
+				$myWfs->deliveryPoint =$myWfs->deliveryPoint[0];
+
+				$myWfs->administrativeArea = $wfs20Cap->xpath('/wfs:WFS_Capabilities/ows:ServiceProvider/ows:ServiceContact/ows:ContactInfo/ows:Address/ows:AdministrativeArea');
+				$myWfs->administrativeArea =$myWfs->administrativeArea[0];
+
+				$myWfs->postalCode = $wfs20Cap->xpath('/wfs:WFS_Capabilities/ows:ServiceProvider/ows:ServiceContact/ows:ContactInfo/ows:Address/ows:PostalCode');
+				$myWfs->postalCode =$myWfs->postalCode[0];
+
+				$myWfs->country = $wfs20Cap->xpath('/wfs:WFS_Capabilities/ows:ServiceProvider/ows:ServiceContact/ows:ContactInfo/ows:Address/ows:Country');
+				$myWfs->country =$myWfs->country[0];
+
+				$myWfs->voice = $wfs20Cap->xpath('/wfs:WFS_Capabilities/ows:ServiceProvider/ows:ServiceContact/ows:ContactInfo/ows:Phone/ows:Voice');
+				$myWfs->voice =$myWfs->voice[0];
+
+				$myWfs->facsimile = $wfs20Cap->xpath('/wfs:WFS_Capabilities/ows:ServiceProvider/ows:ServiceContact/ows:ContactInfo/ows:Phone/ows:Facsimile');
+				$myWfs->facsimile =$myWfs->facsimile[0];
+
+				$myWfs->electronicMailAddress = $wfs20Cap->xpath('/wfs:WFS_Capabilities/ows:ServiceProvider/ows:ServiceContact/ows:ContactInfo/ows:Address/ows:ElectronicMailAddress');
+				$myWfs->electronicMailAddress =$myWfs->electronicMailAddress[0];
+
+
+				//Operation Metadata Part
+
+				$myWfs->getCapabilities = $wfs20Cap->xpath('/wfs:WFS_Capabilities/ows:OperationsMetadata/ows:Operation[@name="GetCapabilities"]/ows:DCP/ows:HTTP/ows:Get/@xlinkhref');
+				$myWfs->getCapabilities = html_entity_decode($myWfs->getCapabilities[0]);
+				$e = new mb_notice($myWfs->getCapabilities);#get
+				
+				$myWfs->describeFeatureType = $wfs20Cap->xpath('/wfs:WFS_Capabilities/ows:OperationsMetadata/ows:Operation[@name="DescribeFeatureType"]/ows:DCP/ows:HTTP/ows:Get/@xlinkhref');
+				$myWfs->describeFeatureType = html_entity_decode($myWfs->describeFeatureType[0]);#get
+				
+				$myWfs->getFeature = $wfs20Cap->xpath('/wfs:WFS_Capabilities/ows:OperationsMetadata/ows:Operation[@name="GetFeature"]/ows:DCP/ows:HTTP/ows:Post/@xlinkhref');
+				$myWfs->getFeature = html_entity_decode($myWfs->getFeature[0]);#post
+				
+				$myWfs->transaction = $wfs20Cap->xpath('/wfs:WFS_Capabilities/ows:OperationsMetadata/ows:Operation[@name="Transaction"]/ows:DCP/ows:HTTP/ows:Post/@xlinkhref');
+				$myWfs->transaction = html_entity_decode($myWfs->transaction[0]);#post
+
+
+				//get list of featuretypes
+				
+				$capFeatureTypes = $wfs20Cap->xpath('/wfs:WFS_Capabilities/wfs:FeatureTypeList/wfs:FeatureType');
+				$i = 1; //cause index of xml objects begin with 1
+				foreach ($capFeatureTypes as $featureType) {
+					//debug
+					$e = new mb_notice("ft: ".$featureType->asXML());
+					//check if the wfs namespaces are used in the featuretype object - as done by e.g. ArcGIS Server
+					$wfsNamespaceUsed = false;
+					$ftNamespaces = $featureType->getNameSpaces(true);
+					foreach ($ftNamespaces as $key => $value) {
+						if ($value == 'http://www.opengis.net/wfs') {
+							$wfsNamespaceUsed = true;
+						}
+					}	
+					if ($wfsNamespaceUsed) {
+						 $featureType = $featureType->children('http://www.opengis.net/wfs');
+					} 
+					$featuretype_name = $this->stripEndlineAndCarriageReturn($featureType->Name[0]);
+					$featuretype_title = $this->stripEndlineAndCarriageReturn($featureType->Title[0]);
+					$featuretype_abstract = $this->stripEndlineAndCarriageReturn($featureType->Abstract[0]);
+					//<DefaultSRS>urn:ogc:def:crs:EPSG::4326</DefaultSRS><OtherSRS>urn:ogc:def:crs:EPSG::4269</OtherSRS><OtherSRS>urn:ogc:def:crs:EPSG::3978</OtherSRS><OtherSRS>urn:ogc:def:crs:EPSG::3857</OtherSRS><OtherSRS>urn:ogc:def:crs:EPSG::31466</OtherSRS><OtherSRS>urn:ogc:def:crs:EPSG::25832</OtherSRS><OtherSRS>urn:ogc:def:crs:EPSG::4258</OtherSRS>
+					$featuretype_srs = $featureType->DefaultCRS[0];
+					$otherCRSArray = $featureType->OtherCRS;
+					foreach ($otherCRSArray as $otherCRS) {
+						$e = new mb_notice("other crs: ".$otherCRS);
+						$featuretype_crsArray[] = $otherCRS;
+						
+					}
+					//<wfs:MetadataURL type="FGDC" format="text/xml">http://www.ogccatservice.com/csw.cgi?service=CSW&version=2.0.0&request=GetRecords&constraintlanguage=CQL&constraint="recordid=urn:uuid:4ee8b2d3-9409-4a1d-b26b-6782e4fa3d59"</wfs:MetadataURL>
+					$metadataURLArray = $featureType->MetadataURL;
+					$featuretype_metadataUrl = array();
+					$i_mdu = 0;
+					foreach ($metadataURLArray as $metadataURL) {
+						//$e = new mb_exception("other srs: ".$otherSRS);
+						$featuretype_metadataUrl[$i_mdu]->href = $metadataURL;
+						$e = new mb_notice("metadataurl: ".$metadataURL);
+						$featuretype_metadataUrl[$i_mdu]->type = $metadataURL->attributes()->type;
+						$e = new mb_notice("type: ".$featuretype_metadataUrl[$i_mdu]->type);
+						$featuretype_metadataUrl[$i_mdu]->format = $metadataURL->attributes()->format;
+						$e = new mb_notice("format: ".$featuretype_metadataUrl[$i_mdu]->format);
+						$i_mdu++;
+					}
+					//<ows:WGS84BoundingBox dimensions="2"><ows:LowerCorner>-9.16611817848171e+15 -3.4016616708962e+32</ows:LowerCorner><ows:UpperCorner>464605646503609 3.4016616708962e+32</ows:UpperCorner></ows:WGS84BoundingBox>
+					$lowerCorner = $wfs20Cap->xpath('/wfs:WFS_Capabilities/wfs:FeatureTypeList/wfs:FeatureType['.$i.']/ows:WGS84BoundingBox/ows:LowerCorner');
+					$lowerCorner = $lowerCorner[0];
+					$lowerCorner = explode(" ",$lowerCorner);
+
+					$upperCorner = $wfs20Cap->xpath('/wfs:WFS_Capabilities/wfs:FeatureTypeList/wfs:FeatureType['.$i.']/ows:WGS84BoundingBox/ows:UpperCorner');
+					$upperCorner = $upperCorner[0];	
+					$upperCorner = explode(" ",$upperCorner);
+					
+					$featuretype_latlon_minx = $lowerCorner[0];
+					$featuretype_latlon_miny = $lowerCorner[1];
+					$featuretype_latlon_maxx = $upperCorner[0];
+					$featuretype_latlon_maxy = $upperCorner[1];
+
+					try {
+						$currentFeatureType = $this->createFeatureTypeFromUrlGet($myWfs, $featuretype_name, $featureTypeNsArray);
+						if ($currentFeatureType !== null) {
+							$currentFeatureType->name = $featuretype_name;
+							$currentFeatureType->title = $featuretype_title;
+							$currentFeatureType->summary = $featuretype_abstract;
+							$currentFeatureType->srs = $featuretype_srs;
+							$currentFeatureType->latLonBboxArray['minx'] = $featuretype_latlon_minx;
+							$currentFeatureType->latLonBboxArray['miny'] = $featuretype_latlon_miny;
+							$currentFeatureType->latLonBboxArray['maxx'] = $featuretype_latlon_maxx;
+							$currentFeatureType->latLonBboxArray['maxy'] = $featuretype_latlon_maxy;
+							$currentFeatureType->crsArray = $featuretype_crsArray;
+							$currentFeatureType->metadataUrlArray = $featuretype_metadataUrl;
+							$myWfs->addFeatureType($currentFeatureType);
+						}
+					}
+					catch (Exception $e) {
+						$e = new mb_exception("Failed to load featuretype " . $featuretype_name);
+					}
+					$i++;
+
+				}
+				
+				//get list of wfs operations
+				
+				$capOperations = $wfs20Cap->xpath('/wfs:WFS_Capabilities/ows:OperationsMetadata/ows:Operation');
+				$wfsOperations = array();
+				$listStoredQueriesUrl = "";
+				$describeStoredQueriesUrl = "";
+				$k = 1; //cause index of xml objects begin with 1
+				foreach ($capOperations as $operation) {
+					//debug
+					#$e = new mb_notice("wfs operation: ".$operation->asXML());
+					
+					$opName = $operation->xpath('@name');
+					$wfsOperations[$k]->name = html_entity_decode($opName[0]->name);
+					
+					$httpGet = $operation->xpath('ows:DCP/ows:HTTP/ows:Get/@xlinkhref');
+					$wfsOperations[$k]->httpGet = html_entity_decode($httpGet[0]->xlinkhref);
+					
+					$httpPost = $operation->xpath('ows:DCP/ows:HTTP/ows:Post/@xlinkhref');
+					$wfsOperations[$k]->httpPost = html_entity_decode($httpPost[0]->xlinkhref);
+					
+					//get url for ListStoredQueries request to go further on with createStoredQueryListFromUrlGet
+					if($wfsOperations[$k]->name == "ListStoredQueries") {
+						$listStoredQueriesUrl = $wfsOperations[$k]->httpGet;
+					}
+					//get url for DescribeStoredQueries request to go further on with createStoredQueryListFromUrlGet
+					if($wfsOperations[$k]->name == "DescribeStoredQueries") {
+						$describeStoredQueriesUrl = $wfsOperations[$k]->httpGet;
+					}
+					
+					$k++;
+				}
+				$myWfs->operationsArray = $wfsOperations;
+				
+				//check for StoredQueries
+				try {
+					$myWfs->storedQueriesArray = $this->createStoredQueryFromUrlGet($myWfs, $listStoredQueriesUrl, $describeStoredQueriesUrl);
+					#if (count($storedQueries) > 0) {
+					#	$myWfs->storedQueriesArray = $storedQueries;
+						
+						
+					#}
+				}
+				catch (Exception $e) {
+					$e = new mb_exception("Failed to load StoredQueries.");
+				}
+			}
+			
+			if (!$myWfs->title) {
+				$myWfs->title = "Untitled";
+			}
+			return $myWfs;
+		}
+		catch (Exception $e) {
+			$e = new mb_exception($e);
+			return null;
+		}
+	}
+
+	public function createFromDb ($id) {
+		$myWfs = new Wfs_2_0();
+		return parent::createFromDb($id, $myWfs);
+	}
+}
+?>

Modified: trunk/mapbender/http/classes/class_wfs_conf.php
===================================================================
--- trunk/mapbender/http/classes/class_wfs_conf.php	2013-06-03 08:28:31 UTC (rev 8641)
+++ trunk/mapbender/http/classes/class_wfs_conf.php	2013-06-03 08:56:00 UTC (rev 8642)
@@ -180,12 +180,58 @@
 		if($row = db_fetch_array($res)){
 			$currentRow["featuretype_name"] = $row["featuretype_name"];
 			$currentRow["featuretype_srs"] = $row["featuretype_srs"];
+			
+			//get OtherSRS if available
+			$sqlEpsg = "SELECT * FROM wfs_featuretype_epsg";
+			$sqlEpsg .= " WHERE fkey_featuretype_id = $1";
+			$vEpsg = array($featuretypeId);
+			$tEpsg = array('i');
+			$res = db_prep_query($sqlEpsg,$vEpsg,$tEpsg);
+			$currentRow["featuretype_other_srs"] = array();
+			$cnt = 0;
+			while($rowEpsg = db_fetch_array($res)){
+				$currentRow["featuretype_other_srs"][$cnt]['epsg'] = $rowEpsg['epsg'];
+				$cnt++;
+			}
 		}
 	
 		return $currentRow;
 	}
 	
 	/**
+	 * Gets the database content of a WFS stored query element given by a WFS conf ID.
+	 *
+	 * @return Array
+	 * @param $id Integer the WFS conf ID.
+	 * @param $storedQueryId String the storedQuery ID.
+	 */
+	private static function getWfsStoredQueryParamsFromDb ($id, $storedQueryId) {
+		$sql = <<<SQL
+SELECT * FROM wfs_stored_query_params
+WHERE fkey_wfs_conf_id = $1 AND stored_query_id = $2
+ORDER BY query_param_id
+SQL;
+		$v = array($id, $storedQueryId);
+		$t = array('i', 's');
+		$res = db_prep_query($sql, $v, $t);
+		
+		$storedQueryElementArray = array();
+		
+		while ($row = db_fetch_array($res)) {
+			$currentElement = array(
+					"id" => $row["query_param_id"],
+					"name" => $row["query_param_name"],
+					"type" => $row["query_param_type"],
+					"wfsConfId" => $row["fkey_wfs_conf_id"],
+					"storedQueryId" => $row["stored_query_id"]
+			);
+			array_push($storedQueryElementArray, $currentElement);
+		}
+	
+		return $storedQueryElementArray;
+	}
+	
+	/**
 	 * get WFS conf data from database
 	 */
 	public function getWfsConfFromDB ($idArray) {
@@ -215,7 +261,9 @@
 									"wfs_transaction" => $rowArray[$i]["wfs_transaction"],
 									"wfs_conf_id" => $rowArray[$i]["wfs_conf_id"],
 									"wfs_conf_type" => $rowArray[$i]["wfs_conf_type"],
-									"element" => $elementArray
+									"element" => $elementArray,
+									"stored_query_id" => $rowArray[$i]["stored_query_id"],
+									"storedQueryElement" => $storedQueryElementArray,
 									);
 
 				// get WFS conf element data of current WFS conf
@@ -226,6 +274,12 @@
 				$wfsId = $rowArray[$i]["fkey_wfs_id"];
 				$featuretypeId = $rowArray[$i]["fkey_featuretype_id"];
 				$currentRow = array_merge($currentRow , self::getWfsFeatureTypeFromDb($wfsId, $featuretypeId));
+				
+				// get WFS stored query data of current WFS conf if exists
+				$storedQueryId = $rowArray[$i]["stored_query_id"];
+				if($storedQueryId && $storedQueryId != "") {
+					$currentRow['storedQueryElement'] = self::getWfsStoredQueryParamsFromDb($id, $storedQueryId);
+				}
 
 				$this->confArray[$id] = $currentRow;
 			}
@@ -267,7 +321,7 @@
 		$con = db_connect($DBSERVER,$OWNER,$PW);
 		db_select_db($DB,$con);
 		if($userid){
-		 	$sql = "SELECT * FROM wfs WHERE wfs_owner = $1";
+		 	$sql = "SELECT * FROM wfs WHERE wfs_owner = $1 ORDER BY wfs_id";
 			$v = array($userid);
 			$t = array('i');
 			$res = db_prep_query($sql,$v,$t);

Modified: trunk/mapbender/http/classes/class_wfs_configuration.php
===================================================================
--- trunk/mapbender/http/classes/class_wfs_configuration.php	2013-06-03 08:28:31 UTC (rev 8641)
+++ trunk/mapbender/http/classes/class_wfs_configuration.php	2013-06-03 08:56:00 UTC (rev 8642)
@@ -166,6 +166,7 @@
 	var $buffer;
 	var $resStyle;
 	var $elementArray = array();
+	var $storedQueryElementArray = array();
 
 	function __construct () {
 	}
@@ -421,6 +422,7 @@
 		$wfsConf->wfsId = intval($row["fkey_wfs_id"]);
 		$wfsConf->type = intval($row["wfs_conf_type"]);
 		$wfsConf->featureTypeId = intval($row["fkey_featuretype_id"]);
+		$wfsConf->storedQueryId = $row["stored_query_id"];
 
 		$sql = <<<SQL
 SELECT featuretype_name FROM wfs_featuretype WHERE featuretype_id = $1 LIMIT 1
@@ -473,9 +475,56 @@
 
 			$wfsConf->elementArray[]= $element;
 		}
+		
+		
+		//if this wfs conf is a stored query, add stored query information
+		if($wfsConf->storedQueryId && $wfsConf->storedQueryId != "") {
+			$sql = <<<SQL
+SELECT * FROM wfs_stored_query_params 
+WHERE fkey_wfs_conf_id = $1 AND stored_query_id = $2
+ORDER BY query_param_id
+SQL;
+			$v = array($wfsConf->id, $wfsConf->storedQueryId);
+			$t = array('i', 's');
+			$res = db_prep_query($sql, $v, $t);
+			while ($row = db_fetch_array($res)) {
+				$storedQueryElement = new StoredQueryElement();
+				
+				$storedQueryElement->id = intval($row["query_param_id"]);
+				$storedQueryElement->name = $row["query_param_name"];
+				$storedQueryElement->type = $row["query_param_type"];
+				$storedQueryElement->wfsConfId = $row["fkey_wfs_conf_id"];
+				$storedQueryElement->storedQueryId = $row["stored_query_id"];
+			
+				$wfsConf->storedQueryElementArray[]= $storedQueryElement;
+			}
+		}
 
 		$wfsConf->id = intval($id);
 		return $wfsConf;
 	}
 }
+
+// ----------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
+// ----------------------------------------------------------------------------
+
+
+/**
+ * The configuration of a WFS stored query element.
+ */
+class StoredQueryElement {
+
+	var $id;
+	var $name;
+	var $type;
+	var $wfsConfId;
+	var $storedQueryId;
+	
+	function __construct () {
+	}
+}
 ?>

Added: trunk/mapbender/http/classes/class_xml_parser.php
===================================================================
--- trunk/mapbender/http/classes/class_xml_parser.php	                        (rev 0)
+++ trunk/mapbender/http/classes/class_xml_parser.php	2013-06-03 08:56:00 UTC (rev 8642)
@@ -0,0 +1,247 @@
+<?php
+
+
+/**
+ * Parsing XML documents.
+ * @author A.R.Pour
+ * @version 0.1
+ */
+
+class XMLParser {
+    private static $xp;
+    private static $doc;
+    private static $schema = array();
+    private static $removeEmptyValues = true;
+    
+    /**
+     * Returns the version of the class.
+     * 
+     * @return float
+     */
+    public static function getVersion() {
+        return 0.1;
+    }
+       
+    public static function loadXMLFromFile($filename) {
+        if(file_exists($filename) and is_readable($filename)) {
+            return self::loadXMLFromString(
+                file_get_contents($filename)
+            );
+        }
+        return false;
+    }
+    
+    public static function loadXMLFromString($string) {
+        self::$doc = new \DOMDocument();
+
+        if( !@self::$doc->loadXML($string) || 
+            !@self::$xp = new \DOMXPath(self::$doc)) {
+            return false;
+        }
+
+        return true;
+    }
+    
+
+    public static function loadJsonSchemaFromString($string) {
+        $array = self::objectToArray(
+            json_decode($string)
+        );
+        
+        if(is_array($array) AND !empty($array)) {
+            self::$schema = json_decode(json_encode(
+                self::merge_recursive(self::objectToArray(self::$schema), $array)
+            ));
+            return true;
+        }
+
+        return false;
+    }
+
+
+    public static function loadJsonSchema($filename) {
+        if(file_exists($filename) and is_readable($filename)) {            
+            $array = self::objectToArray(
+                json_decode(file_get_contents($filename))
+            );
+            
+            if(is_array($array) AND !empty($array)) {
+                self::$schema = json_decode(json_encode(
+                    self::merge_recursive(self::objectToArray(self::$schema), $array)
+                ));
+                return true;
+            }
+        }
+
+        return false;
+    }
+    
+    public static function registerNamespaces($namespaces) {
+        if(!empty($namespaces) and is_object(self::$xp) and get_class(self::$xp) === "DOMXPath") {
+            foreach($namespaces AS $namespaceKey => $namespaceValue) {
+                self::$xp->registerNamespace($namespaceKey,$namespaceValue);
+            }
+            return true;
+        }
+        return false;
+    }
+
+    public static function parse() {
+        if(isset(self::$schema->cmd)) {
+            self::parseCommands(self::$schema->cmd);
+        }        
+        return self::parseRecursive(self::$schema);
+    }
+    
+    private static function objectToArray($object) {
+        $array = array();
+        $object = (array)$object;
+        
+        if(!empty($object)) {
+            foreach($object as $key => $val) {
+                $array[$key] = (is_array($val) || is_object($val)) ? self::objectToArray($val) : $val;
+            }
+        }
+        return $array;
+    }
+    
+    private static function parseRecursive($object, $name = "", $context = null, $path = "", $recursive = false, $asArray = false) {
+        $result = array();
+
+        foreach($object as $key => $val) {
+            switch($key) {
+                case "cmd" : 
+                    continue;
+                case "path" : 
+                    $path .= $val;
+                    continue;
+                case "asArray" : 
+                    $asArray = $val;
+                    continue;
+                case "recursive":
+                    $recursive = true;
+                    continue;
+                case "data" :
+                    $result = self::parseData($val, $name, $path, $context, $recursive, $asArray);
+                    continue;
+                default :
+                    if(is_object($val)) {
+                        $tmp = self::parseRecursive($val, $key, $context, $path, $recursive);
+                    } else if(is_array($val) && count($val) >= 2) {
+                        $tmp = self::getValue($path.$val[0], $context);
+                        
+                        switch($val[1]) {
+                            case "commaSeparated"  : 
+                                if(is_array($tmp)) {
+                                    $tmp = implode(", ", $tmp); 
+                                }
+                                break;
+                            case "raw" :
+                               	$nodes = self::$xp->query($val[0], $context);
+                               	if($nodes->length > 0) {
+                               		$tmp = $context->ownerDocument->saveXML($nodes->item(0));
+                               	}
+                               	break;
+                        }
+                        
+                    } else {
+                        $tmp = self::getValue($path.$val, $context); 
+                    }
+                    
+                    if(self::$removeEmptyValues && ($tmp === "" || $tmp === array())) {
+                        continue;
+                    }
+                    
+                    $result[$key] = $tmp;
+            }
+        }
+        
+        return $result;
+    }
+    
+    private static function parseData($data, $name, $path, $context, $recursive, $asArray = false) {
+        if(!is_object($data)) return array();
+        $tmp = array();
+        
+        if($context == null) {
+            $nodes = self::$xp->query($path);
+        } else {
+            $nodes = self::$xp->query($path, $context);
+        }
+        
+        if($nodes) {
+            foreach($nodes as $node) {
+                $dataRecTmp = array();
+                
+                if($recursive) {
+                    $dataRecTmp = self::parseData($data, $name, $path, $node, $recursive);
+                }
+                
+                $dataTmp = self::parseRecursive($data, $name, $node);
+                
+                $tmp[] = empty($dataRecTmp) ? $dataTmp : array_merge(
+                    $dataTmp,
+                    array($name => $dataRecTmp)
+                );
+            }
+        }
+
+        return $asArray ? $tmp : self::getCleanArray($tmp);
+
+    }
+    
+    private static function parseCommands($commands) {
+        foreach($commands as $key => $val) {
+            switch($key) {
+                case "addNamespaces" :
+                    self::registerNamespaces($val);
+                    break;
+                case "removeEmptyValues" :
+                    if($val) self::$removeEmptyValues = true;
+                    else self::$removeEmptyValues = false;
+                    break;
+            }
+        }
+    }
+    
+    private static function getValue($xpath, $context = null) {
+        $result = array();
+        $nodes = self::$xp->query($xpath, $context);
+        
+        if($nodes) {
+            foreach($nodes as $node) {
+                switch($node->nodeType) {
+                    case XML_ATTRIBUTE_NODE:
+                        $result[] = $node->value;
+                        break;
+                    case XML_TEXT_NODE:
+                        $result[] = $node->wholeText;
+                        break;
+                    default:
+                }
+            }
+        }
+
+        return self::getCleanArray($result);
+    }
+    
+    private static function getCleanArray($array) {
+        if(count($array) === 1) {
+            return $array[0];
+        }
+        
+        return $array;
+    }
+    
+    
+    private static function merge_recursive( $arr1, $arr2 ) {
+        foreach( array_keys( $arr2 ) as $key ) {
+            if( isset( $arr1[$key] ) && is_array( $arr1[$key] ) && is_array( $arr2[$key] ) ) {
+                $arr1[$key] = self::merge_recursive( $arr1[$key], $arr2[$key] );
+            } else {
+                $arr1[$key] = $arr2[$key];
+            }
+        }
+        return $arr1;
+    }
+}
\ No newline at end of file



More information about the Mapbender_commits mailing list