Kaynağa Gözat

ogc:Filter export parser from Data_Source to ParseOgcFilter

Piotr Labudda 10 yıl önce
ebeveyn
işleme
ce43aa9a67

+ 65 - 0
SE/schema/wfs/convertOgcFilterToXmlTaskList.xsl

@@ -0,0 +1,65 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsl:stylesheet version="1.0"
+								xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
+								xmlns:filter="https://biuro.biall-net.pl/SE/version-git/schema/filter.xsd"
+								xmlns:ogc="http://www.opengis.net/ogc"
+								>
+	<xsl:output method="xml" omit-xml-declaration="yes" indent="no"/>
+
+	<xsl:template match="/">
+		<xsl:element name="filter">
+			<xsl:apply-templates select="filter:filter/ogc:Filter"/>
+		</xsl:element>
+	</xsl:template>
+
+	<xsl:template match="ogc:Filter">
+		<xsl:apply-templates/>
+	</xsl:template>
+
+	<xsl:template match="*">
+		<xsl:element name="not_implemented_tag">
+			<xsl:attribute name="name"><xsl:value-of select="name()"/></xsl:attribute>
+			<xsl:apply-templates/>
+		</xsl:element>
+	</xsl:template>
+
+	<xsl:template match="ogc:Or">
+		<xsl:element name="sql_filter_openBlock">
+			<xsl:attribute name="type"><xsl:value-of select="'or'" /></xsl:attribute>
+		</xsl:element>
+		<xsl:apply-templates/>
+		<xsl:element name="sql_filter_closeBlock">
+			<xsl:attribute name="type"><xsl:value-of select="'or'" /></xsl:attribute>
+		</xsl:element>
+	</xsl:template>
+
+	<xsl:template match="ogc:And">
+		<xsl:element name="sql_filter_openBlock">
+			<xsl:attribute name="type"><xsl:value-of select="'and'" /></xsl:attribute>
+		</xsl:element>
+		<xsl:apply-templates/>
+		<xsl:element name="sql_filter_closeBlock">
+			<xsl:attribute name="type"><xsl:value-of select="'and'" /></xsl:attribute>
+		</xsl:element>
+	</xsl:template>
+
+	<xsl:template match="ogc:PropertyIsEqualTo">
+		<xsl:element name="sql_filter_comparisonFieldToValue">
+			<xsl:attribute name="fieldName"><xsl:value-of select="ogc:PropertyName" /></xsl:attribute>
+			<xsl:attribute name="comparisonSign"><xsl:value-of select="'='" /></xsl:attribute>
+			<xsl:attribute name="value"><xsl:value-of select="ogc:Literal" /></xsl:attribute>
+		</xsl:element>
+	</xsl:template>
+
+	<xsl:template match="ogc:PropertyIsLike">
+		<xsl:element name="sql_filter_comparisonFieldToValue">
+			<xsl:attribute name="fieldName"><xsl:value-of select="ogc:PropertyName" /></xsl:attribute>
+			<xsl:attribute name="comparisonSign"><xsl:value-of select="'like'" /></xsl:attribute>
+			<xsl:attribute name="value"><xsl:value-of select="ogc:Literal" /></xsl:attribute>
+			<xsl:attribute name="wildCard"><xsl:value-of select="@wildCard" /></xsl:attribute>
+			<xsl:attribute name="singleChar"><xsl:value-of select="@singleChar" /></xsl:attribute>
+			<xsl:attribute name="escapeChar"><xsl:value-of select="@escapeChar" /></xsl:attribute>
+		</xsl:element>
+	</xsl:template>
+
+</xsl:stylesheet>

+ 4 - 186
SE/se-lib/Data_Source.php

@@ -1,6 +1,7 @@
 <?php
 <?php
 
 
 Lib::loadClass('SqlQueryWhereBuilder');
 Lib::loadClass('SqlQueryWhereBuilder');
