Jelajahi Sumber

added skip features as xlink to query features

Piotr Labudda 8 tahun lalu
induk
melakukan
eb2c28d2e0
1 mengubah file dengan 43 tambahan dan 3 penghapusan
  1. 43 3
      SE/se-lib/AclQueryFeatures.php

+ 43 - 3
SE/se-lib/AclQueryFeatures.php

@@ -24,6 +24,7 @@ class AclQueryFeatures {
 	public $_selectRemote; // TODO: ...
 	public $_dbgExecTime;
 	public $_instanceID;
+	public $_foundFeatures;
 
 	public function __construct($acl, $params, $legacyMode = false) {
 		$this->_acl = $acl;
@@ -34,6 +35,13 @@ class AclQueryFeatures {
 		// TODO: _legacyMode = ($from instanceof simple schema or another programmed objects)
 		$this->_selectLocalFields = null;
 		$this->_selectRemote = null;
+		$this->_foundFeatures = [];
+		// 'skipFeaturesAsXlink' => $this->_foundFeatures
+		if (array_key_exists('skipFeaturesAsXlink', $this->_params)) {
+			$this->_foundFeatures = V::get('skipFeaturesAsXlink', [], $this->_params, 'array');
+			unset($this->_params['skipFeaturesAsXlink']);
+		}
+
 
 		$DBG_LOG_TO_FILE = true; // TODO: read from ENV or REQUEST
 		if ($DBG_LOG_TO_FILE) {
@@ -580,6 +588,12 @@ class AclQueryFeatures {
 	}
 
 	public function fetchRowsRefs($rows) {
+		$pkField = $this->_acl->getPrimaryKeyField();
+		$namespace = $this->_acl->getNamespace();
+		$this->_foundFeatures = array_merge($this->_foundFeatures, array_map(function ($row) use ($namespace, $pkField) {
+			return "{$namespace}." . V::get($pkField, '', $row);
+		}, $rows));
+		DBG::log($this->_foundFeatures, 'array', "_foundFeatures");
 		return array_map([ $this, 'fetchRowRefs' ], $rows);
 		// if (!empty($rows) && !empty($rows[0])) {
 		//	 $rows[0]['default_db__x3A__CRM_WSKAZNIK:CRM_WSKAZNIK'] = [
@@ -634,18 +648,36 @@ class AclQueryFeatures {
 					DBG::log($row[$fieldName], 'array', "remote xlinks for \$items[{$primaryKey}][{$fieldName}]");
 				}
 			} else if ('ref:' === substr($xsdType, 0, 4) && !empty($cols)) {
-				$items = ACL::getAclByTypeName($fieldName)->buildQuery([
+				$refAcl = ACL::getAclByTypeName($fieldName);
+				$items = $refAcl->buildQuery([
 					'cols' => $cols,
 					'__backRef' => [
 						'namespace' => $this->_acl->getNamespace(),
 						'primaryKey' => $primaryKey,
 						'fieldName' => $fieldName,
-					]
+					],
+					'skipFeaturesAsXlink' => $this->_foundFeatures
 					// TODO: add $refLimit + 1
 				])->getItems();
 				// TODO: if (count($items) > $refLimit) // TODO: add item for GUI - has more data + wfs link to fetch more (offset)
 				DBG::log($items, 'array', "add remote items '{$fieldName}' \$items");
-				$row[$fieldName] = $items;
+				$refNs = $refAcl->getNamespace();
+				$refPk = $refAcl->getPrimaryKeyField();
+				$this__hasFeatureId = [ $this, 'hasFeatureId' ];
+				$this__addFeatureId = [ $this, 'addFeatureId' ];
+				$row[$fieldName] = array_map(function ($item) use ($fieldName, $refNs, $refPk, $this__hasFeatureId, $this__addFeatureId) {
+					$pk = V::get($refPk, '', $item);
+					$featureId = "{$refNs}.{$pk}";
+					if (!$this__hasFeatureId($featureId)) {
+						$this__addFeatureId($featureId);
+						return $item;
+					} else {
+						$ns = Core_AclHelper::parseTypeName($fieldName);
+						return [
+							'xlink' => "{$ns['url']}#{$ns['name']}.{$pk}",
+						];
+					}
+				}, $items);
 			} else { // TODO: field is not ref
 				DBG::log($items, 'array', "NotImplemented - add remote items for non ref field \$items[{$primaryKey}][{$fieldName}]?");
 			}
@@ -653,6 +685,14 @@ class AclQueryFeatures {
 		return $row;
 	}
 
+	public function hasFeatureId($featureId) {
+		return in_array($featureId, $this->_foundFeatures);
+	}
+	public function addFeatureId($featureId) {
+		$this->_foundFeatures[] = $featureId;
+		DBG::log($this->_foundFeatures, 'array', "TODO: addFeatureId({$featureId})");
+	}
+
 	public function getAclSqlPrimaryKeyField() {
 		return ($this->_acl instanceof Core_AclBase)
 			? $this->_acl->getSqlPrimaryKeyField()