[Mapbender-commits] r3586 - in branches/print_dev: http http/classes http/css http/extensions http/img http/include http/javascripts http/php lib resources/db/update

svn_mapbender at osgeo.org svn_mapbender at osgeo.org
Tue Feb 24 11:28:59 EST 2009


Author: mschulz
Date: 2009-02-24 11:28:58 -0500 (Tue, 24 Feb 2009)
New Revision: 3586

Added:
   branches/print_dev/http/classes/class_gml_geometry.php
   branches/print_dev/http/classes/class_wfs_configuration.php
   branches/print_dev/http/css/tablesorter.css
   branches/print_dev/http/extensions/jquery.tablesorter.js
   branches/print_dev/http/img/admin.png
   branches/print_dev/http/include/template_splash.php
Modified:
   branches/print_dev/http/classes/class_connector.php
   branches/print_dev/http/classes/class_element.php
   branches/print_dev/http/classes/class_gml.php
   branches/print_dev/http/classes/class_gml_2.php
   branches/print_dev/http/classes/class_gml_2_factory.php
   branches/print_dev/http/classes/class_gml_3.php
   branches/print_dev/http/classes/class_gml_3_factory.php
   branches/print_dev/http/classes/class_gml_factory.php
   branches/print_dev/http/classes/class_gml_line.php
   branches/print_dev/http/classes/class_gml_multiline.php
   branches/print_dev/http/classes/class_gml_multipolygon.php
   branches/print_dev/http/classes/class_gml_point.php
   branches/print_dev/http/classes/class_gml_polygon.php
   branches/print_dev/http/classes/class_ows.php
   branches/print_dev/http/classes/class_universal_gml_factory.php
   branches/print_dev/http/classes/class_wfs.php
   branches/print_dev/http/extensions/geom2wfst.php
   branches/print_dev/http/index.php
   branches/print_dev/http/javascripts/geometry.js
   branches/print_dev/http/php/mod_wfs_conf.php
   branches/print_dev/http/php/mod_wfs_edit.php
   branches/print_dev/lib/exception.js
   branches/print_dev/resources/db/update/update_2.6.sql
Log:
merged from trunk

Modified: branches/print_dev/http/classes/class_connector.php
===================================================================
--- branches/print_dev/http/classes/class_connector.php	2009-02-24 11:45:18 UTC (rev 3585)
+++ branches/print_dev/http/classes/class_connector.php	2009-02-24 16:28:58 UTC (rev 3586)
@@ -214,7 +214,8 @@
 		    $xmlstr = false;
 		    while (!feof($fp)) {
 		    	$content = fgets($fp,4096);
-		    	if( strpos($content, '<?xml') === 0){
+//		    	if( strpos($content, '<?xml') === 0){
+		    	if( strpos($content, '<') === 0){
 		    		$xmlstr = true;
 		    	}
 		    	if($xmlstr == true){

Modified: branches/print_dev/http/classes/class_element.php
===================================================================
--- branches/print_dev/http/classes/class_element.php	2009-02-24 11:45:18 UTC (rev 3585)
+++ branches/print_dev/http/classes/class_element.php	2009-02-24 16:28:58 UTC (rev 3586)
@@ -202,14 +202,13 @@
 						$splashScreen .= ob_get_contents();
 						ob_end_clean();
 					}
-				}
-				else {
-					$splashScreen .= "<img src='../img/indicator_wheel.gif'>&nbsp;" . 
-						"<b>Ma<font color='#0000CE'>p</font><font color='#C00000'>b</font>ender " . 
-						MB_VERSION_NUMBER . " " . strtolower(MB_VERSION_APPENDIX) . "</b>..." .
-						"loading application '" . $this->guiId . "'";
-				}
-	
+					else {
+						$splashScreen .= "<img src='../img/indicator_wheel.gif'>&nbsp;" . 
+							"<b>Ma<font color='#0000CE'>p</font><font color='#C00000'>b</font>ender " . 
+							MB_VERSION_NUMBER . " " . strtolower(MB_VERSION_APPENDIX) . "</b>..." .
+							"loading application '" . $this->guiId . "'";
+					}
+				}	
 				$openTag .= "<div id='loading_mapbender' " .
 								"style='margin:0px;padding:0px;width:100%;height:100%;'>" . 
 								$splashScreen . "</div>" . 

Modified: branches/print_dev/http/classes/class_gml.php
===================================================================
--- branches/print_dev/http/classes/class_gml.php	2009-02-24 11:45:18 UTC (rev 3585)
+++ branches/print_dev/http/classes/class_gml.php	2009-02-24 16:28:58 UTC (rev 3586)
@@ -22,17 +22,31 @@
 require_once(dirname(__FILE__)."/../classes/class_json.php");
 require_once(dirname(__FILE__)."/../classes/class_gml_feature_collection.php");
 
