Przeglądaj źródła

exported GetFeature in wfs-data and updated recurse get nested obj

Piotr Labudda 8 lat temu
rodzic
commit
3185910ab5

+ 1 - 1
SE/se-lib/AclQueryFeatures.php

@@ -495,7 +495,7 @@ class AclQueryFeatures {
 			if ('ref:' === substr($xsdType, 0, 4) && empty($cols)) { // only xlink's
 				DBG::log("TODO: add remote xlink's '{$fieldName}' \$items[{$primaryKey}]");
 				$refTable = ACL::getRefTable($this->_acl->getNamespace(), $fieldName);
-				DBG::log($refTable, 'string', "TODO: add remote xlink's '{$fieldName}' \$items[{$primaryKey}] from refTable");
+				if (!$refTable) DBG::log("BUG: Missing refTable in add remote xlink's '{$fieldName}' \$items[{$primaryKey}]");
 				if ($refTable) {
 					$xlinks = DB::getPDO()->fetchAll("
 						select r.REMOTE_PRIMARY_KEY

+ 159 - 0
SE/se-lib/Api/Wfs/GetFeature.php

@@ -0,0 +1,159 @@
+<?php
+
+Lib::loadClass('Api_WfsGeomTypeConverter');
+
+class Api_Wfs_GetFeature {
+
+	// TODO: add $contextAcl and context xpath to check for special perms by contextAcl
+	public static function printXmlFeatureRecurse($xmlWriter, $acl, $item, $tagName, $attrs = [], $showAdvancedAttrs = false, $schemaCache = [], $printedFidLog = []) {
+		$dbgFid = V::get('fid', 0, $attrs);
+		if ($dbgFid) $printedFidLog[] = $dbgFid;
+		if(V::get('DBG_XML', '', $_GET))$xmlWriter->writeComment("DBG: printXmlFeatureRecurse... '{$tagName}'" . ( $dbgFid ? " fid='{$dbgFid}'" : "" )); // TODO: DBG
+		DBG::log($acl, 'array', "DBG: printXmlFeatureRecurse( ... {$tagName}, \$acl)" . ( $dbgFid ? " fid='{$dbgFid}'" : "" ));
+		DBG::log($item, 'array', "DBG: printXmlFeatureRecurse( ... {$tagName}, \$item)" . ( $dbgFid ? " fid='{$dbgFid}'" : "" ));
+		DBG::log([$attrs, $showAdvancedAttrs, array_keys($schemaCache), $printedFidLog], 'array', "DBG: printXmlFeatureRecurse( ... {$tagName}, \$attrs, \$showAdvancedAttrs, keys(\$schemaCache), \$printedFidLog)");
+		// $rootWfsNs = 'p5';
+		list($itemPrefix, $localName) = explode(':', $tagName);
+
+		if (1 === count($item) && !empty($item['xlink'])) {
+			// @example 'xlink' => 'https://biuro.biall-net.pl/wfs/default_db/CRM_PROCES#PROCES.857'
+			$xlink = $item['xlink'];
+			list($xlinkUrl, $xlinkFid) = explode('#', $xlink);
+
+			// } else if (1 == count($item[$fldName]) && !empty($item[$fldName][0]['xlink'])) {
+			// $xmlWriter->writeComment("TODO: xlinks for '{$fldName}'"); // TODO: DBG
+			DBG::log($item[$fldName], 'array', "TODO: xlinks for '{$tagName}'");
+			// $xlink = $item[$fldName][0]['xlink'];
+			// $xlinkParts = explode(':', $xlink);
+			// if (2 != count($xlinkParts)) throw new Exception("Error Processing Request - wrong xlink format for ".$acl->getName().".{$itemKey}/{$fldName}");
+			// $xlinkParts[0] = Api_WfsNs::getNsUri($xlinkParts[0]);
+			// $xlink = implode('#', $xlinkParts);
+			$xmlWriter->startElement($tagName);
+				foreach ($attrs as $name => $value) {
+					$xmlWriter->writeAttribute($name, $value);
+				}
+				if ($showAdvancedAttrs && !$acl->canReadObjectField($fldName, (object)$item)) {
+					$xmlWriter->writeAttribute("p5:allow_read", "false");
+				}
+				if ($showAdvancedAttrs && $acl->canWriteObjectField($fldName, (object)$item)) {
+					$xmlWriter->writeAttribute("p5:allow_write", "true");
+				}
+				$xmlWriter->writeAttribute('xlink:href', $xlink);
+			$xmlWriter->endElement();// {$itemPrefix}:{$fldName}
+			return;
+		}
+
+		$xmlWriter->startElement($tagName);
+		foreach ($attrs as $name => $value) {
+			$xmlWriter->writeAttribute($name, $value);
+		}
+
+		$fldList = $acl->getRealFieldListByIdZasob();
+		$geomFld = null;
+		foreach ($fldList as $fldName) {
+			if ($acl->isGeomField($fldName)) {
+				$geomFld = $fldName;
+			}
+		}
+
+		DBG::log($fldList, 'array', ">>> loop start fields(".count($fldList).")");
+		foreach ($fldList as $idZasob => $fldName) {
+			DBG::log(">>> loop {$idZasob} => {$fldName}...");
+			$fldType = $acl->getXsdFieldType($fldName);
+			DBG::log(">>> loop '{$fldName}' xsdType: '{$fldType}'");
+			if (!$acl->canReadObjectField($fldName, (object)$item)) if(V::get('DBG_XML', '', $_GET))$xmlWriter->writeComment("DBG: skip - !canReadObjectField('{$fldName}')"); // TODO: DBG
+			if (!$acl->canReadObjectField($fldName, (object)$item)) continue;
+			DBG::log(">>> loop '{$fldName}' can read...");
+
+			if ($geomFld != null && $fldName == $geomFld) {
+				$xmlWriter->startElement("{$itemPrefix}:{$fldName}");
+					if ($showAdvancedAttrs && !$acl->canReadObjectField($fldName, (object)$item)) {
+						$xmlWriter->writeAttribute("p5:allow_read", "false");
+					}
+					if ($showAdvancedAttrs && $acl->canWriteObjectField($fldName, (object)$item)) {
+						$xmlWriter->writeAttribute("p5:allow_write", "true");
+					}
+					(new Api_WfsGeomTypeConverter())->createGmlFromWkt_xmlWriter($item[$fldName], $xmlWriter);
+				$xmlWriter->endElement();// {$itemPrefix}:{$fldName}
+			} else if (is_array($item[$fldName])) {// TODO: by struct - REF field
+				DBG::log($item[$fldName], 'array', ">>> loop({$itemKey}) REF item[{$itemKey}][{$fldName}]");
+				if (empty($item[$fldName])) { // SKIP empty fields
+					if(V::get('DBG_XML', '', $_GET))$xmlWriter->writeComment("DBG: skip empty field '{$fldName}'"); // TODO: DBG
+					// $xmlWriter->h($fldName);
+				} else {
+					if(V::get('DBG_XML', '', $_GET))$xmlWriter->writeComment("DBG: TODO: array field... '{$fldName}'"); // TODO: DBG
+					// $xmlWriter->writeComment("TODO: ".$acl->getName().".{$itemKey}/{$fldName} ...");
+					$fieldNs = str_replace(['__x3A__', ':'], '/', $fldName); // substr($xsdType, 4));
+					if (!array_key_exists($fieldNs, $schemaCache)) {
+						DBG::log($schemaCache, 'array', "Error Processing Request - field is not ref or missing acl ".$acl->getName().".{$itemKey}/{$fldName}");
+						if(V::get('DBG_XML', '', $_GET))$xmlWriter->writeComment("Error Processing Request - field is not ref or missing acl ".$acl->getName().".{$itemKey}/{$fldName}");
+					} else {
+						DBG::log($schemaCache[$fieldNs], 'array', "TODO: xxxxxxx ".$acl->getName().".{$itemKey}/{$fldName}");
+						$childAcl = Core_AclHelper::getAclByNamespace($schemaCache[$fieldNs]['namespace'], false, $schemaCache[$fieldNs]);
+						$childName = $schemaCache[$fieldNs]['name'];
+						foreach ($item[$fldName] as $childItem) {
+							$childPK = V::get($childAcl->getPrimaryKeyField(), '', $childItem);
+							self::printXmlFeatureRecurse($xmlWriter, $childAcl, $childItem, $fldName, ($childPK) ? [ 'fid' => "{$childName}.{$childPK}" ] : [], $showAdvancedAttrs, $schemaCache, $printedFidLog);
+						}
+						// foreach ($item[$fldName] as $refItem) {
+						// 	DBG::log($refItem, 'array', "\$refItem fld({$fldName})");
+						// 	if (1 == count($refItem) && !empty($refItem['xlink'])) {
+						// 		$xmlWriter->startElement($schemaCache[$fieldNs]['typeName']);
+						// 		$xmlWriter->writeAttribute("xlink:href", $refItem['xlink']);
+						// 		$xmlWriter->endElement();
+						// 	} else {
+						// 		$xmlWriter->writeComment("DBG: array field ref ... '{$fldName}'"); // TODO: DBG
+						// 		$xmlWriter->startElement($schemaCache[$fieldNs]['typeName']);
+						// 		foreach ($schemaCache[$fieldNs]['field'] as $field) {
+						// 			if (array_key_exists($field['fieldNamespace'], $refItem)) {
+						// 				$xmlWriter->writeComment("REF field ({$field['fieldNamespace']}) value({$refItem[$field['fieldNamespace']]}) TODO: get xsdType - TODO: recurse");
+						// 				DBG::log($refItem[$field['fieldNamespace']], 'array', "REF field ({$field['fieldNamespace']}) TODO: get xsdType - TODO: recurse");
+						// 				if (false !== strpos($field['fieldNamespace'], ':')) { // is ref - TODO: better check by xsdType
+						// 					$xmlWriter->startElement($field['fieldNamespace']);
+						// 					$xmlWriter->writeComment("TODO: recurse ...");
+						// 					// $xmlWriter->text($refItem[$field['fieldNamespace']]);
+						// 					$xmlWriter->endElement();
+						// 				} else {
+						// 					$xmlWriter->startElement("{$schemaCache[$fieldNs]['nsPrefix']}:{$field['fieldNamespace']}");
+						// 					$xmlWriter->text($refItem[$field['fieldNamespace']]);
+						// 					$xmlWriter->endElement();
+						// 				}
+						// 			}
+						// 		}
+						// 		$xmlWriter->endElement();
+						// 	}
+						// }
+					}
+				}
+			} else if ('xsd:base64Binary' === $acl->getXsdFieldType($fldName)) {
+				if (empty($item[$fldName]) && '0' !== $item[$fldName]) continue;
+				$xmlWriter->startElement("{$itemPrefix}:{$fldName}");
+					if ($showAdvancedAttrs && !$acl->canReadObjectField($fldName, (object)$item)) {
+						$xmlWriter->writeAttribute("p5:allow_read", "false");
+					}
+					if ($showAdvancedAttrs && $acl->canWriteObjectField($fldName, (object)$item)) {
+						$xmlWriter->writeAttribute("p5:allow_write", "true");
+					}
+					$xmlWriter->text(base64_encode($item[$fldName]));
+				$xmlWriter->endElement();// {$itemPrefix}:{$fldName}
+			} else {
+				$value = str_replace('&', '&amp;', $item[$fldName]);
+				if (empty($value) && '0' !== $value) {
+					continue;
+				} else {
+					$xmlWriter->startElement("{$itemPrefix}:{$fldName}");
+						if ($showAdvancedAttrs && !$acl->canReadObjectField($fldName, (object)$item)) {
+							$xmlWriter->writeAttribute("p5:allow_read", "false");
+						}
+						if ($showAdvancedAttrs && $acl->canWriteObjectField($fldName, (object)$item)) {
+							$xmlWriter->writeAttribute("p5:allow_write", "true");
+						}
+						$xmlWriter->text($value);
+					$xmlWriter->endElement();// {$itemPrefix}:{$fldName}
+				}
+			}
+		}
+		$xmlWriter->endElement();
+	}
+
+}

+ 12 - 129
SE/se-lib/Api/WfsDataServer.php

@@ -108,7 +108,6 @@ class Api_WfsDataServer extends Api_WfsServerBase {
 		DBG::log("typeName({$args['xsd:type']})");
 		$acl = $this->getAclFromTypeName($args['xsd:type']);
 		DBG::log([ 'msg'=>"typeName({$args['xsd:type']}) - acl(".get_class($acl).")", '$acl'=>$acl ]);
-		$fldList = $this->_getFieldListFromAcl($acl);
 
 		$baseNsUri = Api_WfsNs::getBaseWfsUri();
 		$rootWfsNs = 'p5';
@@ -117,16 +116,6 @@ class Api_WfsDataServer extends Api_WfsServerBase {
 		$wfsNsUri = "{$baseNsUri}/" . ('p5_' == substr($args['typePrefix'], 0, 3)) ? substr($args['typePrefix'], 3) : $args['typePrefix'];
 		$featureTypeUri = $this->getBaseUri() . "?SERVICE=WFS&VERSION=1.0.0&TYPENAME={$args['xsd:type']}&REQUEST=DescribeFeatureType";
 
-		// get BBox from geom_field (only one geom fld is allowed)
-		$geomFld = null;
-		{
-			foreach ($fldList as $fldName) {
-				if ($acl->isGeomField($fldName)) {
-					$geomFld = $fldName;
-				}
-			}
-		}
-
 		DBG::log("ogcFilter(" . strlen($args['ogc:filter']) . "): {$args['ogc:filter']}");
 		$searchParams = array();
 		$searchParams['limit'] = $args['limit'];
@@ -168,7 +157,6 @@ class Api_WfsDataServer extends Api_WfsServerBase {
 		DBG::log("typeName({$args['xsd:type']})");
 		$acl = $this->getAclFromTypeName($args['xsd:type']);
 		DBG::log([ 'msg'=>"typeName({$args['xsd:type']}) - acl(".get_class($acl).")", '$acl'=>$acl ]);
-		$fldList = $this->_getFieldListFromAcl($acl);
 
 		$baseNsUri = Api_WfsNs::getBaseWfsUri();
 		$rootWfsNs = 'p5';
@@ -177,16 +165,6 @@ class Api_WfsDataServer extends Api_WfsServerBase {
 		$wfsNsUri = "{$baseNsUri}/" . str_replace('__x3A__', '/', ('p5_' === substr($args['typePrefix'], 0, 3) ? substr($args['typePrefix'], 3) : $args['typePrefix']));
 		$featureTypeUri = $this->getBaseUri() . "?SERVICE=WFS&VERSION=1.0.0&TYPENAME={$args['xsd:type']}&REQUEST=DescribeFeatureType";
 
-		// get BBox from geom_field (only one geom fld is allowed)
-		$geomFld = null;
-		{
-			foreach ($fldList as $fldName) {
-				if ($acl->isGeomField($fldName)) {
-					$geomFld = $fldName;
-				}
-			}
-		}
-
 		DBG::log("ogcFilter(" . strlen($args['ogc:filter']) . "): {$args['ogc:filter']}");
 		$searchParams = array();
 		$searchParams['limit'] = $args['limit'];
@@ -275,6 +253,7 @@ class Api_WfsDataServer extends Api_WfsServerBase {
 				}
 			}
 			DBG::log($contextFieldList, 'array', "\$contextFieldList");
+			DBG::log(array_keys($schemaCache), 'array', "\$schemaCache keys");
 
 			$searchParams['cols'] = $contextFieldList;
 		} catch (Exception $e) {
@@ -282,11 +261,10 @@ class Api_WfsDataServer extends Api_WfsServerBase {
 			throw $e;
 		}
 
-		DBG::log([ 'msg'=>'getItems - $searchParams', '$searchParams'=>$searchParams ]);
-		if($DBG){echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;">get_total (F.' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r($jsonData->total);echo'</pre>';}
+		DBG::log($searchParams, 'string', 'getItems - $searchParams');
 		$queryFeatures = $acl->buildQuery($searchParams);
 		$items = $queryFeatures->getItems();
-		DBG::log([ 'msg'=>'getItems - $items', '$items'=>$items ]);
+		DBG::log($items, 'array', 'getItems - $items');
 
 
 		header('Content-type: application/xml; charset=utf-8');
@@ -327,110 +305,15 @@ class Api_WfsDataServer extends Api_WfsServerBase {
 			if (!empty($geomFld)) DBG::log(['msg'=>"item[{$itemKey}] ({$geomFld})isEmpty(".empty($item[$geomFld])."):", '$item['.$geomFld.']'=>$item[$geomFld]]);
 			DBG::log([ 'msg'=>">>> loop({$itemKey})", '$item'=>$item ]);
 			$xmlWriter->startElement('gml:featureMember');
-				$xmlWriter->startElement("{$wfsNs}:{$type}");
-					$xmlWriter->writeAttribute('fid', "{$type}.{$itemKey}");
-					if (!$simple) $xmlWriter->writeAttribute("{$rootWfsNs}:web_link", Request::getPathUri() . "index.php?_route=ViewTableAjax&namespace=" . $acl->getNamespace() . "#EDIT/{$itemKey}");
-					foreach ($fldList as $idZasob => $fldName) {
-						if(V::get('DBG_LOOP','',$_GET))DBG::log([ 'msg'=>">>> loop({$itemKey}) item({$item['ID']}) fld({$fldName})", '$item'=>$item[$fldName] ]);
-						$fldType = $acl->getXsdFieldType($fldName);
-						if (!$acl->canReadObjectField($fldName, (object)$item)) continue;
-
-						if ($geomFld != null && $fldName == $geomFld) {
-							$xmlWriter->startElement("{$wfsNs}:{$fldName}");
-								if (!$simple && !$acl->canReadObjectField($fldName, (object)$item)) {
-									$xmlWriter->writeAttribute("{$rootWfsNs}:allow_read", "false");
-								}
-								if (!$simple && $acl->canWriteObjectField($fldName, (object)$item)) {
-									$xmlWriter->writeAttribute("{$rootWfsNs}:allow_write", "true");
-								}
-								$this->_typeConverter->createGmlFromWkt_xmlWriter($item[$fldName], $xmlWriter);
-							$xmlWriter->endElement();// {$wfsNs}:{$fldName}
-						} else if (is_array($item[$fldName])) {// TODO: by struct - REF field
-							DBG::log([ 'msg'=>">>> loop({$itemKey}) REF item[{$itemKey}][{$fldName}]", '$item'=>$item[$fldName] ]);
-							$xmlWriter->writeComment("DBG: array field... '{$fldName}'"); // TODO: DBG
-							if (empty($item[$fldName])) {
-								$xmlWriter->h($fldName);
-							// } else if (1 == count($item[$fldName]) && !empty($item[$fldName][0]['xlink'])) {
-							// 	$xlink = $item[$fldName][0]['xlink'];
-							// 	$xlinkParts = explode(':', $xlink);
-							// 	if (2 != count($xlinkParts)) throw new Exception("Error Processing Request - wrong xlink format for ".$acl->getName().".{$itemKey}/{$fldName}");
-							// 	$xlinkParts[0] = Api_WfsNs::getNsUri($xlinkParts[0]);
-							// 	$xlink = implode('#', $xlinkParts);
-							// 	$xmlWriter->startElement("{$wfsNs}:{$fldName}");
-							// 		if (!$simple && !$acl->canReadObjectField($fldName, (object)$item)) {
-							// 			$xmlWriter->writeAttribute("{$rootWfsNs}:allow_read", "false");
-							// 		}
-							// 		if (!$simple && $acl->canWriteObjectField($fldName, (object)$item)) {
-							// 			$xmlWriter->writeAttribute("{$rootWfsNs}:allow_write", "true");
-							// 		}
-							// 		$xmlWriter->writeAttribute('xlink:href', $xlink);
-							// 	$xmlWriter->endElement();// {$wfsNs}:{$fldName}
-							} else {
-								// $xmlWriter->writeComment("TODO: ".$acl->getName().".{$itemKey}/{$fldName} ...");
-								$fieldNs = str_replace(['__x3A__', ':'], '/', $fldName); // substr($xsdType, 4));
-								if (!array_key_exists($fieldNs, $schemaCache)) {
-									DBG::log($schemaCache, 'array', "Error Processing Request - field is not ref ".$acl->getName().".{$itemKey}/{$fldName}");
-									$xmlWriter->writeComment("Error Processing Request - field is not ref ".$acl->getName().".{$itemKey}/{$fldName}");
-								} else {
-									foreach ($item[$fldName] as $refItem) {
-										DBG::log($refItem, 'array', "\$refItem fld({$fldName})");
-										if (1 == count($refItem) && !empty($refItem['xlink'])) {
-											$xmlWriter->startElement($schemaCache[$fieldNs]['typeName']);
-											$xmlWriter->writeAttribute("xlink:href", $refItem['xlink']);
-											$xmlWriter->endElement();
-										} else {
-											$xmlWriter->writeComment("DBG: array field ref ... '{$fldName}'"); // TODO: DBG
-											$xmlWriter->startElement($schemaCache[$fieldNs]['typeName']);
-											foreach ($schemaCache[$fieldNs]['field'] as $field) {
-												if (array_key_exists($field['fieldNamespace'], $refItem)) {
-													$xmlWriter->writeComment("REF field ({$field['fieldNamespace']}) value({$refItem[$field['fieldNamespace']]}) TODO: get xsdType - TODO: recurse");
-													DBG::log($refItem[$field['fieldNamespace']], 'array', "REF field ({$field['fieldNamespace']}) TODO: get xsdType - TODO: recurse");
-													if (false !== strpos($field['fieldNamespace'], ':')) { // is ref - TODO: better check by xsdType
-														$xmlWriter->startElement($field['fieldNamespace']);
-														$xmlWriter->writeComment("TODO: recurse ...");
-														// $xmlWriter->text($refItem[$field['fieldNamespace']]);
-														$xmlWriter->endElement();
-													} else {
-														$xmlWriter->startElement("{$schemaCache[$fieldNs]['nsPrefix']}:{$field['fieldNamespace']}");
-														$xmlWriter->text($refItem[$field['fieldNamespace']]);
-														$xmlWriter->endElement();
-													}
-												}
-											}
-											$xmlWriter->endElement();
-										}
-									}
-								}
-							}
-						} else if ('xsd:base64Binary' === $acl->getXsdFieldType($fldName)) {
-							if (empty($item[$fldName]) && '0' !== $item[$fldName]) continue;
-							$xmlWriter->startElement("{$wfsNs}:{$fldName}");
-								if (!$simple && !$acl->canReadObjectField($fldName, (object)$item)) {
-									$xmlWriter->writeAttribute("{$rootWfsNs}:allow_read", "false");
-								}
-								if (!$simple && $acl->canWriteObjectField($fldName, (object)$item)) {
-									$xmlWriter->writeAttribute("{$rootWfsNs}:allow_write", "true");
-								}
-								$xmlWriter->text(base64_encode($item[$fldName]));
-							$xmlWriter->endElement();// {$wfsNs}:{$fldName}
-						} else {
-							$value = str_replace('&', '&amp;', $item[$fldName]);
-							if (empty($value) && '0' !== $value) {
-								continue;
-							} else {
-								$xmlWriter->startElement("{$wfsNs}:{$fldName}");
-									if (!$simple && !$acl->canReadObjectField($fldName, (object)$item)) {
-										$xmlWriter->writeAttribute("{$rootWfsNs}:allow_read", "false");
-									}
-									if (!$simple && $acl->canWriteObjectField($fldName, (object)$item)) {
-										$xmlWriter->writeAttribute("{$rootWfsNs}:allow_write", "true");
-									}
-									$xmlWriter->text($value);
-								$xmlWriter->endElement();// {$wfsNs}:{$fldName}
-							}
-						}
-					}
-				$xmlWriter->endElement();// {$wfsNs}:{$type}
+			Lib::loadClass('Api_Wfs_GetFeature');
+			Api_Wfs_GetFeature::printXmlFeatureRecurse($xmlWriter, $acl, $item, $tagName = "{$wfsNs}:{$type}", array_merge(
+				[
+					'fid' => "{$type}.{$itemKey}",
+				],
+				(!$simple)
+				?	[ "{$rootWfsNs}:web_link" => Request::getPathUri() . "index.php?_route=ViewTableAjax&namespace=" . $acl->getNamespace() . "#EDIT/{$itemKey}" ]
+				:	[]
+			), $showAdvancedAttrs = !$simple, $schemaCache);
 			$xmlWriter->endElement();// gml:featureMember
 		}
 		$xmlWriter->endElement();// wfs:FeatureCollection