+Lib::loadClass('ParseOgcFilter');
 
 
 /**
 /**
  * API:
  * API:
@@ -240,195 +241,12 @@ if(V::get('DBG_DS', 0, $_GET) > 0){echo'<pre style="max-height:200px;overflow:au
 	}
 	}
 
 
 	public function _parseOgcFilter($ogcFilter) {
 	public function _parseOgcFilter($ogcFilter) {
-		$ogcFilterXmlString = <<<OGC_FILTER_XML_FILE
-<?xml version="1.0" encoding="UTF-8"?>
-<filter xmlns="https://biuro.biall-net.pl/SE/version-git/schema/filter.xsd"
-        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
-        xmlns:ogc="http://www.opengis.net/ogc">
-	{$ogcFilter}
-</filter>
-OGC_FILTER_XML_FILE;
-		$convertedGuiXml = $this->_convertGuiXmlToCmdList($ogcFilterXmlString);
-
-		DBG::_('DBG_DS_OGC', '>1', "convertedGuiXml(".strlen($convertedGuiXml).")", $convertedGuiXml, __CLASS__, __FUNCTION__, __LINE__);
-
-		$tags = array();
-		$parserXml = xml_parser_create();
-		xml_parser_set_option($parserXml, XML_OPTION_CASE_FOLDING, 0);
-		xml_parser_set_option($parserXml, XML_OPTION_SKIP_WHITE, 1);
-		if (0 == xml_parse_into_struct($parserXml, $convertedGuiXml, $tags)) {
-			throw new Exception("Parse Request xml error #" . __LINE__ . ": parse converted transaction failed");
-		}
-		xml_parser_free($parserXml);
-		if (empty($tags)) {
-			throw new Exception("Parse Request xml error #" . __LINE__ . ": parse converted transaction returns empty structure");
-		}
-
-		$queryWhereBuilder = new SqlQueryWhereBuilder();
-		foreach ($tags as $tag) {
-			switch ($tag['tag']) {
-				case 'filter': {// root tag
-				}
-					break;
-				case 'sql_filter_comparisonFieldToValue': {
-					$fieldName = V::get('fieldName', '', $tag['attributes']);
-					$comparisonSign = V::get('comparisonSign', '', $tag['attributes']);
-					$value = V::get('value', '', $tag['attributes']);
-					DBG::_('DBG_DS_OGC', '>3', "sql_filter_comparisonFieldToValue comparisonSign", $comparisonSign, __CLASS__, __FUNCTION__, __LINE__);
-					if ('like' == $comparisonSign) {
-						$wildCard = V::get('wildCard', '', $tag['attributes']);
-						$singleChar = V::get('singleChar', '', $tag['attributes']);
-						$escapeChar = V::get('escapeChar', '', $tag['attributes']);
-						// wildCard="*" singleChar="#" escapeChar="!" => sql: % _ \
-						// '*ORMA!*' => '%ORMA\*'
-						// TODO: first replace every escapeChar
-						$valLength = strlen($value);
-						$valCharsAllowReplace = array(); for ($i = 0; $i < $valLength; $i++) $valCharsAllowReplace[] = true;
-						{// escapeChar
-							$lastOffset = 0;
-							while (false !== ($pos = strpos($value, $escapeChar, $lastOffset))) {
-								DBG::_('DBG_DS_OGC', '>3', "sql_filter_comparisonFieldToValue like value({$value}) escapeChar({$escapeChar}) pos({$pos}) lastOffset({$lastOffset})", null, __CLASS__, __FUNCTION__, __LINE__);
-								$value[$pos] = '\\';
-								$valCharsAllowReplace[$pos] = false;
-								if ($pos + 1 < $valLength) $valCharsAllowReplace[$pos + 1] = false;
-								$lastOffset = $pos + 1;
-							}
-						}
-						{// singleChar
-							$lastOffset = 0;
-							while (false !== ($pos = strpos($value, $singleChar, $lastOffset))) {
-								DBG::_('DBG_DS_OGC', '>3', "sql_filter_comparisonFieldToValue like value({$value}) singleChar({$singleChar}) pos({$pos}) lastOffset({$lastOffset})", null, __CLASS__, __FUNCTION__, __LINE__);
-								if ($valCharsAllowReplace[$pos]) {
-									$value[$pos] = '_';
-									$valCharsAllowReplace[$pos] = false;
-								}
-								$lastOffset = $pos + 1;
-							}
-						}
-						{// wildCard
-							$lastOffset = 0;
-							while (false !== ($pos = strpos($value, $wildCard, $lastOffset))) {
-								DBG::_('DBG_DS_OGC', '>3', "sql_filter_comparisonFieldToValue like value({$value}) wildCard({$wildCard}) pos({$pos}) lastOffset({$lastOffset})", null, __CLASS__, __FUNCTION__, __LINE__);
-								if ($valCharsAllowReplace[$pos]) {
-									$value[$pos] = '%';
-									$valCharsAllowReplace[$pos] = false;
-								}
-								$lastOffset = $pos + 1;
-							}
-						}
-					}
-					DBG::_('DBG_DS_OGC', '>3', "sql_filter_comparisonFieldToValue value({$value})", null, __CLASS__, __FUNCTION__, __LINE__);
-					$queryWhereBuilder->addComparisonFieldToValue($fieldName, $comparisonSign, $value);
-				}
-					break;
-				case 'sql_filter_openBlock': {
-					$blockType = V::get('type', '', $tag['attributes']);
-					DBG::_('DBG_DS_OGC', '>2', "sql_filter_openBlock block Type {$blockType} attrs", json_encode($tag), __CLASS__, __FUNCTION__, __LINE__);
-					$queryWhereBuilder->openBlock($blockType);
-				}
-					break;
-				case 'sql_filter_closeBlock': {
-					$blockType = V::get('type', '', $tag['attributes']);
-					$queryWhereBuilder->closeBlock($blockType);
-				}
-					break;
-				case 'not_implemented_tag': {
-					$tagName = V::get('name', '', $tag['attributes']);
-					DBG::_('DBG_DS_OGC', '>1', "Not Implemented tag '{$tagName}'", $queryWhereBuilder, __CLASS__, __FUNCTION__, __LINE__);
-					throw new HttpException("Not Implemented tag '{$tagName}'", 501);
-				}
-					break;
-				default: {
-					DBG::_('DBG_DS_OGC', '>1', "TODO: tag {$tag['tag']}", $queryWhereBuilder, __CLASS__, __FUNCTION__, __LINE__);
-					throw new Exception("TODO: tag {$tag['tag']}");
-				}
-			}
-		}
-
-		$queryWhereBuilder->parseQueryWhere();
-		DBG::_('DBG_DS_OGC', '>1', "queryWhereBuilder", $queryWhereBuilder, __CLASS__, __FUNCTION__, __LINE__);
+		$parser = new ParseOgcFilter();
+		$parser->loadOgcFilter($ogcFilter);
+		$queryWhereBuilder = $parser->convertToSqlQueryWhereBuilder();
 		return $queryWhereBuilder->getQueryWhere('t');
 		return $queryWhereBuilder->getQueryWhere('t');
 	}
 	}
 
 
-	public function _convertGuiXmlToCmdList($ogcFilterXmlString) {
-		$convertOgcFilterXslString = <<<XSL_CONVERT_OGC_FILTER_TO_XML_TASK_LIST
-<?xml version="1.0" encoding="UTF-8"?>
-<xsl:stylesheet version="1.0"
-								xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
-								xmlns:filter="https://biuro.biall-net.pl/SE/version-git/schema/filter.xsd"
-								xmlns:ogc="http://www.opengis.net/ogc"
-								>
-	<xsl:output method="xml" omit-xml-declaration="yes" indent="no"/>
-
-	<xsl:template match="/">
-		<xsl:element name="filter">
-			<xsl:apply-templates select="filter:filter/ogc:Filter"/>
-		</xsl:element>
-	</xsl:template>
-
-	<xsl:template match="ogc:Filter">
-		<xsl:apply-templates/>
-	</xsl:template>
-
-	<xsl:template match="*">
-		<xsl:element name="not_implemented_tag">
-			<xsl:attribute name="name"><xsl:value-of select="name()"/></xsl:attribute>
-			<xsl:apply-templates/>
-		</xsl:element>
-	</xsl:template>
-
-	<xsl:template match="ogc:Or">
-		<xsl:element name="sql_filter_openBlock">
-			<xsl:attribute name="type"><xsl:value-of select="'or'" /></xsl:attribute>
-		</xsl:element>
-		<xsl:apply-templates/>
-		<xsl:element name="sql_filter_closeBlock">
-			<xsl:attribute name="type"><xsl:value-of select="'or'" /></xsl:attribute>
-		</xsl:element>
-	</xsl:template>
-
-	<xsl:template match="ogc:And">
-		<xsl:element name="sql_filter_openBlock">
-			<xsl:attribute name="type"><xsl:value-of select="'and'" /></xsl:attribute>
-		</xsl:element>
-		<xsl:apply-templates/>
-		<xsl:element name="sql_filter_closeBlock">
-			<xsl:attribute name="type"><xsl:value-of select="'and'" /></xsl:attribute>
-		</xsl:element>
-	</xsl:template>
-
-	<xsl:template match="ogc:PropertyIsEqualTo">
-		<xsl:element name="sql_filter_comparisonFieldToValue">
-			<xsl:attribute name="fieldName"><xsl:value-of select="ogc:PropertyName" /></xsl:attribute>
-			<xsl:attribute name="comparisonSign"><xsl:value-of select="'='" /></xsl:attribute>
-			<xsl:attribute name="value"><xsl:value-of select="ogc:Literal" /></xsl:attribute>
-		</xsl:element>
-	</xsl:template>
-
-	<xsl:template match="ogc:PropertyIsLike">
-		<xsl:element name="sql_filter_comparisonFieldToValue">
-			<xsl:attribute name="fieldName"><xsl:value-of select="ogc:PropertyName" /></xsl:attribute>
-			<xsl:attribute name="comparisonSign"><xsl:value-of select="'like'" /></xsl:attribute>
-			<xsl:attribute name="value"><xsl:value-of select="ogc:Literal" /></xsl:attribute>
-			<xsl:attribute name="wildCard"><xsl:value-of select="@wildCard" /></xsl:attribute>
-			<xsl:attribute name="singleChar"><xsl:value-of select="@singleChar" /></xsl:attribute>
-			<xsl:attribute name="escapeChar"><xsl:value-of select="@escapeChar" /></xsl:attribute>
-		</xsl:element>
-	</xsl:template>
-
-</xsl:stylesheet>
-
-XSL_CONVERT_OGC_FILTER_TO_XML_TASK_LIST;
-		$requestXml = new DOMDocument();
-		$requestXml->loadXml($ogcFilterXmlString);
-
-		$convertOgcFilterXsl = new DOMDocument();
-		$convertOgcFilterXsl->loadXml($convertOgcFilterXslString);
-		$proc = new XSLTProcessor();
-		$proc->importStylesheet($convertOgcFilterXsl);
-		return $proc->transformToXML($requestXml);
-	}
-
 	function _parseSpecialFilter($fltr, $value) {
 	function _parseSpecialFilter($fltr, $value) {
 		$sqlFltr = "";
 		$sqlFltr = "";
 
 

+ 160 - 0
SE/se-lib/ParseOgcFilter.php

@@ -0,0 +1,160 @@
+<?php
+
+/**
+ * @usage:
+		$parser = new ParseOgcFilter();
+		$parser->loadOgcFilter($ogcFilter);
+		$queryWhereBuilder = $parser->convertToSqlQueryWhereBuilder();
+		$query = $queryWhereBuilder->getQueryWhere('t');
+ *
+ */
+class ParseOgcFilter {
+
+	public $_ogcFilter = '';
+
+	public function __construct() {
+	}
+
+	public function loadOgcFilter($ogcFilter) {
+		// validate?
+		$this->_ogcFilter = $ogcFilter;
+	}
+
+	public function convertToSqlQueryWhereBuilder() {
+		$ogcFilterXmlString = <<<OGC_FILTER_XML_FILE
+<?xml version="1.0" encoding="UTF-8"?>
+<filter xmlns="https://biuro.biall-net.pl/SE/version-git/schema/filter.xsd"
+        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+        xmlns:ogc="http://www.opengis.net/ogc">
+	{$this->_ogcFilter}
+</filter>
+OGC_FILTER_XML_FILE;
+		$convertedGuiXml = $this->_convertOgcFilterToCmdList($ogcFilterXmlString);
+
+		DBG::_('DBG_DS_OGC', '>1', "convertedGuiXml(".strlen($convertedGuiXml).")", $convertedGuiXml, __CLASS__, __FUNCTION__, __LINE__);
+
+		$tags = array();
+		$parserXml = xml_parser_create();
+		xml_parser_set_option($parserXml, XML_OPTION_CASE_FOLDING, 0);
+		xml_parser_set_option($parserXml, XML_OPTION_SKIP_WHITE, 1);
+		if (0 == xml_parse_into_struct($parserXml, $convertedGuiXml, $tags)) {
+			throw new Exception("Parse Request xml error #" . __LINE__ . ": parse converted transaction failed");
+		}
+		xml_parser_free($parserXml);
+		if (empty($tags)) {
+			throw new Exception("Parse Request xml error #" . __LINE__ . ": parse converted transaction returns empty structure");
+		}
+
+		$queryWhereBuilder = new SqlQueryWhereBuilder();
+		foreach ($tags as $tag) {
+			switch ($tag['tag']) {
+				case 'filter': {// root tag
+				}
+					break;
+				case 'sql_filter_comparisonFieldToValue': {
+					$fieldName = V::get('fieldName', '', $tag['attributes']);
+					$comparisonSign = V::get('comparisonSign', '', $tag['attributes']);
+					$value = V::get('value', '', $tag['attributes']);
+					DBG::_('DBG_DS_OGC', '>3', "sql_filter_comparisonFieldToValue comparisonSign", $comparisonSign, __CLASS__, __FUNCTION__, __LINE__);
+					if ('like' == $comparisonSign) {
+						$wildCard = V::get('wildCard', '', $tag['attributes']);
+						$singleChar = V::get('singleChar', '', $tag['attributes']);
+						$escapeChar = V::get('escapeChar', '', $tag['attributes']);
+						// wildCard="*" singleChar="#" escapeChar="!" => sql: % _ \
+						// '*ORMA!*' => '%ORMA\*'
+						// TODO: first replace every escapeChar
+						$valLength = strlen($value);
+						$valCharsAllowReplace = array(); for ($i = 0; $i < $valLength; $i++) $valCharsAllowReplace[] = true;
+						{// escapeChar
+							$lastOffset = 0;
+							while (false !== ($pos = strpos($value, $escapeChar, $lastOffset))) {
+								DBG::_('DBG_DS_OGC', '>3', "sql_filter_comparisonFieldToValue like value({$value}) escapeChar({$escapeChar}) pos({$pos}) lastOffset({$lastOffset})", null, __CLASS__, __FUNCTION__, __LINE__);
+								$value[$pos] = '\\';
+								$valCharsAllowReplace[$pos] = false;
+								if ($pos + 1 < $valLength) $valCharsAllowReplace[$pos + 1] = false;
+								$lastOffset = $pos + 1;
+							}
+						}
+						{// singleChar
+							$lastOffset = 0;
+							while (false !== ($pos = strpos($value, $singleChar, $lastOffset))) {
+								DBG::_('DBG_DS_OGC', '>3', "sql_filter_comparisonFieldToValue like value({$value}) singleChar({$singleChar}) pos({$pos}) lastOffset({$lastOffset})", null, __CLASS__, __FUNCTION__, __LINE__);
+								if ($valCharsAllowReplace[$pos]) {
+									$value[$pos] = '_';
+									$valCharsAllowReplace[$pos] = false;
+								}
+								$lastOffset = $pos + 1;
+							}
+						}
+						{// wildCard
+							$lastOffset = 0;
+							while (false !== ($pos = strpos($value, $wildCard, $lastOffset))) {
+								DBG::_('DBG_DS_OGC', '>3', "sql_filter_comparisonFieldToValue like value({$value}) wildCard({$wildCard}) pos({$pos}) lastOffset({$lastOffset})", null, __CLASS__, __FUNCTION__, __LINE__);
+								if ($valCharsAllowReplace[$pos]) {
+									$value[$pos] = '%';
+									$valCharsAllowReplace[$pos] = false;
+								}
+								$lastOffset = $pos + 1;
+							}
+						}
+					}
+					DBG::_('DBG_DS_OGC', '>3', "sql_filter_comparisonFieldToValue value({$value})", null, __CLASS__, __FUNCTION__, __LINE__);
+					$queryWhereBuilder->addComparisonFieldToValue($fieldName, $comparisonSign, $value);
+				}
+					break;
+				case 'sql_filter_openBlock': {
+					$blockType = V::get('type', '', $tag['attributes']);
+					DBG::_('DBG_DS_OGC', '>2', "sql_filter_openBlock block Type {$blockType} attrs", json_encode($tag), __CLASS__, __FUNCTION__, __LINE__);
+					$queryWhereBuilder->openBlock($blockType);
+				}
+					break;
+				case 'sql_filter_closeBlock': {
+					$blockType = V::get('type', '', $tag['attributes']);
+					$queryWhereBuilder->closeBlock($blockType);
+				}
+					break;
+				case 'not_implemented_tag': {
+					$tagName = V::get('name', '', $tag['attributes']);
+					DBG::_('DBG_DS_OGC', '>1', "Not Implemented tag '{$tagName}'", $queryWhereBuilder, __CLASS__, __FUNCTION__, __LINE__);
+					throw new HttpException("Not Implemented tag '{$tagName}'", 501);
+				}
+					break;
+				default: {
+					DBG::_('DBG_DS_OGC', '>1', "TODO: tag {$tag['tag']}", $queryWhereBuilder, __CLASS__, __FUNCTION__, __LINE__);
+					throw new HttpException("TODO: tag {$tag['tag']}", 501);
+				}
+			}
+		}
+
+		$queryWhereBuilder->parseQueryWhere();
+		DBG::_('DBG_DS_OGC', '>1', "queryWhereBuilder", $queryWhereBuilder, __CLASS__, __FUNCTION__, __LINE__);
+		return $queryWhereBuilder;
+	}
+
+	public function _convertOgcFilterToCmdList($ogcFilterXmlString) {
+		$convertOgcFilterXslString = @file_get_contents(APP_PATH_SCHEMA . DS . 'wfs' . DS . 'convertOgcFilterToXmlTaskList.xsl');
+		if (false === $convertOgcFilterXslString) {
+			throw new HttpException("Cannot find file 'convertOgcFilter...'", 404);
+		} else if (empty($convertOgcFilterXslString)) {
+			throw new HttpException("Empty file 'convertOgcFilter...'", 404);
+		}
+
+		$requestXml = new DOMDocument();
+		$isFileCorrect = @$requestXml->loadXml($ogcFilterXmlString);
+		if (false === $isFileCorrect) {
+			throw new HttpException("Parse error for ogc filter", 400);
+		}
+		$convertOgcFilterXsl = new DOMDocument();
+		$isFileCorrect = @$convertOgcFilterXsl->loadXml($convertOgcFilterXslString);
+		if (false === $isFileCorrect) {
+			throw new HttpException("Parse error for file 'convertOgcFilter...'", 500);
+		}
+		$proc = new XSLTProcessor();
+		$isImported = $proc->importStylesheet($convertOgcFilterXsl);
+		if (false === $isImported) {
+			throw new HttpException("XSLT Parse error for import 'convertOgcFilter...'", 500);
+		}
+		return $proc->transformToXML($requestXml);
+	}
+
+}