|
|
@@ -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()
|