-class Gml {
+abstract class Gml {
 	var $featureCollection = null;
 	var $geomFeaturetypeElement;
 	var $doc;
 	
+	abstract public function toGml ();
+	
 	public function toGeoJSON () {
 		if ($this->featureCollection === null) {
 			return null;
 		}
 		return $this->featureCollection->toGeoJSON();
 	}	
+	
+	/**
+	 * Shortcut for GeoJSON conversion
+	 * 
+	 * @return String
+	 * @param $geoJson String
+	 */
+	public static function geoJsonToGml ($geoJson) {
+		$gmlFactory = new UniversalGmlFactory();
+		$myGmlObj = $gmlFactory->createFromGeoJson($geoJson);
+		return $myGmlObj->toGml();
+	}
 }
 
 ?>
\ No newline at end of file

Modified: branches/print_dev/http/classes/class_gml_2.php
===================================================================
--- branches/print_dev/http/classes/class_gml_2.php	2009-02-24 11:45:18 UTC (rev 3585)
+++ branches/print_dev/http/classes/class_gml_2.php	2009-02-24 16:28:58 UTC (rev 3586)
@@ -23,5 +23,18 @@
 require_once(dirname(__FILE__)."/../classes/class_gml.php");
 
 class Gml_2 extends Gml {
+	public function toGml () {
+		
+		$str = "";
+		foreach ($this->featureCollection->featureArray as $feature) {
+			if (!$feature->geometry) {
+				$e = new mb_exception("Feature doesn't have a geometry.");
+				return null;
+			}
+			$geometry = $feature->geometry;
+			$str .= $geometry->toGml2();
+		}
+		return $str;
+	}
 }
 ?>
\ No newline at end of file

Modified: branches/print_dev/http/classes/class_gml_2_factory.php
===================================================================
--- branches/print_dev/http/classes/class_gml_2_factory.php	2009-02-24 11:45:18 UTC (rev 3585)
+++ branches/print_dev/http/classes/class_gml_2_factory.php	2009-02-24 16:28:58 UTC (rev 3586)
@@ -30,6 +30,18 @@
  */
 class Gml_2_Factory extends GmlFactory {
 
+	/**
+	 * Creates a GML object from a GeoJSON (http://www.geojson.org) String
+	 * 
+	 * @return Gml_3
+	 * @param $geoJson String
+	 */
+	public function createFromGeoJson ($geoJson) {
+		$gml2 = new Gml_2();
+		
+		return parent::createFromGeoJson($geoJson, $gml2);
+	}
+
 	function findNameSpace($s){
 		list($ns,$FeaturePropertyName) = split(":",$s);
 		$nodeName = array('ns' => $ns, 'value' => $FeaturePropertyName);

Modified: branches/print_dev/http/classes/class_gml_3.php
===================================================================
--- branches/print_dev/http/classes/class_gml_3.php	2009-02-24 11:45:18 UTC (rev 3585)
+++ branches/print_dev/http/classes/class_gml_3.php	2009-02-24 16:28:58 UTC (rev 3586)
@@ -23,5 +23,10 @@
 require_once(dirname(__FILE__)."/../classes/class_gml.php");
 
 class Gml_3 extends Gml {
+
+	public function toGml () {
+		
+	}
+
 }
 ?>
\ No newline at end of file

Modified: branches/print_dev/http/classes/class_gml_3_factory.php
===================================================================
--- branches/print_dev/http/classes/class_gml_3_factory.php	2009-02-24 11:45:18 UTC (rev 3585)
+++ branches/print_dev/http/classes/class_gml_3_factory.php	2009-02-24 16:28:58 UTC (rev 3586)
@@ -31,6 +31,18 @@
 class Gml_3_Factory extends GmlFactory {
 
 	/**
+	 * Creates a GML object from a GeoJSON (http://www.geojson.org) String
+	 * 
+	 * @return Gml_3
+	 * @param $geoJson String
+	 */
+	public function createFromGeoJson ($geoJson) {
+		$gml3 = new Gml_3();
+		
+		return parent::createFromGeoJson($geoJson, $gml3);
+	}
+
+	/**
 	 * Creates GML 3 objects from GML documents.
 	 * 
 	 * @return Gml_3

Modified: branches/print_dev/http/classes/class_gml_factory.php
===================================================================
--- branches/print_dev/http/classes/class_gml_factory.php	2009-02-24 11:45:18 UTC (rev 3585)
+++ branches/print_dev/http/classes/class_gml_factory.php	2009-02-24 16:28:58 UTC (rev 3586)
@@ -20,6 +20,7 @@
 require_once(dirname(__FILE__)."/../../core/globalSettings.php");
 require_once(dirname(__FILE__)."/../classes/class_connector.php");
 require_once(dirname(__FILE__)."/../classes/class_administration.php");
+require_once(dirname(__FILE__)."/../classes/class_json.php");
 
 /**
  * Creates GML objects from GML documents.
@@ -33,6 +34,142 @@
 	}
 	
 	/**
+	 * Creates a GML object from a GeoJSON (http://www.geojson.org) String
+	 * 
+	 * @return Gml
+	 * @param $geoJson String
+	 */
+	public function createFromGeoJson ($geoJson, $gml) {
+		$json = new Mapbender_JSON ();
+		$jsonObj = $json->decode($geoJson);
+
+		// check if valid feature collection
+		new mb_exception("Is Array? " . is_array($jsonObj->features));
+		new mb_exception("Type? " . strtoupper($jsonObj->type));
+		if (strtoupper($jsonObj->type) != "FEATURECOLLECTION" || !is_array($jsonObj->features)) {
+			$e = new mb_exception("Not a valid GeoJSON Feature Collection.");
+			return null;
+		}
+
+		$gml->featureCollection = new FeatureCollection();
+		foreach ($jsonObj->features as $currentFeature) {
+			$feature = new Feature();
+			if (!is_object($currentFeature->crs) || $currentFeature->crs->type !== "name") {
+				$e = new mb_exception("Feature doesn't have a SRS.");
+				return null;
+			}
+			$srs = $currentFeature->crs->properties->name;
+
+			// set geometry
+			if (is_object($currentFeature->geometry)) {
+				$currentGeometry = $currentFeature->geometry;
+				switch (strtoupper($currentGeometry->type)) {
+					case "POLYGON":
+						$geometry = new GMLPolygon();
+						for ($i = 0; $i < count($currentGeometry->coordinates); $i++) {
+							$currentRing = $currentGeometry->coordinates[$i];
+							
+							foreach ($currentRing as $coords) {
+								list($x, $y) = $coords;
+	
+								// exterior ring							
+								if (0 == $i) {
+									$geometry->addPoint($x, $y);
+								}
+								// interior ring
+								else {
+									$geometry->addPointToRing($i, $x, $y);
+								}
+							}
+						}
+						break;
+					case "POINT":
+						$geometry = new GMLPoint();
+						list($x, $y) = $currentGeometry->coordinates;
+						$geometry->setPoint($x, $y);
+						break;
+					case "LINESTRING":
+						$geometry = new GMLLine();
+						for ($i = 0; $i < count($currentGeometry->coordinates); $i++) {
+							$currentLinePoint = $currentGeometry->coordinates[$i];
+							list($x, $y) = $currentLinePoint;
+							$geometry->addPoint($x, $y);
+						}
+						break;
+					case "MULTIPOLYGON":
+						$geometry = new GMLMultiPolygon();
+						for ($i = 0; $i < count($currentGeometry->coordinates); $i++) {
+							$currentPolygon = $currentGeometry->coordinates[$i];
+								
+							for ($j = 0; $j < count($currentPolygon); $j++) {
+								$currentRing = $currentPolygon[$j];
+								
+								foreach ($currentRing as $coords) {
+									list($x, $y) = $coords;
+		
+									// exterior ring							
+									if (0 == $j) {
+										$geometry->addPoint($x, $y, $i);
+									}
+									// interior ring
+									else {
+										$geometry->addPointToRing($i, $j-1, $x, $y);
+									}
+								}
+							}
+						}
+						break;
+					case "MULTIPOINT":
+						$e = new mb_exception($currentGeometry->type . " are not supported!");
+						return null;
+						break;
+					case "MULTILINESTRING": // not tested!
+						$geometry = new GMLMultiLine();
+						for ($i = 0; $i < count($currentGeometry->coordinates); $i++) {
+							$currentLine = $currentGeometry->coordinates[$i];
+							foreach ($currentLine as $currentLinePoint) {
+								list($x, $y) = $currentLinePoint;
+								$geometry->addPoint($x, $y, $i);
+							}
+						}
+						break;
+					case "GEOMETRYCOLLECTION":
+						$e = new mb_exception($currentGeometry->type . " are not supported!");
+						return null;
+						break;
+					default:
+						$e = new mb_exception($currentGeometry->type . " is not a valid geometry type");
+						return null;
+						break;
+				}
+				// add the geometry to the feature
+				$geometry->srs = $srs;
+				$feature->geometry = $geometry;
+			}
+			else {
+				$e = new mb_exception("This feature does not have a geometry.");
+				return null;
+			}
+			
+
+			// set fid and properties
+			if (is_object($currentFeature->properties)) {
+				foreach ($currentFeature->properties as $pName => $pValue) {
+					if ("fid" == $pName) {
+						$feature->fid = $pValue;
+					}
+					else {
+						$feature->properties[$pName] = $pValue;
+					}
+				}
+			}
+
+			$gml->featureCollection->addFeature($feature);
+		}
+		return $gml;
+	}
+
+	/**
 	 * Creates GML objects from GML documents.
 	 * 
 	 * @return Gml

Added: branches/print_dev/http/classes/class_gml_geometry.php
===================================================================
--- branches/print_dev/http/classes/class_gml_geometry.php	                        (rev 0)
+++ branches/print_dev/http/classes/class_gml_geometry.php	2009-02-24 16:28:58 UTC (rev 3586)
@@ -0,0 +1,35 @@
+<?php
+# $Id: class_gml2.php 3099 2008-10-02 15:29:23Z nimix $
+# http://www.mapbender.org/index.php/class_gml2.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_connector.php");
+require_once(dirname(__FILE__)."/../classes/class_json.php");
+require_once(dirname(__FILE__)."/../classes/class_gml_feature_collection.php");
+
+abstract class GmlGeometry {
+
+	abstract public function toGml2 ();
+
+	abstract public function toGml3 ();
+	
+	abstract public function toGeoJSON ();
+	
+	public $srs;
+}
+?>
\ No newline at end of file

Modified: branches/print_dev/http/classes/class_gml_line.php
===================================================================
--- branches/print_dev/http/classes/class_gml_line.php	2009-02-24 11:45:18 UTC (rev 3585)
+++ branches/print_dev/http/classes/class_gml_line.php	2009-02-24 16:28:58 UTC (rev 3586)
@@ -19,9 +19,10 @@
 
 require_once(dirname(__FILE__)."/../../core/globalSettings.php");
 require_once(dirname(__FILE__)."/../classes/class_json.php");
+require_once(dirname(__FILE__)."/../classes/class_gml_geometry.php");
 
 
-class GMLLine {
+class GMLLine extends GmlGeometry {
 
 	var $pointArray = array();
 
@@ -33,6 +34,25 @@
 		array_push($this->pointArray, array("x" => $x, "y" => $y));
 	}
 	
+	public function toGml2 () {
+		$str = "<gml:MultiLineString srsName=\"$this->srs\">" . 
+			"<gml:lineStringMember><gml:LineString><gml:coordinates>";
+
+		$ptArray = array();
+		foreach ($this->pointArray as $point) {
+			$ptArray[] = $point["x"] . "," . $point["y"];
+		}
+		$str .= implode(" ", $ptArray);
+
+		$str .= "</gml:coordinates></gml:LineString></gml:lineStringMember>";
+		$str .= "</gml:MultiLineString>";		
+		return $str;
+	}
+	
+	public function toGml3 () {
+		
+	}
+
 	public function toGeoJSON () {
 		$numberOfPoints = count($this->pointArray);
 		$str = "";

Modified: branches/print_dev/http/classes/class_gml_multiline.php
===================================================================
--- branches/print_dev/http/classes/class_gml_multiline.php	2009-02-24 11:45:18 UTC (rev 3585)
+++ branches/print_dev/http/classes/class_gml_multiline.php	2009-02-24 16:28:58 UTC (rev 3586)
@@ -19,9 +19,10 @@
 
 require_once(dirname(__FILE__)."/../../core/globalSettings.php");
 require_once(dirname(__FILE__)."/../classes/class_json.php");
+require_once(dirname(__FILE__)."/../classes/class_gml_geometry.php");
 
 
-class GMLMultiLine {
+class GMLMultiLine extends GmlGeometry {
 
 	var $lineArray = array();
 
@@ -33,6 +34,25 @@
 		array_push($this->lineArray[$i], array("x" => $x, "y" => $y));
 	}
 	
+	public function toGml2 () {
+		$str = "<gml:MultiLineString srsName='$srsName'>";
+		foreach ($this->lineArray as $line) {
+			$str .=	"<gml:lineStringMember><gml:LineString><gml:coordinates>";
+			$ptArray = array();
+			foreach ($line as $point) {
+				$ptArray[] = $point["x"] . "," . $point["y"];
+			}
+			$str .= implode(" ", $ptArray);
+			$str .= "</gml:coordinates></gml:LineString>";
+		}
+		$str .=	"<gml:lineStringMember><gml:MultiLineString>";
+		return $str;		
+	}
+	
+	public function toGml3 () {
+		
+	}
+
 	public function toGeoJSON () {
 		$numberlineArray = count($this->lineArray);
 		$str = "";

Modified: branches/print_dev/http/classes/class_gml_multipolygon.php
===================================================================
--- branches/print_dev/http/classes/class_gml_multipolygon.php	2009-02-24 11:45:18 UTC (rev 3585)
+++ branches/print_dev/http/classes/class_gml_multipolygon.php	2009-02-24 16:28:58 UTC (rev 3586)
@@ -19,8 +19,9 @@
 
 require_once(dirname(__FILE__)."/../../core/globalSettings.php");
 require_once(dirname(__FILE__)."/../classes/class_json.php");
+require_once(dirname(__FILE__)."/../classes/class_gml_geometry.php");
 
-class GMLMultiPolygon {
+class GMLMultiPolygon extends GmlGeometry {
 
 	var $polygonArray = array();
 	var $innerRingArray = array();
@@ -30,17 +31,65 @@
 	}
 
 	public function addPointToRing ($i, $j, $x, $y) {
-		if (count($this->innerRingArray[$i]) <= $j) {
+		while (count($this->innerRingArray) <= $i) {
+			array_push($this->innerRingArray, array());
+		}
+		while (count($this->innerRingArray[$i]) <= $j) {
 			array_push($this->innerRingArray[$i], array());
 		}
 		array_push($this->innerRingArray[$i][$j], array("x" => $x, "y" => $y));
 	}
 	
 	public function addPoint ($x, $y, $i) {
-
+		while (count($this->polygonArray) <= $i) {
+			array_push($this->polygonArray, array());
+		}
 		array_push($this->polygonArray[$i], array("x" => $x, "y" => $y));
 	}
+
+	public function toGml2 () {
+		$str .= "<gml:MultiPolygon srsName='$srsName'>";
+		for ($i = 0; $i < count($this->polygonArray); $i++) {
+			$str .= "<gml:polygonMember><gml:Polygon>" . 
+				"<gml:outerBoundaryIs><gml:LinearRing><gml:coordinates>";
+
+			$currentExteriorRing = $this->polygonArray[$i];
+			
+			$ptArray = array();
+			for ($j = 0; $j < count($currentExteriorRing); $j++) {
+				$point = $currentExteriorRing[$j];
+				$ptArray[] = $point["x"] . "," . $point["y"];
+			}
+			$str .= implode(" ", $ptArray);
+			$str .= "</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs>";
+			
+			// interior rings exist
+			if (count($this->innerRingArray) > $i && count($this->innerRingArray[$i]) > 0) {
+
+				for ($j = 0; $j < count($this->innerRingArray[$i]); $j++) {
+					$currentInteriorRing = $this->innerRingArray[$i][$j];
+					$str .= "<gml:innerBoundaryIs><gml:LinearRing><gml:coordinates>";
+					$ptArray = array();
+					for ($k = 0; $k < count($currentInteriorRing); $k++) {
+						$point = $currentInteriorRing[$k];
+						$ptArray[] = $point["x"] . "," . $point["y"];
+					}
+					$str .= implode(" ", $ptArray);
+					$str .= "</gml:coordinates></gml:LinearRing></gml:innerBoundaryIs>";
+				}
+
+			}
+			$str .= "</gml:Polygon></gml:polygonMember>";
+		}
+		$str .= "</gml:MultiPolygon>";
+
+		return $str;		
+	}
 	
+	public function toGml3 () {
+		
+	}
+	
 	public function toGeoJSON () {
 		$numberPolygonArray = count($this->polygonArray);
 		$str = "";

Modified: branches/print_dev/http/classes/class_gml_point.php
===================================================================
--- branches/print_dev/http/classes/class_gml_point.php	2009-02-24 11:45:18 UTC (rev 3585)
+++ branches/print_dev/http/classes/class_gml_point.php	2009-02-24 16:28:58 UTC (rev 3586)
@@ -19,8 +19,9 @@
 
 require_once(dirname(__FILE__)."/../../core/globalSettings.php");
 require_once(dirname(__FILE__)."/../classes/class_json.php");
+require_once(dirname(__FILE__)."/../classes/class_gml_geometry.php");
 
-class GMLPoint {
+class GMLPoint extends GmlGeometry {
 
 	var $point;
 
@@ -33,6 +34,17 @@
 		$this->point = array("x" => $x, "y" => $y);
 	}
 	
+	public function toGml2 () {
+		$str = "<gml:Point srsName='$this->srs'><gml:coordinates>";
+		$str .= $this->point["x"] . "," . $this->point["y"];
+		$str .= "</gml:coordinates></gml:Point>";
+		return $str;		
+	}
+	
+	public function toGml3 () {
+		
+	}
+
 	public function toGeoJSON () {
 		$str = "";
 		if ($this->point) {

Modified: branches/print_dev/http/classes/class_gml_polygon.php
===================================================================
--- branches/print_dev/http/classes/class_gml_polygon.php	2009-02-24 11:45:18 UTC (rev 3585)
+++ branches/print_dev/http/classes/class_gml_polygon.php	2009-02-24 16:28:58 UTC (rev 3586)
@@ -19,9 +19,10 @@
 
 require_once(dirname(__FILE__)."/../../core/globalSettings.php");
 require_once(dirname(__FILE__)."/../classes/class_json.php");
+require_once(dirname(__FILE__)."/../classes/class_gml_geometry.php");
 
 
-class GMLPolygon {
+class GMLPolygon extends GmlGeometry {
 
 	var $pointArray = array();
 	var $innerRingArray = array();
@@ -44,6 +45,37 @@
 		array_push($this->innerRingArray[$currentIndex], array("x" => $x, "y" => $y));
 	}
 	
+	public function toGml2 () {
+		$str = "<gml:MultiPolygon srsName=\"$this->srs\">" . 
+			"<gml:polygonMember><gml:Polygon><gml:outerBoundaryIs>" . 
+			"<gml:LinearRing><gml:coordinates>";
+
+		$ptArray = array();
+		foreach ($this->pointArray as $point) {
+			$ptArray[] = $point["x"] . "," . $point["y"];
+		}
+		$str .= implode(" ", $ptArray);
+
+		$str .= '</gml:coordinates></gml:LinearRing></gml:outerBoundaryIs>';
+				
+		foreach ($this->innerRingArray as $ring) {
+			$str .= "<gml:innerBoundaryIs><gml:LinearRing><gml:coordinates>";
+			$ptArray = array();
+			foreach ($ring as $point) {
+				$ptArray[] = $point["x"] . "," . $point["y"];
+			}
+			$str .= implode(" ", $ptArray);
+			
+			$str .= "</gml:coordinates></gml:LinearRing></gml:innerBoundaryIs>";
+		}
+		$str .= "</gml:Polygon></gml:polygonMember></gml:MultiPolygon>";
+		return $str;
+	}
+	
+	public function toGml3 () {
+		
+	}
+	
 	public function toGeoJSON () {
 		$numberOfPoints = count($this->pointArray);
 		$str = "";

Modified: branches/print_dev/http/classes/class_ows.php
===================================================================
--- branches/print_dev/http/classes/class_ows.php	2009-02-24 11:45:18 UTC (rev 3585)
+++ branches/print_dev/http/classes/class_ows.php	2009-02-24 16:28:58 UTC (rev 3586)
@@ -56,7 +56,7 @@
 	 */
 	final protected function getNameSpace($s) {
 		$c = strpos($s, ":"); 
-		if ($c > 0) {
+		if ($c !== false) {
 			return substr($s, 0, $c);
 		}
 		return $s;

Modified: branches/print_dev/http/classes/class_universal_gml_factory.php
===================================================================
--- branches/print_dev/http/classes/class_universal_gml_factory.php	2009-02-24 11:45:18 UTC (rev 3585)
+++ branches/print_dev/http/classes/class_universal_gml_factory.php	2009-02-24 16:28:58 UTC (rev 3586)
@@ -56,6 +56,17 @@
 	}
 
 	/**
+	 * Creates a GML object from a GeoJSON (http://www.geojson.org) String
+	 * 
+	 * @return Gml
+	 * @param $geoJson String
+	 */
+	public function createFromGeoJson ($geoJson) {
+		$gml2Factory = new Gml_2_Factory();
+		return $gml2Factory->createFromGeoJson($geoJson);
+	}
+	
+	/**
 	 * Creates a GML object by parsing its XML representation. 
 	 * 
 	 * The GML version is determined by parsing 

Modified: branches/print_dev/http/classes/class_wfs.php
===================================================================
--- branches/print_dev/http/classes/class_wfs.php	2009-02-24 11:45:18 UTC (rev 3585)
+++ branches/print_dev/http/classes/class_wfs.php	2009-02-24 16:28:58 UTC (rev 3586)
@@ -20,8 +20,10 @@
 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_gml.php");
 require_once(dirname(__FILE__)."/class_ows.php");
 require_once(dirname(__FILE__)."/class_wfsToDb.php");
+require_once(dirname(__FILE__)."/class_wfs_configuration.php");
 
 /**
  * An abstract Web Feature Service (WFS) class, modelling for example
@@ -52,9 +54,20 @@
 				return $ft;
 			}
 		}
+		new mb_exception("This WFS doesn't have a featuretype with name " . $name);
 		return null;
 	}
 	
+	protected function findFeatureTypeById ($id) {
+		foreach ($this->featureTypeArray as $ft) {
+			if ($ft->id == $id) {
+				return $ft;
+			}
+		}
+		new mb_exception("This WFS doesn't have a featuretype with ID " . $id);
+		return null;
+	}
+	
 	protected function getFeatureGet ($featureTypeName, $filter) {
 		$url = $this->getFeature .
 				$this->getConjunctionCharacter($this->getFeature) . 
@@ -72,6 +85,20 @@
 		return $data;
 	}
 	
+	protected function post ($url, $postData) {
+		$connection = new connector();
+		$connection->set("httpType", "post");
+		$connection->set("httpContentType", "xml");
+		$connection->set("httpPostData", $postData);
+		
+		$data = $connection->load($url);
+		if (!$data) {
+			$e = new mb_exception("WFS request returned no result: " . $url . "\n" . $postData);
+			return null;
+		}
+		return $data;
+	}
+	
 	protected function getFeaturePost ($featureTypeName, $filter) {
 		$postData = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" . 
 			"<wfs:GetFeature version=\"" . $this->getVersion() . "\" " . 
@@ -89,18 +116,7 @@
 		$postData .= "typeName=\"" . $featureTypeName . "\"/>" . 
 			"</wfs:GetFeature>";		
 
-		$connection = new connector();
-		$connection->set("httpType", "post");
-		$connection->set("httpContentType", "xml");
-		$connection->set("httpPostData", $postData);
-		
-		$data = $connection->load($this->getFeature);
-		
-		if (!$data) {
-			$e = new mb_exception("WFS request returned no result: " . $url . "\n" . $postData);
-			return null;
-		}
-		return $data;
+		return $this->post($this->getFeature, $postData);
 	}
 	
 	public function getFeature ($featureTypeName, $filter) {
@@ -110,7 +126,194 @@
 		return $this->getFeatureGet($featureTypeName, $filter);
 	}
 	
+	/**
+	 * Performs a WFS transaction (delete, update or insert).
+	 * 
+	 * @return String the WFS reply
+	 * @param $method String "delete", "update" or "insert"
+	 * @param $wfsConf WfsConfiguration
+	 * @param $gmlObj Gml
+	 */
+	public function transaction ($method, $wfsConf, $gmlObj) {
+		
+		//
+		// get feature type and geometry column from WFS configuration
+		//
+		if (!($wfsConf instanceof WfsConfiguration)) {
+			$e = new mb_exception("Invalid WFS configuration.");
+			return null;
+		}
+		$featureType = $this->findFeatureTypeById($wfsConf->featureTypeId);
+		$featureTypeName = $featureType->name;
+		$geomColumnName = $wfsConf->getGeometryColumnName();
+
+		//
+		// GML string
+		//
+		if (!($gmlObj instanceof Gml)) {
+			$e = new mb_exception("Not a GML object.");
+			return null;
+		}
+		$gml = $gmlObj->toGml();
+		if (is_null($gml)) {
+			$e = new mb_exception("GML is not set.");
+			return null;
+		}
+		
+		// I assume that only one feature is contained in the GeoJSON,
+		// so I just take the first from the collection.
+		$feature = $gmlObj->featureCollection->featureArray[0];
+
+
+		switch ($method) {
+			case "delete":
+				$requestData = $this->transactionDelete($feature, $featureTypeName);
+				break;
+			case "update":
+				$requestData = $this->transactionUpdate($feature, $featureTypeName, $gml, $geomColumnName);
+				break;
+			case "insert":
+				$requestData = $this->transactionInsert($feature, $featureTypeName, $gml, $geomColumnName);
+				break;
+			default:
+				$e = new mb_exception("Invalid transaction method: " . $method);
+				return null;
+		}		
+
+		$postData = $this->wrapTransaction($featureType, $requestData);
+		return $this->post($this->transaction, $postData);
+	}
 	
+	protected function transactionInsert ($feature, $featureTypeName, $gml, $geomColumnName) {
+		// add properties
+		$propertiesSegment = "";
+		foreach ($feature->properties as $key => $value) {
+			if (isset($value)) {
+				$propertiesSegment .= "<$key><![CDATA[$value]]></$key>";
+			}
+		}
+
+		// add spatial data
+		$geomSegment = "<$geomColumnName>" . $gml . "</$geomColumnName>";
+
+		return "<wfs:Insert><$featureTypeName>" . $propertiesSegment . 
+					$geomSegment . "</$featureTypeName></wfs:Insert>";
+	}
+	
+	protected function transactionUpdate ($feature, $featureTypeName, $gml, $geomColumnName) {
+		// add properties
+		$propertiesSegment = "";
+		foreach ($feature->properties as $key => $value) {
+			if (isset($value)) {
+				$propertiesSegment .= "<wfs:Property><wfs:Name>$key</wfs:Name>" . 
+					"<wfs:Value><![CDATA[$value]]></wfs:Value></wfs:Property>";
+			}
+		}
+
+		// filter
+		if (!isset($feature->fid)) {
+			$e = new mb_exception("Feature ID not set.");
+			return null;
+		}
+		$filterSegment = "<ogc:Filter><ogc:FeatureId fid=\"$feature->fid\"/></ogc:Filter>";
+
+		// add geometry
+		$geomSegment = "<wfs:Property><wfs:Name>$geomColumnName</wfs:Name>" . 
+			"<wfs:Value>" . $gml . "</wfs:Value></wfs:Property>";
+					
+
+		return "<wfs:Update typeName=\"$featureTypeName\">" . 
+				$propertiesSegment . 
+				$geomSegment . 
+				$filterSegment . 
+				"</wfs:Update>";
+	}
+	
+	protected function transactionDelete ($feature, $featureTypeName) {
+		// filter
+		if (!isset($feature->fid)) {
+			$e = new mb_exception("Feature ID not set.");
+			return null;
+		}
+
+		return "<wfs:Delete typeName=\"$featureTypeName\">" . 
+			"<ogc:Filter><ogc:FeatureId fid=\"$feature->fid\"/></ogc:Filter>" . 
+			"</wfs:Delete>";
+	}
+	
+	protected function wrapTransaction ($featureType, $wfsRequest) {
+		$featureNS = $this->getNameSpace($featureType->name);
+		
+		$str = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" . 
+			"<wfs:Transaction version=\"" . $this->getVersion() . 
+			"\" service=\"WFS\" ";
+
+		$ns_gml = false;
+		$ns_ogc = false;
+		$ns_xsi = false;
+		$ns_wfs = false;
+		$ns_featureNS = false;
+
+		foreach ($featureType->namespaceArray as $namespace) {
+
+			if ($namespace->name == "gml"){
+				 $ns_gml = true;
+				 $str .= "xmlns:" . $namespace->name . 
+				 	"=\"" . $namespace->value . "\" ";
+			} 
+			else if ($namespace->name == "ogc") {
+				$ns_ogc = true;
+				$str .= "xmlns:" . $namespace->name . 
+					"=\"" . $namespace->value . "\" ";
+			} 
+			else if ($namespace->name == "xsi") {
+				$ns_xsi = true;
+				$str .= "xmlns:" . $namespace->name . 
+					"=\"" . $namespace->value . "\" ";
+			} 
+			else if ($namespace->name == "wfs") {
+				$ns_wfs = true;
+				$str .= "xmlns:" . $namespace->name . 
+					"=\"" . $namespace->value . "\" ";
+			} 
+			else if ($namespace->name == $featureNS) {
+				$ns_featureNS = true;
+				$str .= "xmlns:" . $namespace->name .
+					"=\"" . $namespace->value . "\" ";
+				$strForSchemaLocation = $namespace->value;
+			}
+		}
+
+		if (!$ns_gml) {
+			$str .= 'xmlns:gml="http://www.opengis.net/gml" ';	
+		}
+		if (!$ns_ogc) {
+			$str .= 'xmlns:ogc="http://www.opengis.net/ogc" ';	
+		}
+		if (!$ns_xsi) {
+			$str .= 'xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" ';
+		} 
+		if (!ns_featureNS) {
+			$str .= "xmlns:" . $featureNS . "=\"http://www.someserver.com/" . $featureNS . "\" ";	
+		}
+		if (!$ns_wfs) {
+			$str .= "xmlns:wfs=\"http://www.opengis.net/wfs\" ";	
+		}
+
+		$str .= "xsi:schemaLocation=\"http://www.opengis.net/wfs";
+		$str .= " http://schemas.opengis.net/wfs/1.0.0/WFS-transaction.xsd";
+		$str .= " " . $strForSchemaLocation;
+		$str .= " " . $this->describeFeatureType;
+		//$str .= mb_getConjunctionCharacter(myconf['wfs_describefeaturetype']);
+		//$str .= 'typename=' + myconf['featuretype_name'];
+		$str .= "\">";		
+		
+		$str .= $wfsRequest;
+		
+		$str .= "</wfs:Transaction>";
+		return $str;
+	}
+	
 	// -----------------------------------------------------------------------
 	//
 	// Output formats

Added: branches/print_dev/http/classes/class_wfs_configuration.php
===================================================================
--- branches/print_dev/http/classes/class_wfs_configuration.php	                        (rev 0)
+++ branches/print_dev/http/classes/class_wfs_configuration.php	2009-02-24 16:28:58 UTC (rev 3586)
@@ -0,0 +1,170 @@
+<?php
+# $Id: class_wfs_conf.php 3510 2009-02-03 10:36:01Z christoph $
+# http://www.mapbender.org/index.php/class_wfs_conf.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_user.php");
+require_once(dirname(__FILE__)."/../classes/class_administration.php");
+require_once(dirname(__FILE__)."/../classes/class_json.php");
+
+class WfsConfigurationElement {
+	var $name;
+	var $type;
+	var $search;
+	var $styleId;
+	var $toUpper;
+	var $label;
+	var $labelId;
+	var $geom;
+	var $show;
+	var $mandatory;
+	var $respos;
+	var $minInput;
+	var $formElementHtml;
+	var $authVarname;
+	var $detailPos;
+	var $operator;
+	var $showDetail;
+}	
+
+
+class WfsConfiguration {
+	
+	var $id;
+	var $wfsId;
+	var $featureTypeId;
+	var $label; 
+	var $labelId;
+	var $style;
+	var $button;
+	var $buttonId;
+	var $buffer;
+	var $resStyle;
+	var $elementArray = array();
+
+	function __construct () {
+	}
+	
+	public function getGeometryColumnName () {
+		foreach ($this->elementArray as $element) {
+			if ($element->geom) {
+				return $element->name;
+			}
+		}
+		$e = new mb_warning("This WFS conf doesn't have a geometry column.");
+		return null;
+	}
+	
+	/**
+	 * Checks if the user currently logged in is allowed to access
+	 * the WFS configuration
+	 * 
+	 * @return Boolean
+	 */
+	private function accessAllowed () {
+		if ($_SESSION["mb_user_id"]) {
+			$user = new User($_SESSION["mb_user_id"]);
+
+			$allowedWfsConfIds = $user->getWfsConfByPermission();
+
+			$idArray = array_intersect(array($this->id), $allowedWfsConfIds);
+
+			if (count($idArray) === 1) {
+				return true;
+			}
+		}
+		return false;
+	}
+	
+	/**
+	 * Creates an object from the database.
+	 * Maybe we could have a factory for this later...let's
+	 * keep it simple for now
+	 * 
+	 * @return WfsConfiguration
+	 * @param $id Integer
+	 */
+	public static function createFromDb ($id) {
+		if (!is_numeric($id)) {
+			return null;	
+		}
+		$wfsConf = new WfsConfiguration();
+		$wfsConf->id = intval($id);
+		
+		if (!$wfsConf->accessAllowed()) {
+			return null;
+		}
+		
+		$sql = <<<SQL
+SELECT * FROM wfs_conf JOIN wfs ON wfs_conf.fkey_wfs_id = wfs.wfs_id 
+WHERE wfs_conf.wfs_conf_id = $1 LIMIT 1
+SQL;
+
+        $v = array($wfsConf->id);
+        $t = array("i");
+        $res = db_prep_query($sql, $v, $t);
+        $row = db_fetch_array($res);
+		
+		$wfsConf->label = $row["g_label"];
+		$wfsConf->labelId = $row["g_label_id"];
+		$wfsConf->style = $row["g_style"];
+		$wfsConf->button = $row["g_button"];
+		$wfsConf->buttonId = $row["g_button_id"];
+		$wfsConf->buffer = $row["g_buffer"];
+		$wfsConf->resStyle = $row["g_res_style"];
+		$wfsConf->wfsId = $row["fkey_wfs_id"];
+		$wfsConf->featureTypeId = $row["fkey_featuretype_id"];
+
+		$sql = <<<SQL
+SELECT * FROM wfs_conf_element JOIN wfs_element 
+ON wfs_conf_element.f_id = wfs_element.element_id 
+WHERE wfs_conf_element.fkey_wfs_conf_id = $1
+SQL;
+		$v = array($wfsConf->id);
+		$t = array('i');
+		$res = db_prep_query($sql, $v, $t);
+	
+		
+		while ($row = db_fetch_array($res)) {
+			$element = new WfsConfigurationElement();
+
+			$element->name = $row["element_name"];
+			$element->type = $row["element_type"];
+			$element->search = $row["f_search"];
+			$element->styleId = $row["f_style_id"];
+			$element->toUpper = $row["f_toupper"];
+			$element->label = $row["f_label"];
+			$element->labelId = $row["f_label_id"];
+			$element->geom = $row["f_geom"];
+			$element->show = $row["f_show"];
+			$element->mandatory = $row["f_mandatory"];
+			$element->respos = $row["f_respos"];
+			$element->minInput = $row["f_min_input"];
+			$element->formElementHtml = $row["f_form_element_html"];
+			$element->authVarname = $row["f_auth_varname"];
+			$element->detailpos = $row["f_detailpos"];
+			$element->operator = $row["f_operator"];
+			$element->showDetail = $row["f_show_detail"];
+
+			array_push($wfsConf->elementArray, $element);
+		}
+		
+		return $wfsConf;
+	}
+}
+?>
\ No newline at end of file

Added: branches/print_dev/http/css/tablesorter.css
===================================================================
--- branches/print_dev/http/css/tablesorter.css	                        (rev 0)
+++ branches/print_dev/http/css/tablesorter.css	2009-02-24 16:28:58 UTC (rev 3586)
@@ -0,0 +1,39 @@
+/* tables */
+table.tablesorter {
+	font-family: "Verdana","Arial","Tahoma",sans-serif;
+	background-color: #FFFFFF;
+	margin:0 0 0 15px;
+	font-size: 8pt;
+	width: 90%;
+	text-align: left;
+}
+table.tablesorter thead tr th, table.tablesorter tfoot tr th {
+	background-color: #e6EEEE;
+	border: 1px solid #FFF;
+	font-size: 8pt;
+	padding: 4px;
+}
+table.tablesorter thead tr .header {
+	background-image: url(../img/bg.gif);
+	background-repeat: no-repeat;
+	background-position: center right;
+	cursor: pointer;
+}
+table.tablesorter tbody td {
+	color: #3D3D3D;
+	padding: 4px;
+	background-color: #FFF;
+	vertical-align: top;
+}
+table.tablesorter tbody tr.odd td {
+	background-color:#F0F0F6;
+}
+table.tablesorter thead tr .headerSortUp {
+	background-image: url(../img/asc.gif);
+}
+table.tablesorter thead tr .headerSortDown {
+	background-image: url(../img/desc.gif);
+}
+table.tablesorter thead tr .headerSortDown, table.tablesorter thead tr .headerSortUp {
+background-color: #8dbdd8;
+}

Modified: branches/print_dev/http/extensions/geom2wfst.php
===================================================================
--- branches/print_dev/http/extensions/geom2wfst.php	2009-02-24 11:45:18 UTC (rev 3585)
+++ branches/print_dev/http/extensions/geom2wfst.php	2009-02-24 16:28:58 UTC (rev 3586)
@@ -17,17 +17,16 @@
 # along with this program; if not, write to the Free Software
 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 
-/**
- * $_REQUEST["url"]
- * $_REQUEST["filter"] 
- */
+$wfs_conf_id = $_POST["wfs_conf_id"];
+$method = $_POST["method"];
+$geoJson = stripslashes($_POST["geoJson"]);
 
-$wfs_conf_id = $_REQUEST["wfs_conf_id"];
-$featuretype_name = $_REQUEST["featuretype_name"];
-
 require_once(dirname(__FILE__)."/../php/mb_validateSession.php");
 require_once(dirname(__FILE__)."/../classes/class_mb_exception.php");
 require_once(dirname(__FILE__)."/../classes/class_json.php");
+require_once(dirname(__FILE__)."/../classes/class_universal_wfs_factory.php");
+require_once(dirname(__FILE__)."/../classes/class_universal_gml_factory.php");
+require_once(dirname(__FILE__)."/../classes/class_wfs_configuration.php");
 
 function isValidVarName ($varname) {
 	if (preg_match("/[\$]{1}_[a-z]+\[\"[a-z_]+\"\]/i", $varname) != 0) {
@@ -100,43 +99,42 @@
 }
 
 
-function sepNameSpace($s){
-	$c = mb_strpos($s,":"); 
-	if($c>0) return mb_substr($s,$c+1);
-	return $s;
+function sendErrorMessage($data) {
+	$resObj = array();
+	$response = "error";
+	$resObj["errorMessage"] = $data;
+	$resObj["response"] = $response;
+	
+	header("Content-Type:application/x-json");
+	$json = new Mapbender_JSON();
+	echo $json->encode($resObj);
+	die;
 }
-function sendToHost($host,$port,$method,$path,$data){
-	$buf = '';
-    if (empty($method)) $method = 'POST';
-    $method = mb_strtoupper($method);
-    $fp = fsockopen($host, $port);
-    fputs($fp, "$method $path HTTP/1.1\r\n");
-    fputs($fp, "Host: $host\r\n");
-    fputs($fp,"Content-type: application/xml\r\n");
-    fputs($fp, "Content-length: " . strlen($data) . "\r\n");
-    fputs($fp, "Connection: close\r\n\r\n");
-    if ($method == 'POST') fputs($fp, $data);
-    while (!feof($fp)) $buf .= fgets($fp,4096);
-    fclose($fp);
-    return $buf;
+
+
+$wfsConf = WfsConfiguration::createFromDb($wfs_conf_id);
+if (is_null($wfsConf)) {
+	sendErrorMessage("Invalid WFS conf: " . $wfs_conf_id);
 }
 
-$result="";
-$error = false;
-$arURL = parse_url($_REQUEST["url"]);
-$host = $arURL["host"];
-$port = $arURL["port"]; 
-if($port == '') $port = 80;	
+$myWfsFactory = new UniversalWfsFactory();
+$myWfs = $myWfsFactory->createFromDb($wfsConf->wfsId);
 
-$path = $arURL["path"];
-$method = "POST";
-$filter = stripslashes(addParameterToFilter($_REQUEST["filter"], $featuretype_name, $wfs_conf_id));
+if (is_null($myWfs)) {
+	sendErrorMessage("Invalid WFS: " . $wfsConf->wfsId);
+}
 
-$data = sendToHost($host,$port,$method,html_entity_decode($path),$filter);
+$gmlFactory = new UniversalGmlFactory();
+$gmlObj = $gmlFactory->createFromGeoJson($geoJson);
 
+$data = $myWfs->transaction($method, $wfsConf, $gmlObj);
+
+if (is_null($data)) {
+	sendErrorMessage("WFS didn't return any data.");
+}
+
 $data = mb_eregi_replace("^[^<]*", "", $data);
 $data = mb_eregi_replace("[^>]*$", "", $data);
-header('Content-type: text/html');
 
 $resObj = array();
 if (mb_strpos(mb_strtoupper($data), "SUCCESS") !== false) {

Added: branches/print_dev/http/extensions/jquery.tablesorter.js
===================================================================
--- branches/print_dev/http/extensions/jquery.tablesorter.js	                        (rev 0)
+++ branches/print_dev/http/extensions/jquery.tablesorter.js	2009-02-24 16:28:58 UTC (rev 3586)
@@ -0,0 +1,852 @@
+/*
+ * 
+ * TableSorter 2.0 - Client-side table sorting with ease!
+ * Version 2.0.3
+ * @requires jQuery v1.2.3
+ * 
+ * Copyright (c) 2007 Christian Bach
+ * Examples and docs at: http://tablesorter.com
+ * Dual licensed under the MIT and GPL licenses:
+ * http://www.opensource.org/licenses/mit-license.php
+ * http://www.gnu.org/licenses/gpl.html
+ * 
+ */
+/**
+ *
+ * @description Create a sortable table with multi-column sorting capabilitys
+ * 
+ * @example $('table').tablesorter();
+ * @desc Create a simple tablesorter interface.
+ *
+ * @example $('table').tablesorter({ sortList:[[0,0],[1,0]] });
+ * @desc Create a tablesorter interface and sort on the first and secound column in ascending order.
+ * 
+ * @example $('table').tablesorter({ headers: { 0: { sorter: false}, 1: {sorter: false} } });
+ * @desc Create a tablesorter interface and disableing the first and secound column headers.
+ * 
+ * @example $('table').tablesorter({ 0: {sorter:"integer"}, 1: {sorter:"currency"} });
+ * @desc Create a tablesorter interface and set a column parser for the first and secound column.
+ * 
+ * 
+ * @param Object settings An object literal containing key/value pairs to provide optional settings.
+ * 
+ * @option String cssHeader (optional) 			A string of the class name to be appended to sortable tr elements in the thead of the table. 
+ * 												Default value: "header"
+ * 
+ * @option String cssAsc (optional) 			A string of the class name to be appended to sortable tr elements in the thead on a ascending sort. 
+ * 												Default value: "headerSortUp"
+ * 
+ * @option String cssDesc (optional) 			A string of the class name to be appended to sortable tr elements in the thead on a descending sort. 
+ * 												Default value: "headerSortDown"
+ * 
+ * @option String sortInitialOrder (optional) 	A string of the inital sorting order can be asc or desc. 
+ * 												Default value: "asc"
+ * 
+ * @option String sortMultisortKey (optional) 	A string of the multi-column sort key. 
+ * 												Default value: "shiftKey"
+ * 
+ * @option String textExtraction (optional) 	A string of the text-extraction method to use. 
+ * 												For complex html structures inside td cell set this option to "complex", 
+ * 												on large tables the complex option can be slow. 
+ * 												Default value: "simple"
+ * 
+ * @option Object headers (optional) 			An array containing the forces sorting rules. 
+ * 												This option let's you specify a default sorting rule. 
+ * 												Default value: null
+ * 
+ * @option Array sortList (optional) 			An array containing the forces sorting rules. 
+ * 												This option let's you specify a default sorting rule. 
+ * 												Default value: null
+ * 
+ * @option Array sortForce (optional) 			An array containing forced sorting rules. 
+ * 												This option let's you specify a default sorting rule, which is prepended to user-selected rules.
+ * 												Default value: null
+ *  
+  * @option Array sortAppend (optional) 			An array containing forced sorting rules. 
+ * 												This option let's you specify a default sorting rule, which is appended to user-selected rules.
+ * 												Default value: null
+ * 
+ * @option Boolean widthFixed (optional) 		Boolean flag indicating if tablesorter should apply fixed widths to the table columns.
+ * 												This is usefull when using the pager companion plugin.
+ * 												This options requires the dimension jquery plugin.
+ * 												Default value: false
+ *
+ * @option Boolean cancelSelection (optional) 	Boolean flag indicating if tablesorter should cancel selection of the table headers text.
+ * 												Default value: true
+ *
+ * @option Boolean debug (optional) 			Boolean flag indicating if tablesorter should display debuging information usefull for development.
+ *
+ * @type jQuery
+ *
+ * @name tablesorter
+ * 
+ * @cat Plugins/Tablesorter
+ * 
+ * @author Christian Bach/christian.bach at polyester.se
+ */
+
+(function($) {
+	$.extend({
+		tablesorter: new function() {
+			
+			var parsers = [], widgets = [];
+			
+			this.defaults = {
+				cssHeader: "header",
+				cssAsc: "headerSortUp",
+				cssDesc: "headerSortDown",
+				sortInitialOrder: "asc",
+				sortMultiSortKey: "shiftKey",
+				sortForce: null,
+				sortAppend: null,
+				textExtraction: "simple",
+				parsers: {}, 
+				widgets: [],		
+				widgetZebra: {css: ["even","odd"]},
+				headers: {},
+				widthFixed: false,
+				cancelSelection: true,
+				sortList: [],
+				headerList: [],
+				dateFormat: "us",
+				decimal: '.',
+				debug: false
+			};
+			
+			/* debuging utils */
+			function benchmark(s,d) {
+				log(s + "," + (new Date().getTime() - d.getTime()) + "ms");
+			}
+			
+			this.benchmark = benchmark;
+			
+			function log(s) {
+				if (typeof console != "undefined" && typeof console.debug != "undefined") {
+					console.log(s);
+				} else {
+					alert(s);
+				}
+			}
+						
+			/* parsers utils */
+			function buildParserCache(table,$headers) {
+				
+				if(table.config.debug) { var parsersDebug = ""; }
+				
+				var rows = table.tBodies[0].rows;
+				
+				if(table.tBodies[0].rows[0]) {
+
+					var list = [], cells = rows[0].cells, l = cells.length;
+					
+					for (var i=0;i < l; i++) {
+						var p = false;
+						
+						if($.metadata && ($($headers[i]).metadata() && $($headers[i]).metadata().sorter)  ) {
+						
+							p = getParserById($($headers[i]).metadata().sorter);	
+						
+						} else if((table.config.headers[i] && table.config.headers[i].sorter)) {
+	
+							p = getParserById(table.config.headers[i].sorter);
+						}
+						if(!p) {
+							p = detectParserForColumn(table,cells[i]);
+						}
+	
+						if(table.config.debug) { parsersDebug += "column:" + i + " parser:" +p.id + "\n"; }
+	
+						list.push(p);
+					}
+				}
+				
+				if(table.config.debug) { log(parsersDebug); }
+
+				return list;
+			};
+			
+			function detectParserForColumn(table,node) {
+				var l = parsers.length;
+				for(var i=1; i < l; i++) {
+					if(parsers[i].is($.trim(getElementText(table.config,node)),table,node)) {
+						return parsers[i];
+					}
+				}
+				// 0 is always the generic parser (text)
+				return parsers[0];
+			}
+			
+			function getParserById(name) {
+				var l = parsers.length;
+				for(var i=0; i < l; i++) {
+					if(parsers[i].id.toLowerCase() == name.toLowerCase()) {	
+						return parsers[i];
+					}
+				}
+				return false;
+			}
+			
+			/* utils */
+			function buildCache(table) {
+				
+				if(table.config.debug) { var cacheTime = new Date(); }
+				
+				
+				var totalRows = (table.tBodies[0] && table.tBodies[0].rows.length) || 0,
+					totalCells = (table.tBodies[0].rows[0] && table.tBodies[0].rows[0].cells.length) || 0,
+					parsers = table.config.parsers, 
+					cache = {row: [], normalized: []};
+				
+					for (var i=0;i < totalRows; ++i) {
+					
+						/** Add the table data to main data array */
+						var c = table.tBodies[0].rows[i], cols = [];
+					
+						cache.row.push($(c));
+						
+						for(var j=0; j < totalCells; ++j) {
+							cols.push(parsers[j].format(getElementText(table.config,c.cells[j]),table,c.cells[j]));	
+						}
+												
+						cols.push(i); // add position for rowCache
+						cache.normalized.push(cols);
+						cols = null;
+					};
+				
+				if(table.config.debug) { benchmark("Building cache for " + totalRows + " rows:", cacheTime); }
+				
+				return cache;
+			};
+			
+			function getElementText(config,node) {
+				
+				if(!node) return "";
+								
+				var t = "";
+				
+				if(config.textExtraction == "simple") {
+					if(node.childNodes[0] && node.childNodes[0].hasChildNodes()) {
+						t = node.childNodes[0].innerHTML;
+					} else {
+						t = node.innerHTML;
+					}
+				} else {
+					if(typeof(config.textExtraction) == "function") {
+						t = config.textExtraction(node);
+					} else { 
+						t = $(node).text();
+					}	
+				}
+				return t;
+			}
+			
+			function appendToTable(table,cache) {
+				
+				if(table.config.debug) {var appendTime = new Date()}
+				
+				var c = cache, 
+					r = c.row, 
+					n= c.normalized, 
+					totalRows = n.length, 
+					checkCell = (n[0].length-1), 
+					tableBody = $(table.tBodies[0]),
+					rows = [];
+				
+				for (var i=0;i < totalRows; i++) {
+					rows.push(r[n[i][checkCell]]);	
+					if(!table.config.appender) {
+						
+						var o = r[n[i][checkCell]];
+						var l = o.length;
+						for(var j=0; j < l; j++) {
+							
+							tableBody[0].appendChild(o[j]);
+						
+						}
+						
+						//tableBody.append(r[n[i][checkCell]]);
+					}
+				}	
+				
+				if(table.config.appender) {
+				
+					table.config.appender(table,rows);	
+				}
+				
+				rows = null;
+				
+				if(table.config.debug) { benchmark("Rebuilt table:", appendTime); }
+								
+				//apply table widgets
+				applyWidget(table);
+				
+				// trigger sortend
+				setTimeout(function() {
+					$(table).trigger("sortEnd");	
+				},0);
+				
+			};
+			
+			function buildHeaders(table) {
+				
+				if(table.config.debug) { var time = new Date(); }
+				
+				var meta = ($.metadata) ? true : false, tableHeadersRows = [];
+			
+				for(var i = 0; i < table.tHead.rows.length; i++) { tableHeadersRows[i]=0; };
+				
+				$tableHeaders = $("thead th",table);
+		
+				$tableHeaders.each(function(index) {
+							
+					this.count = 0;
+					this.column = index;
+					this.order = formatSortingOrder(table.config.sortInitialOrder);
+					
+					if(checkHeaderMetadata(this) || checkHeaderOptions(table,index)) this.sortDisabled = true;
+					
+					if(!this.sortDisabled) {
+						$(this).addClass(table.config.cssHeader);
+					}
+					
+					// add cell to headerList
+					table.config.headerList[index]= this;
+				});
+				
+				if(table.config.debug) { benchmark("Built headers:", time); log($tableHeaders); }
+				
+				return $tableHeaders;
+				
+			};
+						
+		   	function checkCellColSpan(table, rows, row) {
+                var arr = [], r = table.tHead.rows, c = r[row].cells;
+				
+				for(var i=0; i < c.length; i++) {
+					var cell = c[i];
+					
+					if ( cell.colSpan > 1) { 
+						arr = arr.concat(checkCellColSpan(table, headerArr,row++));
+					} else  {
+						if(table.tHead.length == 1 || (cell.rowSpan > 1 || !r[row+1])) {
+							arr.push(cell);
+						}
+						//headerArr[row] = (i+row);
+					}
+				}
+				return arr;
+			};
+			
+			function checkHeaderMetadata(cell) {
+				if(($.metadata) && ($(cell).metadata().sorter === false)) { return true; };
+				return false;
+			}
+			
+			function checkHeaderOptions(table,i) {	
+				if((table.config.headers[i]) && (table.config.headers[i].sorter === false)) { return true; };
+				return false;
+			}
+			
+			function applyWidget(table) {
+				var c = table.config.widgets;
+				var l = c.length;
+				for(var i=0; i < l; i++) {
+					
+					getWidgetById(c[i]).format(table);
+				}
+				
+			}
+			
+			function getWidgetById(name) {
+				var l = widgets.length;
+				for(var i=0; i < l; i++) {
+					if(widgets[i].id.toLowerCase() == name.toLowerCase() ) {
+						return widgets[i]; 
+					}
+				}
+			};
+			
+			function formatSortingOrder(v) {
+				
+				if(typeof(v) != "Number") {
+					i = (v.toLowerCase() == "desc") ? 1 : 0;
+				} else {
+					i = (v == (0 || 1)) ? v : 0;
+				}
+				return i;
+			}
+			
+			function isValueInArray(v, a) {
+				var l = a.length;
+				for(var i=0; i < l; i++) {
+					if(a[i][0] == v) {
+						return true;	
+					}
+				}
+				return false;
+			}
+				
+			function setHeadersCss(table,$headers, list, css) {
+				// remove all header information
+				$headers.removeClass(css[0]).removeClass(css[1]);
+				
+				var h = [];
+				$headers.each(function(offset) {
+						if(!this.sortDisabled) {
+							h[this.column] = $(this);					
+						}
+				});
+				
+				var l = list.length; 
+				for(var i=0; i < l; i++) {
+					h[list[i][0]].addClass(css[list[i][1]]);
+				}
+			}
+			
+			function fixColumnWidth(table,$headers) {
+				var c = table.config;
+				if(c.widthFixed) {
+					var colgroup = $('<colgroup>');
+					$("tr:first td",table.tBodies[0]).each(function() {
+						colgroup.append($('<col>').css('width',$(this).width()));
+					});
+					$(table).prepend(colgroup);
+				};
+			}
+			
+			function updateHeaderSortCount(table,sortList) {
+				var c = table.config, l = sortList.length;
+				for(var i=0; i < l; i++) {
+					var s = sortList[i], o = c.headerList[s[0]];
+					o.count = s[1];
+					o.count++;
+				}
+			}
+			
+			/* sorting methods */
+			function multisort(table,sortList,cache) {
+				
+				if(table.config.debug) { var sortTime = new Date(); }
+				
+				var dynamicExp = "var sortWrapper = function(a,b) {", l = sortList.length;
+					
+				for(var i=0; i < l; i++) {
+					
+					var c = sortList[i][0];
+					var order = sortList[i][1];
+					var s = (getCachedSortType(table.config.parsers,c) == "text") ? ((order == 0) ? "sortText" : "sortTextDesc") : ((order == 0) ? "sortNumeric" : "sortNumericDesc");
+					
+					var e = "e" + i;
+					
+					dynamicExp += "var " + e + " = " + s + "(a[" + c + "],b[" + c + "]); ";
+					dynamicExp += "if(" + e + ") { return " + e + "; } ";
+					dynamicExp += "else { ";
+				}
+				
+				// if value is the same keep orignal order	
+				var orgOrderCol = cache.normalized[0].length - 1;
+				dynamicExp += "return a[" + orgOrderCol + "]-b[" + orgOrderCol + "];";
+						
+				for(var i=0; i < l; i++) {
+					dynamicExp += "}; ";
+				}
+				
+				dynamicExp += "return 0; ";	
+				dynamicExp += "}; ";	
+				
+				eval(dynamicExp);
+				
+				cache.normalized.sort(sortWrapper);
+				
+				if(table.config.debug) { benchmark("Sorting on " + sortList.toString() + " and dir " + order+ " time:", sortTime); }
+				
+				return cache;
+			};
+			
+			function sortText(a,b) {
+				return ((a < b) ? -1 : ((a > b) ? 1 : 0));
+			};
+			
+			function sortTextDesc(a,b) {
+				return ((b < a) ? -1 : ((b > a) ? 1 : 0));
+			};	
+			
+	 		function sortNumeric(a,b) {
+				return a-b;
+			};
+			
+			function sortNumericDesc(a,b) {
+				return b-a;
+			};
+			
+			function getCachedSortType(parsers,i) {
+				return parsers[i].type;
+			};
+			
+			/* public methods */
+			this.construct = function(settings) {
+
+				return this.each(function() {
+					
+					if(!this.tHead || !this.tBodies) return;
+					
+					var $this, $document,$headers, cache, config, shiftDown = 0, sortOrder;
+					
+					this.config = {};
+					
+					config = $.extend(this.config, $.tablesorter.defaults, settings);
+					
+					// store common expression for speed					
+					$this = $(this);
+					
+					// build headers
+					$headers = buildHeaders(this);
+					
+					// try to auto detect column type, and store in tables config
+					this.config.parsers = buildParserCache(this,$headers);
+					
+					
+					// build the cache for the tbody cells
+					cache = buildCache(this);
+					
+					// get the css class names, could be done else where.
+					var sortCSS = [config.cssDesc,config.cssAsc];
+					
+					// fixate columns if the users supplies the fixedWidth option
+					fixColumnWidth(this);
+					
+					// apply event handling to headers
+					// this is to big, perhaps break it out?
+					$headers.click(function(e) {
+						
+						$this.trigger("sortStart");
+						
+						var totalRows = ($this[0].tBodies[0] && $this[0].tBodies[0].rows.length) || 0;
+						
+						if(!this.sortDisabled && totalRows > 0) {
+							
+							
+							// store exp, for speed
+							var $cell = $(this);
+	
+							// get current column index
+							var i = this.column;
+							
+							// get current column sort order
+							this.order = this.count++ % 2;
+							
+							// user only whants to sort on one column
+							if(!e[config.sortMultiSortKey]) {
+								
+								// flush the sort list
+								config.sortList = [];
+								
+								if(config.sortForce != null) {
+									var a = config.sortForce; 
+									for(var j=0; j < a.length; j++) {
+										if(a[j][0] != i) {
+											config.sortList.push(a[j]);
+										}
+									}
+								}
+								
+								// add column to sort list
+								config.sortList.push([i,this.order]);
+							
+							// multi column sorting
+							} else {
+								// the user has clicked on an all ready sortet column.
+								if(isValueInArray(i,config.sortList)) {	 
+									
+									// revers the sorting direction for all tables.
+									for(var j=0; j < config.sortList.length; j++) {
+										var s = config.sortList[j], o = config.headerList[s[0]];
+										if(s[0] == i) {
+											o.count = s[1];
+											o.count++;
+											s[1] = o.count % 2;
+										}
+									}	
+								} else {
+									// add column to sort list array
+									config.sortList.push([i,this.order]);
+								}
+							};
+							setTimeout(function() {
+								//set css for headers
+								setHeadersCss($this[0],$headers,config.sortList,sortCSS);
+								appendToTable($this[0],multisort($this[0],config.sortList,cache));
+							},1);
+							// stop normal event by returning false
+							return false;
+						}
+					// cancel selection	
+					}).mousedown(function() {
+						if(config.cancelSelection) {
+							this.onselectstart = function() {return false};
+							return false;
+						}
+					});
+					
+					// apply easy methods that trigger binded events
+					$this.bind("update",function() {
+						
+						// rebuild parsers.
+						this.config.parsers = buildParserCache(this,$headers);
+						
+						// rebuild the cache map
+						cache = buildCache(this);
+						
+					}).bind("sorton",function(e,list) {
+						
+						$(this).trigger("sortStart");
+						
+						config.sortList = list;
+						
+						// update and store the sortlist
+						var sortList = config.sortList;
+						
+						// update header count index
+						updateHeaderSortCount(this,sortList);
+						
+						//set css for headers
+						setHeadersCss(this,$headers,sortList,sortCSS);
+						
+						
+						// sort the table and append it to the dom
+						appendToTable(this,multisort(this,sortList,cache));
+
+					}).bind("appendCache",function() {
+						
+						appendToTable(this,cache);
+					
+					}).bind("applyWidgetId",function(e,id) {
+						
+						getWidgetById(id).format(this);
+						
+					}).bind("applyWidgets",function() {
+						// apply widgets
+						applyWidget(this);
+					});
+					
+					if($.metadata && ($(this).metadata() && $(this).metadata().sortlist)) {
+						config.sortList = $(this).metadata().sortlist;
+					}
+					// if user has supplied a sort list to constructor.
+					if(config.sortList.length > 0) {
+						$this.trigger("sorton",[config.sortList]);	
+					}
+					
+					// apply widgets
+					applyWidget(this);
+				});
+			};
+			
+			this.addParser = function(parser) {
+				var l = parsers.length, a = true;
+				for(var i=0; i < l; i++) {
+					if(parsers[i].id.toLowerCase() == parser.id.toLowerCase()) {
+						a = false;
+					}
+				}
+				if(a) { parsers.push(parser); };
+			};
+			
+			this.addWidget = function(widget) {
+				widgets.push(widget);
+			};
+			
+			this.formatFloat = function(s) {
+				var i = parseFloat(s);
+				return (isNaN(i)) ? 0 : i;
+			};
+			this.formatInt = function(s) {
+				var i = parseInt(s);
+				return (isNaN(i)) ? 0 : i;
+			};
+			
+			this.isDigit = function(s,config) {
+				var DECIMAL = '\\' + config.decimal;
+				var exp = '/(^[+]?0(' + DECIMAL +'0+)?$)|(^([-+]?[1-9][0-9]*)$)|(^([-+]?((0?|[1-9][0-9]*)' + DECIMAL +'(0*[1-9][0-9]*)))$)|(^[-+]?[1-9]+[0-9]*' + DECIMAL +'0+$)/';
+				return RegExp(exp).test($.trim(s));
+			};
+			
+			this.clearTableBody = function(table) {
+				if($.browser.msie) {
+					function empty() {
+						while ( this.firstChild ) this.removeChild( this.firstChild );
+					}
+					empty.apply(table.tBodies[0]);
+				} else {
+					table.tBodies[0].innerHTML = "";
+				}
+			};
+		}
+	});
+	
+	// extend plugin scope
+	$.fn.extend({
+        tablesorter: $.tablesorter.construct
+	});
+	
+	var ts = $.tablesorter;
+	
+	// add default parsers
+	ts.addParser({
+		id: "text",
+		is: function(s) {
+			return true;
+		},
+		format: function(s) {
+			return $.trim(s.toLowerCase());
+		},
+		type: "text"
+	});
+	
+	ts.addParser({
+		id: "digit",
+		is: function(s,table) {
+			var c = table.config;
+			return $.tablesorter.isDigit(s,c);
+		},
+		format: function(s) {
+			return $.tablesorter.formatFloat(s);
+		},
+		type: "numeric"
+	});
+	
+	ts.addParser({
+		id: "currency",
+		is: function(s) {
+			return /^[£$€?.]/.test(s);
+		},
+		format: function(s) {
+			return $.tablesorter.formatFloat(s.replace(new RegExp(/[^0-9.]/g),""));
+		},
+		type: "numeric"
+	});
+	
+	ts.addParser({
+		id: "ipAddress",
+		is: function(s) {
+			return /^\d{2,3}[\.]\d{2,3}[\.]\d{2,3}[\.]\d{2,3}$/.test(s);
+		},
+		format: function(s) {
+			var a = s.split("."), r = "", l = a.length;
+			for(var i = 0; i < l; i++) {
+				var item = a[i];
+			   	if(item.length == 2) {
+					r += "0" + item;
+			   	} else {
+					r += item;
+			   	}
+			}
+			return $.tablesorter.formatFloat(r);
+		},
+		type: "numeric"
+	});
+	
+	ts.addParser({
+		id: "url",
+		is: function(s) {
+			return /^(https?|ftp|file):\/\/$/.test(s);
+		},
+		format: function(s) {
+			return jQuery.trim(s.replace(new RegExp(/(https?|ftp|file):\/\//),''));
+		},
+		type: "text"
+	});
+	
+	ts.addParser({
+		id: "isoDate",
+		is: function(s) {
+			return /^\d{4}[\/-]\d{1,2}[\/-]\d{1,2}$/.test(s);
+		},
+		format: function(s) {
+			return $.tablesorter.formatFloat((s != "") ? new Date(s.replace(new RegExp(/-/g),"/")).getTime() : "0");
+		},
+		type: "numeric"
+	});
+		
+	ts.addParser({
+		id: "percent",
+		is: function(s) { 
+			return /\%$/.test($.trim(s));
+		},
+		format: function(s) {
+			return $.tablesorter.formatFloat(s.replace(new RegExp(/%/g),""));
+		},
+		type: "numeric"
+	});
+
+	ts.addParser({
+		id: "usLongDate",
+		is: function(s) {
+			return s.match(new RegExp(/^[A-Za-z]{3,10}\.? [0-9]{1,2}, ([0-9]{4}|'?[0-9]{2}) (([0-2]?[0-9]:[0-5][0-9])|([0-1]?[0-9]:[0-5][0-9]\s(AM|PM)))$/));
+		},
+		format: function(s) {
+			return $.tablesorter.formatFloat(new Date(s).getTime());
+		},
+		type: "numeric"
+	});
+
+	ts.addParser({
+		id: "shortDate",
+		is: function(s) {
+			return /\d{1,2}[\/\-]\d{1,2}[\/\-]\d{2,4}/.test(s);
+		},
+		format: function(s,table) {
+			var c = table.config;
+			s = s.replace(/\-/g,"/");
+			if(c.dateFormat == "us") {
+				// reformat the string in ISO format
+				s = s.replace(/(\d{1,2})[\/\-](\d{1,2})[\/\-](\d{4})/, "$3/$1/$2");
+			} else if(c.dateFormat == "uk") {
+				//reformat the string in ISO format
+				s = s.replace(/(\d{1,2})[\/\-](\d{1,2})[\/\-](\d{4})/, "$3/$2/$1");
+			} else if(c.dateFormat == "dd/mm/yy" || c.dateFormat == "dd-mm-yy") {
+				s = s.replace(/(\d{1,2})[\/\-](\d{1,2})[\/\-](\d{2})/, "$1/$2/$3");	
+			}
+			return $.tablesorter.formatFloat(new Date(s).getTime());
+		},
+		type: "numeric"
+	});
+
+	ts.addParser({
+	    id: "time",
+	    is: function(s) {
+	        return /^(([0-2]?[0-9]:[0-5][0-9])|([0-1]?[0-9]:[0-5][0-9]\s(am|pm)))$/.test(s);
+	    },
+	    format: function(s) {
+	        return $.tablesorter.formatFloat(new Date("2000/01/01 " + s).getTime());
+	    },
+	  type: "numeric"
+	});
+	
+	
+	ts.addParser({
+	    id: "metadata",
+	    is: function(s) {
+	        return false;
+	    },
+	    format: function(s,table,cell) {
+			var c = table.config, p = (!c.parserMetadataName) ? 'sortValue' : c.parserMetadataName;
+	        return $(cell).metadata()[p];
+	    },
+	  type: "numeric"
+	});
+	
+	// add default widgets
+	ts.addWidget({
+		id: "zebra",
+		format: function(table) {
+			if(table.config.debug) { var time = new Date(); }
+			$("tr:visible",table.tBodies[0])
+	        .filter(':even')
+	        .removeClass(table.config.widgetZebra.css[1]).addClass(table.config.widgetZebra.css[0])
+	        .end().filter(':odd')
+	        .removeClass(table.config.widgetZebra.css[0]).addClass(table.config.widgetZebra.css[1]);
+			if(table.config.debug) { $.tablesorter.benchmark("Applying Zebra widget", time); }
+		}
+	});	
+})(jQuery);
\ No newline at end of file

Added: branches/print_dev/http/img/admin.png
===================================================================
(Binary files differ)


Property changes on: branches/print_dev/http/img/admin.png
___________________________________________________________________
Name: svn:mime-type
   + application/octet-stream

Added: branches/print_dev/http/include/template_splash.php
===================================================================
--- branches/print_dev/http/include/template_splash.php	                        (rev 0)
+++ branches/print_dev/http/include/template_splash.php	2009-02-24 16:28:58 UTC (rev 3586)
@@ -0,0 +1,6 @@
+<?php
+echo "<img src='../img/indicator_wheel.gif'>&nbsp;" . 
+	"<b>Ma<font color='#0000CE'>p</font><font color='#C00000'>b</font>ender " . 
+	MB_VERSION_NUMBER . " " . strtolower(MB_VERSION_APPENDIX) . "</b>..." .
+	"loading application '" . $gui_id . "'";
+?>

Modified: branches/print_dev/http/index.php
===================================================================
--- branches/print_dev/http/index.php	2009-02-24 11:45:18 UTC (rev 3585)
+++ branches/print_dev/http/index.php	2009-02-24 16:28:58 UTC (rev 3586)
@@ -111,7 +111,7 @@
 		
 			<div class="mapbender_welcome">Welcome to <font align="left" color="#000000">Ma</font><font color="#0000CE">p</font><font color="#C00000">b</font><font color="#000000">ender</font></div>
 		
-		<font color="#ff0000">Mapbender Version <?php echo MB_VERSION_NUMBER." ".MB_VERSION_APPENDIX?> (<?php echo date("d-m-Y",MB_RELEASE_DATE);?>)</font>
+		<font color="#ff0000">Mapbender Version <?php echo MB_VERSION_NUMBER." ".MB_VERSION_APPENDIX?> (<?php echo date("F jS, Y",MB_RELEASE_DATE);?>)</font>
 		</td></tr>
 	</table>
 <br>

Modified: branches/print_dev/http/javascripts/geometry.js
===================================================================
--- branches/print_dev/http/javascripts/geometry.js	2009-02-24 11:45:18 UTC (rev 3585)
+++ branches/print_dev/http/javascripts/geometry.js	2009-02-24 16:28:58 UTC (rev 3586)
@@ -461,7 +461,14 @@
 	}
 }
 
+GeometryArray.prototype.featureToString = function (i) {
+	var str = "{\"type\": \"FeatureCollection\", \"features\": [";
+	str += this.get(i).toString();
+	str += "]}";
+	return str;
+};
 
+
 GeometryArray.prototype.toString = function () {
 	var str = "{\"type\": \"FeatureCollection\", \"features\": [";
 
@@ -765,17 +772,57 @@
 
 	var epsg = this.getEpsg();
 	if (epsg) {
-		str += "\"crs\": {\"type\": \"EPSG\", \"properties\": {\"code\": " + epsg + "}}, ";
+		str += "\"crs\": {\"type\": \"name\", \"properties\": {\"name\": \"" + epsg + "\"}}, ";
 	}
-	str += "\"geometry\": ";
+	str += "\"geometry\": {";
 
+	var len = this.count(); 
+	
+	switch (this.geomType) {
+		case geomType.polygon:
+			if (len > 1) {
+				str += "\"type\": \"MultiPolygon\", ";
+			}
+			else {
+				str += "\"type\": \"Polygon\", ";
+			}
+			break;
+		case geomType.line:
+			if (len > 1) {
+				str += "\"type\": \"MultiLineString\", ";
+			}
+			else {
+				str += "\"type\": \"LineString\", ";
+			}
+			break;
+		case geomType.point:
+			if (len > 1) {
+				str += "\"type\": \"MultiPoint\", ";
+			}
+			else {
+				str += "\"type\": \"Point\", ";
+			}
+			break;
+	}
+
+	str += "\"coordinates\": "
 	// geometries
-	for (var i = 0, len = this.count(); i < len; i++) {
-		if (i > 0) {
-			str += ",";
-		}		
-		str += this.get(i).toString();
+	if (len > 1) {
+		str += "[";
+		for (var i = 0; i < len; i++) {
+			if (i > 0) {
+				str += ",";
+			}		
+			str += this.get(i).toString();
+		}
+		str += "]";
 	}
+	else {
+		str += this.get(0).toString();
+	}
+
+	str += "}";
+
 // this closing curly bracket is added in toString()
 //	str += "}";
 	
@@ -981,10 +1028,9 @@
 	 */
 	this.setEpsg = function (someEpsg) {
 		// TODO: how to check if EPSG code is correct?
-		if (typeof(someEpsg) == "number") {
-			epsg = someEpsg;
-			return true;
-		}
+		epsg = someEpsg;
+		return true;
+
 		var e = new Mb_exception("EPSG code not valid ("+someEpsg+")");
 		return false;
 	};
@@ -1255,15 +1301,8 @@
 
 Geometry.prototype.toString = function () {
 	var str = "";
-	
-	var epsgStr = "";
-	var epsg = this.getEpsg();
-	if (epsg) {
-		epsgStr = "\"crs\": {\"type\": \"EPSG\", \"properties\": {\"code\": " + epsg + "}}, ";
-	}
-	
 	if (this.geomType == geomType.polygon) {
-		str += "{\"type\": \"Polygon\", " + epsgStr + "\"coordinates\": [[";
+		str += "[[";
 		for (var i = 0; i < this.count(); i++) {
 			if (i > 0) {
 				str += ", ";
@@ -1284,22 +1323,20 @@
 				}
 			}
 		}
-		str += "]]}";
+		str += "]]";
 	}
 	else if (this.geomType == geomType.line) {
-		str += "{\"type\": \"LineString\", " + epsgStr + "\"coordinates\": [";
+		str += "[";
 		for (var i = 0; i < this.count(); i++) {
 			if (i > 0) {
 				str += ", ";
 			}
 			str += this.get(i).toString();
 		}
-		str += "]}";
+		str += "]";
 	}
 	else if (this.geomType == geomType.point) {
-		str += "{\"type\": \"Point\", " + epsgStr + "\"coordinates\": ";
 		str += this.get(0).toString();
-		str += "}";
 	}
 	
 	return str;

Modified: branches/print_dev/http/php/mod_wfs_conf.php
===================================================================
--- branches/print_dev/http/php/mod_wfs_conf.php	2009-02-24 11:45:18 UTC (rev 3585)
+++ branches/print_dev/http/php/mod_wfs_conf.php	2009-02-24 16:28:58 UTC (rev 3586)
@@ -19,6 +19,12 @@
 
 require_once(dirname(__FILE__)."/../php/mb_validateSession.php");
 require(dirname(__FILE__)."/../classes/class_wfs_conf.php");
+
+foreach ($_POST as $key => &$value) {
+	if (is_string($value) && 1 === get_magic_quotes_gpc()) {
+		$value = stripslashes($value);
+	}
+}
 ?>
 <html>
 <head>
@@ -117,7 +123,7 @@
 
 /* save wfs_conf properties */
 
-if(isset($_REQUEST["save"])){
+if(isset($_POST["save"])){
 
         db_select_db($DB,$con);
 
@@ -126,7 +132,7 @@
         $sql .= "fkey_featuretype_id, g_label, g_label_id, g_button, ";
         $sql .= "g_button_id, g_style, g_buffer, g_res_style, g_use_wzgraphics";
 		$sql .= ") VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, ";
-        if (!empty($_REQUEST["g_use_wzgraphics"])) {
+        if (!empty($_POST["g_use_wzgraphics"])) {
 			$sql .= "'1'";
 		}
 		else {
@@ -134,51 +140,62 @@
 		}
         $sql .= "); ";
         
-		$v = array($_REQUEST["wfs_conf_abstract"], $_REQUEST["wfs"], $_REQUEST["featuretype"], $_REQUEST["g_label"], $_REQUEST["g_label_id"], $_REQUEST["g_button"], $_REQUEST["g_button_id"], $_REQUEST["g_style"], $_REQUEST["g_buffer"], $_REQUEST["g_res_style"]);
+		$v = array(
+			$_POST["wfs_conf_abstract"], 
+			$_POST["wfs"], 
+			$_POST["featuretype"], 
+			$_POST["g_label"], 
+			$_POST["g_label_id"], 
+			$_POST["g_button"], 
+			$_POST["g_button_id"], 
+			$_POST["g_style"], 
+			$_POST["g_buffer"], 
+			$_POST["g_res_style"]
+		);
 		$t = array("s", "s", "s", "s", "s", "s", "s", "s", "s", "s");
         $res = db_prep_query($sql, $v, $t);
         
         $wfsID = db_insert_id($con,'wfs_conf','wfs_conf_id');
 
-        for ($i = 0; $i < $_REQUEST["num"]; $i++){
+        for ($i = 0; $i < $_POST["num"]; $i++){
                 $sql = "INSERT INTO wfs_conf_element (fkey_wfs_conf_id,f_id,f_search,f_pos,f_min_input,f_style_id,f_toupper,f_label,f_label_id,f_show,f_respos,f_edit,f_form_element_html,f_mandatory,f_auth_varname,f_show_detail,f_detailpos,f_operator) VALUES(";
                 $sql .= "$1, $2, ";
-                if (!empty($_REQUEST["f_search".$i])) {
+                if (!empty($_POST["f_search".$i])) {
                 	$sql .= "'1'";
                 }
                 else {
                 	$sql .= "'0'";
                 }
                 $sql .= ", $3, $4, $5, ";
-				if (!empty($_REQUEST["f_toupper".$i])) {
+				if (!empty($_POST["f_toupper".$i])) {
                 	$sql .= "'1'";
                 }
                 else {
                 	$sql .= "'0'";
                 }				
                 $sql .= ",$6, $7, ";
-                if (!empty($_REQUEST["f_show".$i])) {
+                if (!empty($_POST["f_show".$i])) {
                 	$sql .= "'1'";
                 }
                 else {
                 	$sql .= "'0'";
                 }
                 $sql .= ", $8, ";
-                if (!empty($_REQUEST["f_edit".$i])) {
+                if (!empty($_POST["f_edit".$i])) {
                 	$sql .= "'1'";
                 } 
                 else {
                 	$sql .= "'0'";
                 }
                 $sql .= ",$9, ";
-                if (!empty($_REQUEST["f_mandatory".$i])) {
+                if (!empty($_POST["f_mandatory".$i])) {
                 	$sql .= "'1'";
                 }
                 else {
                 	$sql .= "'0'";
                 }
                 $sql .= ",$10,";
-                if(!empty($_REQUEST["f_show_detail".$i])){
+                if(!empty($_POST["f_show_detail".$i])){
                 	$sql .= "'1'";
                 }
                 else {
@@ -187,14 +204,14 @@
                 $sql .= ",$11,$12";
  				$sql .= "); ";
 
-				$v = array($wfsID, $_REQUEST["f_id".$i], $_REQUEST["f_pos".$i], $_REQUEST["f_min_input".$i], $_REQUEST["f_style_id".$i], $_REQUEST["f_label".$i], $_REQUEST["f_label_id".$i], $_REQUEST["f_respos".$i], stripslashes($_REQUEST["f_form_element_html".$i]), $_REQUEST["f_auth_varname".$i], $_REQUEST["f_detailpos".$i], $_REQUEST["f_operator".$i]);
+				$v = array($wfsID, $_POST["f_id".$i], $_POST["f_pos".$i], $_POST["f_min_input".$i], $_POST["f_style_id".$i], $_POST["f_label".$i], $_POST["f_label_id".$i], $_POST["f_respos".$i], $_POST["f_form_element_html".$i], $_POST["f_auth_varname".$i], $_POST["f_detailpos".$i], $_POST["f_operator".$i]);
 				$t = array("i", "s", "s", "i", "s", "s", "s", "i", "s", "s", "i", "s");
                 $res = db_prep_query($sql, $v, $t);
         }
-        if (isset($_REQUEST["f_geom"])) {
+        if (isset($_POST["f_geom"])) {
 	        $sql = "UPDATE wfs_conf_element SET f_geom = 1 ";
 	        $sql .= "WHERE fkey_wfs_conf_id = $1 AND f_id = $2;";
-	        $v = array($wfsID, $_REQUEST["f_geom"]);
+	        $v = array($wfsID, $_POST["f_geom"]);
 	        $t = array("i", "i");
 			$res = db_prep_query($sql, $v, $t);
         }
@@ -208,16 +225,16 @@
 
 /* select wfs */
 
-if(isset($_REQUEST["wfs"]) && $_REQUEST["wfs"] == ""){
-        unset($_REQUEST["wfs"]);
-        unset($_REQUEST["featuretype"]);
+if(isset($_POST["wfs"]) && $_POST["wfs"] == ""){
+        unset($_POST["wfs"]);
+        unset($_POST["featuretype"]);
 }
 
 echo "<select name='wfs' onchange='selectWFS()'>";
 echo "<option value=''>...</option>";
 for($i=0; $i<count($aWFS->wfs_id);$i++){
         echo "<option value='".$aWFS->wfs_id[$i]."' ";
-        if(isset($_REQUEST["wfs"]) && $aWFS->wfs_id[$i] == $_REQUEST["wfs"]){
+        if(isset($_POST["wfs"]) && $aWFS->wfs_id[$i] == $_POST["wfs"]){
                 echo "selected";
         }
         echo ">".$aWFS->wfs_id[$i]." ".$aWFS->wfs_title[$i]."</option>";
@@ -230,10 +247,10 @@
 
 /* select featuretype */
 
-if(isset($_REQUEST["wfs"])){
+if(isset($_POST["wfs"])){
 
         for($i=0; $i<count($aWFS->wfs_id);$i++){
-                if($aWFS->wfs_id[$i] == $_REQUEST["wfs"]){
+                if($aWFS->wfs_id[$i] == $_POST["wfs"]){
                         echo "<table>";
                         echo "<tr><td>ID:</td><td>".$aWFS->wfs_id[$i]."</td></tr>";
                         echo "<tr><td>Name:</td><td>".$aWFS->wfs_name[$i]."</td></tr>";
@@ -246,12 +263,12 @@
                 }
         }
 
-        $aWFS->getfeatures($_REQUEST["wfs"]);
+        $aWFS->getfeatures($_POST["wfs"]);
         echo "<table>";
         for($i=0; $i<count($aWFS->features->featuretype_id); $i++){
                 echo "<tr>";
                 echo "<td><input type='radio' name='featuretype' value='".$aWFS->features->featuretype_id[$i]."' onclick='submit()' ";
-                if(isset($_REQUEST["featuretype"]) && $_REQUEST["featuretype"] == $aWFS->features->featuretype_id[$i]){
+                if(isset($_POST["featuretype"]) && $_POST["featuretype"] == $aWFS->features->featuretype_id[$i]){
                         echo "checked ";
                 }
                 echo "/></td>";
@@ -264,11 +281,11 @@
 /* end select featuretype */
 
 /* configure elements */
-if(isset($_REQUEST["featuretype"])){
+if(isset($_POST["featuretype"])){
 
 
         for($i=0; $i<count($aWFS->features->featuretype_id); $i++){
-                if($_REQUEST["featuretype"] == $aWFS->features->featuretype_id[$i]){
+                if($_POST["featuretype"] == $aWFS->features->featuretype_id[$i]){
                         echo "<hr>SRS: ".$aWFS->features->featuretype_srs[$i];
                 }
         }
@@ -288,7 +305,7 @@
 
 
         /* set element options */
-        $aWFS->getelements($_REQUEST["featuretype"]);
+        $aWFS->getelements($_POST["featuretype"]);
         echo "<table border='1'>";
         echo "<tr valign = bottom>";
                 echo "<td>" . toImage('ID') . "</td>";
@@ -354,4 +371,4 @@
 /* end configure elements */
 ?>
 </form>
-</body>
\ No newline at end of file
+</body>

Modified: branches/print_dev/http/php/mod_wfs_edit.php
===================================================================
--- branches/print_dev/http/php/mod_wfs_edit.php	2009-02-24 11:45:18 UTC (rev 3585)
+++ branches/print_dev/http/php/mod_wfs_edit.php	2009-02-24 16:28:58 UTC (rev 3586)
@@ -18,6 +18,12 @@
 # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 
 require_once(dirname(__FILE__)."/../php/mb_validateSession.php");
+
+foreach ($_POST as $key => &$value) {
+	if (is_string($value) && 1 === get_magic_quotes_gpc()) {
+		$value = stripslashes($value);
+	}
+}
 ?>
 <html>
 <head>
@@ -91,13 +97,13 @@
 <?php
 /* save wfs_conf properties */
 
-if(isset($_REQUEST["save"])){
+if(isset($_POST["save"])){
 
         $sql = "UPDATE wfs_conf SET ";
         $sql .= "wfs_conf_abstract = $1, g_label = $2, ";
         $sql .= "g_label_id = $3, g_button = $4, g_button_id = $5, g_style = $6, ";
         $sql .= "g_buffer = $7, g_res_style = $8, g_use_wzgraphics = ";
-        if (!empty($_REQUEST["g_use_wzgraphics"])) {
+        if (!empty($_POST["g_use_wzgraphics"])) {
         	$sql .= "1";
         }
         else {
@@ -105,35 +111,35 @@
         }
         $sql .= " WHERE wfs_conf_id = $9;";
         
-        $v = array($_REQUEST["wfs_conf_abstract"], $_REQUEST["g_label"], $_REQUEST["g_label_id"], $_REQUEST["g_button"], $_REQUEST["g_button_id"], $_REQUEST["g_style"], $_REQUEST["g_buffer"], $_REQUEST["g_res_style"], $_REQUEST["gaz"]);
+        $v = array($_POST["wfs_conf_abstract"], $_POST["g_label"], $_POST["g_label_id"], $_POST["g_button"], $_POST["g_button_id"], $_POST["g_style"], $_POST["g_buffer"], $_POST["g_res_style"], $_POST["gaz"]);
         $t = array("s", "s", "s", "s", "s", "s", "s", "s", "s");
         $res = db_prep_query($sql, $v, $t);
 		        
-		if (isset($_REQUEST["f_geom"])) {
+		if (isset($_POST["f_geom"])) {
 	        $sql = "UPDATE wfs_conf_element SET f_geom = 1 ";
 	        $sql .= "WHERE fkey_wfs_conf_id = $1 AND f_id = $2;";
-	        $v = array($_REQUEST["gaz"], $_REQUEST["f_geom"]);
+	        $v = array($_POST["gaz"], $_POST["f_geom"]);
 	        $t = array("i", "s");
 			$res = db_prep_query($sql, $v, $t);
 			
 			$sql = "UPDATE wfs_conf_element SET f_geom = 0 ";
 	        $sql .= "WHERE fkey_wfs_conf_id = $1 AND f_id <> $2;";
-	        $v = array($_REQUEST["gaz"], $_REQUEST["f_geom"]);
+	        $v = array($_POST["gaz"], $_POST["f_geom"]);
 	        $t = array("i", "s");
 			$res = db_prep_query($sql, $v, $t);
 		}
 		else {
 			$sql = "UPDATE wfs_conf_element SET f_geom = 0 ";
 	        $sql .= "WHERE fkey_wfs_conf_id = $1;";
-	        $v = array($_REQUEST["gaz"]);
+	        $v = array($_POST["gaz"]);
 	        $t = array("i");
 			$res = db_prep_query($sql, $v, $t);
 		}
 		
-        for($i=0; $i<$_REQUEST["num"]; $i++){
+        for($i=0; $i<$_POST["num"]; $i++){
         	
                 $sql = "UPDATE wfs_conf_element SET f_search = '";
-                if (!empty($_REQUEST["f_search".$i])) {
+                if (!empty($_POST["f_search".$i])) {
                 	$sql .= "1";
                 }
                 else {
@@ -141,7 +147,7 @@
                 }
                 $sql .= "', f_pos = $1, f_min_input = $2, f_style_id = $3,";
                 $sql .= "f_toupper = '" ;
-                if (!empty($_REQUEST["f_toupper".$i])) {
+                if (!empty($_POST["f_toupper".$i])) {
                 	$sql .= "1";
                 }
                 else { 
@@ -149,7 +155,7 @@
                 }
                 $sql .= "',f_label = $4, f_label_id = $5,";
                 $sql .= "f_show = '";
-                if (!empty($_REQUEST["f_show".$i])) {
+                if (!empty($_POST["f_show".$i])) {
                 	$sql .= "1";
                 }
                 else {
@@ -157,7 +163,7 @@
                 }
 				$sql .= "',f_respos = $6,";
                 $sql .= "f_edit = '";
-                if (!empty($_REQUEST["f_edit".$i])) {
+                if (!empty($_POST["f_edit".$i])) {
                 	$sql .= "1";
                 }
                 else {
@@ -165,15 +171,15 @@
                 }
 				$sql .= "', f_form_element_html = $7,";
                 $sql .= "f_mandatory = '";
-                if (!empty($_REQUEST["f_mandatory".$i])) {
+                if (!empty($_POST["f_mandatory".$i])) {
                 	$sql .= "1";
                 }
                 else {
                 	$sql .= "0";
                 }
 				$sql .= "', f_auth_varname = $8";
-			   	$sql .= ", f_show_detail = '";
-                if(!empty($_REQUEST["f_show_detail".$i])){
+				$sql .= ", f_show_detail = '";
+                if(!empty($_POST["f_show_detail".$i])){
                 	$sql .= "1";
                 }
                 else {
@@ -183,7 +189,7 @@
                 $sql .= ", f_operator = $10";
 				$sql .= " WHERE fkey_wfs_conf_id = $11 AND f_id = $12;";
 
-				$v = array($_REQUEST["f_pos".$i], $_REQUEST["f_min_input".$i], $_REQUEST["f_style_id".$i], $_REQUEST["f_label".$i], $_REQUEST["f_label_id".$i], $_REQUEST["f_respos".$i], stripslashes($_REQUEST["f_form_element_html".$i]), $_REQUEST["f_auth_varname".$i], $_REQUEST["f_detailpos".$i], $_REQUEST["f_operator".$i], $_REQUEST["gaz"], $_REQUEST["f_id".$i]);
+				$v = array($_POST["f_pos".$i], $_POST["f_min_input".$i], $_POST["f_style_id".$i], $_POST["f_label".$i], $_POST["f_label_id".$i], $_POST["f_respos".$i], $_POST["f_form_element_html".$i], $_POST["f_auth_varname".$i], $_POST["f_detailpos".$i], $_POST["f_operator".$i], $_POST["gaz"], $_POST["f_id".$i]);
 				$t = array("s", "i", "s", "s", "s", "s", "s", "s", "i", "s", "i", "s");
                 $res = db_prep_query($sql, $v, $t);
         }
@@ -199,7 +205,7 @@
 $cnt = 0;
 while($row = db_fetch_array($res)){
         echo "<option value='".$row["wfs_conf_id"]."' ";
-        if(isset($_REQUEST["gaz"]) && $row["wfs_conf_id"] == $_REQUEST["gaz"]){
+        if(isset($_POST["gaz"]) && $row["wfs_conf_id"] == $_POST["gaz"]){
                 echo "selected";
         }
         echo ">".$row["wfs_conf_id"]." ".$row["wfs_conf_abstract"]."</option>";
@@ -220,9 +226,9 @@
 }
 
 /* configure elements */
-if (isset($_REQUEST["gaz"])) {
+if (isset($_POST["gaz"])) {
         $sql = "SELECT * FROM wfs_conf WHERE wfs_conf_id = $1";
-        $v = array($_REQUEST["gaz"]);
+        $v = array($_POST["gaz"]);
         $t = array("i");
         $res = db_prep_query($sql, $v, $t);
         if($row = db_fetch_array($res)){
@@ -246,7 +252,7 @@
         $sql = "SELECT * FROM wfs_conf_element ";
         $sql .= "JOIN wfs_element ON wfs_conf_element.f_id = wfs_element.element_id ";
         $sql .= "WHERE fkey_wfs_conf_id = $1 ORDER BY f_id";
-		$v = array($_REQUEST["gaz"]);
+		$v = array($_POST["gaz"]);
 		$t = array("i");
         $res = db_prep_query($sql, $v, $t);
 		
@@ -307,8 +313,8 @@
                 echo "<td><input name='f_toupper".$cnt."' type='checkbox'";
                 if($row["f_toupper"] == 1){ echo " checked"; }
                 echo "></td>";
-                echo "<td><input name='f_label".$cnt."' type='text' size='4' value='".$row["f_label"]."'></td>";
-                echo "<td><input name='f_label_id".$cnt."' type='text' size='2' value='".$row["f_label_id"]."'></td>";
+                echo "<td><input name='f_label".$cnt."' type='text' size='4' value=\"".htmlentities($row["f_label"])."\"></td>";
+                echo "<td><input name='f_label_id".$cnt."' type='text' size='2' value=\"".htmlentities($row["f_label_id"])."\"></td>";
                 echo "<td><input name='f_show".$cnt."' type='checkbox'";
                 if($row["f_show"] == 1){ echo " checked"; }
                 echo "></td>";
@@ -323,8 +329,8 @@
                 echo "<td><input name='f_edit".$cnt."' type='checkbox'";
                 if($row["f_edit"] == 1){ echo " checked"; }
                 echo "></td>";
-                echo "<td><textarea name='f_form_element_html".$cnt."' cols='15' rows='1' >".$row["f_form_element_html"]."</textarea></td>";
-                echo "<td><input name='f_auth_varname".$cnt."' type='text' size='8' value='".$row["f_auth_varname"]."'></td>";
+                echo "<td><textarea name='f_form_element_html".$cnt."' cols='15' rows='1' >".htmlentities($row["f_form_element_html"])."</textarea></td>";
+                echo "<td><input name='f_auth_varname$cnt' type='text' size='8' value=\"" . htmlentities($row["f_auth_varname"]) . "\"></td>";
                 echo "<td><select name='f_operator".$cnt."' id='f_operator".$cnt."' ";
                 if($row["f_search"] != 1){
                 	echo "disabled";
@@ -368,4 +374,4 @@
 /* end configure elements */
 ?>
 </form>
-</body>
\ No newline at end of file
+</body>

Modified: branches/print_dev/lib/exception.js
===================================================================
--- branches/print_dev/lib/exception.js	2009-02-24 11:45:18 UTC (rev 3585)
+++ branches/print_dev/lib/exception.js	2009-02-24 16:28:58 UTC (rev 3586)
@@ -34,7 +34,7 @@
 	var isValidLevel = function(aLevel) {
 		var isNotOff = typeof(log_js) != 'undefined' && log_js != "off";
 		var levelIndex = indexOfLevel(aLevel);
-		var isAppropriate = (typeof(levelIndex)=='number' && levelIndex < indexOfLevel(log_level));
+		var isAppropriate = (typeof(levelIndex)=='number' && levelIndex <= indexOfLevel(log_level));
 		return (isNotOff && isAppropriate);
 	};
 	this.throwException = function (message, level) {

Modified: branches/print_dev/resources/db/update/update_2.6.sql
===================================================================
--- branches/print_dev/resources/db/update/update_2.6.sql	2009-02-24 11:45:18 UTC (rev 3585)
+++ branches/print_dev/resources/db/update/update_2.6.sql	2009-02-24 16:28:58 UTC (rev 3586)
@@ -15,6 +15,19 @@
 INSERT INTO gui_element_vars(fkey_gui_id, fkey_e_id, var_name, var_value, context, var_type) VALUES('gui_digitize', 'gazetteerWFS', 'showResultInPopup', '1', 'if value is 1 search results will be displayed in popup, otherwise in gazetteer div' ,'var');
 INSERT INTO gui_element_vars(fkey_gui_id, fkey_e_id, var_name, var_value, context, var_type) VALUES('gui_digitize', 'gazetteerWFS', 'wfs_spatial_request_conf_filename', 'wfs_additional_spatial_search.conf', 'location and name of the WFS configuration file for spatialRequest' ,'php_var');
 
+--new element vars for body for css style of popups and tablesorter
+INSERT INTO gui_element_vars (fkey_gui_id, fkey_e_id, var_name, var_value, context, var_type) VALUES ('gui', 'body', 'popupcss', '../css/popup.css', 'file css', 'file/css');
+INSERT INTO gui_element_vars (fkey_gui_id, fkey_e_id, var_name, var_value, context, var_type) VALUES ('gui2', 'body', 'popupcss', '../css/popup.css', 'file css', 'file/css');
+INSERT INTO gui_element_vars (fkey_gui_id, fkey_e_id, var_name, var_value, context, var_type) VALUES ('gui_digitize', 'body', 'popupcss', '../css/popup.css', 'file css', 'file/css');
+INSERT INTO gui_element_vars(fkey_gui_id, fkey_e_id, var_name, var_value, context, var_type) VALUES('gui', 'body', 'tablesortercss', '../css/tablesorter.css', 'file css' ,'file/css');
+INSERT INTO gui_element_vars(fkey_gui_id, fkey_e_id, var_name, var_value, context, var_type) VALUES('gui2', 'body', 'tablesortercss', '../css/tablesorter.css', 'file css' ,'file/css');
+INSERT INTO gui_element_vars(fkey_gui_id, fkey_e_id, var_name, var_value, context, var_type) VALUES('gui_digitize', 'body', 'tablesortercss', '../css/tablesorter.css', 'file css' ,'file/css');
+
+--add all used modules for gazetteerWFS
+UPDATE gui_element SET e_mb_mod = 'geometry.js,requestGeometryConstructor.js,popup.js,../extensions/jquery.tablesorter.js' WHERE e_id = 'gazetteerWFS' AND fkey_gui_id = 'gui';
+UPDATE gui_element SET e_mb_mod = 'geometry.js,requestGeometryConstructor.js,popup.js,../extensions/jquery.tablesorter.js' WHERE e_id = 'gazetteerWFS' AND fkey_gui_id = 'gui2';
+UPDATE gui_element SET e_mb_mod = 'geometry.js,requestGeometryConstructor.js,popup.js,../extensions/jquery.tablesorter.js' WHERE e_id = 'gazetteerWFS' AND fkey_gui_id = 'gui_digitize';
+
 --add style class to element var text css of element digitize in gui_digitize
 UPDATE gui_element_vars SET var_value = '
 .digitizeGeometryList{
@@ -86,7 +99,26 @@
 </div>' WHERE e_id = 'navFrame';
 
 
-UPDATE gui_element SET e_pos = 1, e_element = 'div', e_src = '', e_attributes = '', e_more_styles = 'overflow:hidden;', e_content = '<div id="mapframe1_maps" style="position:absolute;left:0px;right:0px;"></div>', e_closetag = 'div', e_js_file = 'mapnf.php' WHERE e_id = 'mapframe1';
+UPDATE gui_element SET e_pos = 1, e_element = 'div', e_src = '', e_attributes = '', e_more_styles = 'overflow:hidden;', e_content = '<div id="markResult" name="maps" style ="position: absolute; left: 0px; top: 0px; width: 0px; height: 0px; z-index:26"> </div>
+<div id="mapframe1_maps" name="maps" style ="position: absolute; left: 0px; top: 0px; width: 0px; height: 0px; z-index:2;"> </div>
+<div id="highlight" style="position:absolute;top:-10px;left:-10px;width:14px;height:14px;z-index:3;visibility:visible"><img src="../img/redball.gif"/></div>
+<div id="l_right" name="l_right" style="position:absolute;top:0px;left:0px;width:0px;height:0px;overflow:hidden;z-index:10;visibility:hidden;background-color:#ff0000;cursor: crosshair;"></div>
+<div id="l_bottom"  name="l_bottom" style="position:absolute;top:0px;left:0px;width:0px;height:0px;overflow:hidden;z-index:11;visibility:hidden;background-color:#ff0000;cursor: crosshair;"></div>
+<div id="l_left" name="l_left" style="position:absolute;top:0px;left:0px;width:0px;height:0px;overflow:hidden;z-index:12;visibility:hidden;background-color:#ff0000;cursor: crosshair;"></div>
+<div id="l_top" name="l_top" style="position:absolute;top:0px;left:0px;width:0px;height:0px;overflow:hidden;z-index:13;visibility:hidden;background-color:#ff0000;cursor: crosshair;"></div>
+<div id="sandclock" style="position:absolute; top:0px; left:0px; z-index:14;"></div>
+<div id="scalebar" style="position:absolute; top:0px; left:0px; z-index:15;"></div>
+<div id="measuring" style="position:absolute; top:0px; left:0px; z-index:16; font-size:10px"></div>
+<div id="measure_display" style="position:absolute; top:0px; left:0px; z-index:17;"></div>
+<div id="copyright" style="position:absolute; top:0px; left:0px; z-index:18;"></div>
+<div id="measure_sub" style="position:absolute; top:0px; left:0px; z-index:19;"></div>
+<div id="permanent" style="position:absolute;top:-10px;left:-10px;width:14px;height:14px;z-index:13;visibility:hidden"><img src="../img/redball.gif"/></div>
+<div id="digitize_sub" style="position:absolute; top:0px; left:0px; z-index:24;"></div>
+<div id="digitize_display" style="position:absolute; top:0px; left:0px; z-index:25;"></div>
+<div id="um_title" name="um_title" style="font-family: Arial, Helvetica, sans-serif; DISPLAY:none; OVERFLOW:visible; POSITION:absolute; DISPLAY:none; BACKGROUND:#BEC1C4;border:1px solid black; z-index:98;"></div>
+<div id="um_draw" name="um_draw" style="LEFT:0px;OVERFLOW:visible;POSITION:absolute;TOP:0px;z-index:99;"></div>
+<img id="um_img" name="um_img" style ="position: absolute; left: 0px; top: 0px; width: 0px; height: 0px; border:0;z-index:100" src="../img/transparent.gif" useMap="#um">
+<map name="um" id="um"></map>', e_closetag = 'div', e_js_file = 'mapnf.php' WHERE e_id = 'mapframe1';
 UPDATE gui_element SET e_element = 'div', e_src = '', e_attributes = '', e_more_styles = 'overflow:hidden;', e_content = '<div id="overview_maps" style="position:absolute;left:0px;right:0px;"></div>', e_closetag = 'div', e_js_file = 'ovnf.php', e_target = 'mapframe1', e_requires = 'mapframe1' WHERE e_id = 'overview';
 INSERT INTO gui_element_vars select fkey_gui_id,'overview' as fkey_e_id, 'overview_wms' as var_name, '0' as var_value, 'wms that shows up as overview' as context, 'var' as var_type from gui_element where e_id = 'overview';
 UPDATE gui_element SET e_pos = 2, e_element = 'div', e_more_styles = 'visibility:visible;overflow:scroll', e_content = '', e_closetag = 'div', e_js_file = '../html/mod_treefolderPlain.php', e_mb_mod = 'jsTree.js', e_requires = 'mapframe1' WHERE e_id = 'treeGDE';
@@ -101,6 +133,7 @@
 DELETE FROM gui_element WHERE e_id = 'closePolygon';
 DELETE FROM gui_element WHERE e_id = 'rubber';
 DELETE FROM gui_element WHERE e_id = 'getArea';
+DELETE FROM gui_element WHERE e_id = 'rubberExt';
 
 UPDATE gui_element SET e_element = 'div', e_src = '', e_attributes = '', e_more_styles = 'overflow:hidden;', e_content = '', e_closetag = 'div', e_js_file = 'mod_zoomCoords.php', e_target = 'mapframe1,overview', e_requires = 'mapframe1' WHERE e_id = 'zoomCoords';
 
@@ -108,3 +141,8 @@
 -- a demo splash screen for gui1
 INSERT INTO gui_element_vars(fkey_gui_id, fkey_e_id, var_name, var_value, context, var_type) VALUES('gui1', 'body', 'use_load_message', 'true', '' ,'php_var');
 INSERT INTO gui_element_vars(fkey_gui_id, fkey_e_id, var_name, var_value, context, var_type) VALUES('gui1', 'body', 'includeWhileLoading', '../include/gui1_splash.php', '' ,'php_var');
+
+UPDATE gui_element SET e_mb_mod = '../extensions/wz_jsgraphics.js,geometry.js' WHERE e_id = 'wfs';
+ 
+INSERT INTO translations (locale, msgid, msgstr) VALUES ('de', 'Measure distance', 'Messen'); 
+UPDATE gui_element SET e_attributes = 'onload="init()"' WHERE e_id = 'body' AND fkey_gui_id IN ('wms_africa', 'wms_australia', 'wms_europe', 'wms_gdi_de', 'wms_germany', 'wms_north_america', 'wms_worldwide');



More information about the Mapbender_commits mailing list