{$message}
EOT;
self::output($xml);
die();
}
public function objectStructureAction($namespace) { // objectStructAction
Lib::loadClass('SchemaFactory');
Lib::loadClass('ACL');
try {
error_log('objectStructureAction for '.$namespace);
if (empty($namespace)) throw new Exception("Missing param namespace");
$item = SchemaFactory::loadDefaultObject('SystemObject')->getItem($namespace, [ 'propertyName' => '*,field' ]);
$return=$this->objectStructView($item);
return $return;
} catch (Exception $e) {
//error_log('danger', "Error #" . $e->getCode() . "|" . $e->getLine() . ": " . $e->getMessage());
DBG::log($e);
}
}
//input param $item['namespace']='default_db/BI_audit_CEIDG_powiazania/BI_audit_CEIDG_powiazania'
public function objectStructView($item) {
$namespace = $item['namespace'];
$thisGetLink = [ $this, 'getLink' ];
$getBackRefList=ACL::getBackRefList($item['namespace']);
foreach($getBackRefList as $ind=>$backref) {
$exploded_ns = explode('/', $backref['namespace']);
$return['backrefs'][]=$exploded_ns[1].'__x3A__'.$exploded_ns[2].':'.$exploded_ns[3];
}
foreach($item['field'] as $ind=>$refs) {
$return['refs'] []=$refs['fieldNamespace'];
$return['refs__rootTableName'][]=$refs['_rootTableName'];
$return['refs__objectNamespace'][]=$refs['objectNamespace'];
}
$return['table']=$item['name'];
$return['primaryKey']=$item['primaryKey'];
//print_r($this->BaseStruct);
return $return;
}
private function addChild($node, $name, $value = null) {
$child = $this->dom->createElement($name, $value);
$node->appendChild($child);
return $child;
}
private function addAttribute($node, $name, $value) {
$attr = $this->dom->createAttribute($name);
$attr->value = $value;
$node->appendChild($attr);
}
public function setRootNode($node) {
$this->_wfsRootNode = $node;
}
public function addRootXmlnsTablePrefix($typeName) {
if (!$this->_wfsRootNode) throw new Exception("Root node not set");
list($nsPrefix, $nsBaseName) = explode(':', $typeName);
list($nsSourceName, $nsBaseTable) = explode('__x3A__', $nsPrefix);
if (!in_array($nsBaseTable, $this->_xmlnsTablePrefix)) {
$this->_xmlnsTablePrefix[] = $nsBaseTable;
$this->addAttribute($this->_wfsRootNode, "xmlns:default_db__x3A__{$nsBaseTable}", "https://biuro.biall-net.pl/wfs/default_db/{$nsBaseTable}");
}
}
private function relationName($ID) {
if (!isset($this->relations[$ID])) {
$query = "select `RELATION` from `BI_audit_ALL_ref_RELATIONS` where `ID` & {$ID} order by `ID`";
$result = DB::getPDO()->fetchAll($query);
$rels = array_map('reset', $result);
$this->relations[$ID] = implode(", ", $rels);
}
return $this->relations[$ID];
}
private function findRelations_base($node, $ID, $resolveDepth, $relation = null, $BaseStruct=null,$table=null) {
if (in_array($ID, $this->path)) return;
$this->path[] = $ID;
error_log('#208 findRelations_base passing');
foreach($BaseStruct['refs__objectNamespace'] as $ind=>$refs){
$getRefTable=ACL::getRefTable('default_db/'.$table.'/'.$table,$refs);
$query = "select `REMOTE_PRIMARY_KEY` from `".$getRefTable."` where `PRIMARY_KEY` = {$ID}";
error_log('#114 findRelations_base passing query '.$query);
if (!($row = DB::getPDO()->fetchFirst($query))) {
} else {
/*{
$this->objectStructureAction('default_db/BI_audit_CEIDG_pelnomocnicy/BI_audit_CEIDG_pelnomocnicy');
self::throwServiceException("Błąd danych #102 findRelations_base");
}*/
$this->addRootXmlnsTablePrefix("default_db__x3A__{$BaseStruct['_rootTableName'][$ind]}:{$BaseStruct['_rootTableName'][$ind]}"); // if (!in_array($BaseStruct['_rootTableName'][$ind], $this->tablesUsed)) $this->tablesUsed[] = $BaseStruct['_rootTableName'][$ind];
}
if ($resolveDepth) {
$feature = $this->addChild($node, $BaseStruct['refs'][$ind]);
$this->addAttribute($feature, 'fid', $BaseStruct['_rootTableName'][$ind].$row['REMOTE_PRIMARY_KEY']);
$this->addChild($feature, "default_db__x3A__".$BaseStruct['_rootTableName'][$ind].":ID", $row['REMOTE_PRIMARY_KEY']);
if ($relation) $this->addChild($feature, "relation_from", $this->relationName($relation));
//$query = "select `ID2` from `BI_audit_ALL_ref` where `ID1` = {$ID}";
//$where = $relation ? "and ({$relation} & `RELATION_ID`) != {$relation}" : "";
$RefBaseStruct=$this->objectStructureAction($BaseStruct['objectNamespace'][$ind]);
$query = "select `".$RefBaseStruct['primaryKey']."` from `".$RefBaseStruct['table']."` where `".$RefBaseStruct['primaryKey']."` = ".$row['REMOTE_PRIMARY_KEY'] ;
$result = DB::getPDO()->fetchAll($query);
foreach ($result as $row) $this->findRelations($feature, $row['REMOTE_PRIMARY_KEY'], $resolveDepth - 1, null,$BaseStruct['table'],$RefBaseStruct['table']);
} else {
$xlink = $this->addChild($node, $BaseStruct['refs'][$ind]);
$this->addAttribute($xlink, 'xlink:href', "https://biuro.biall-net.pl/wfs/default_db/{$RefBaseStruct['table']}?BI_audit_ALL_ref_RELATIONS={$relation}#{$RefBaseStruct['table']}.{$row['REMOTE_PRIMARY_KEY']}");
}
array_pop($this->path);
}
}
private function findRelations($node, $ID, $resolveDepth, $relation = null, $BaseTableFrom = null, $BaseTableTo = null) {
if (in_array($ID, $this->path)) return;
$this->path[] = $ID;
if (!empty($BaseTableFrom) && !empty($BaseTableTo)) {
$query = "select `REMOTE_TABLE`, `REMOTE_ID` from `BI_audit_ALL` where `ID` = {$ID} and `REMOTE_TABLE`='".$BaseTableTo."'"; //todo nie wiem czy nie na odwrot $BaseTableTo
} else {
$query = "select `REMOTE_TABLE`, `REMOTE_ID` from `BI_audit_ALL` where `ID` = {$ID}";
}
if (!($row = DB::getPDO()->fetchFirst($query))) {
if (empty($BaseTableFrom) && empty($BaseTableTo)) {
self::throwServiceException("Błąd danych z BaseStruct/findRelations #161 ");
}
//$this->objectStructureAction('default_db/BI_audit_CEIDG_pelnomocnicy/BI_audit_CEIDG_pelnomocnicy');
// self::throwServiceException("Błąd danych findRelations #130");
$this->BaseStruct=$this->objectStructureAction("default_db/".$BaseTableTo."/".$BaseTableTo );
$query = "select `".$this->BaseStruct['primaryKey']."` from `".$BaseTableTo."` where ".$this->BaseStruct['primaryKey']." = {$ID}";
if (!($ID = DB::getPDO()->fetchValue($query))) {
self::throwServiceException("Błąd danych z BaseStruct/findRelations #162 ");
}
$this->addRootXmlnsTablePrefix("default_db__x3A__{$BaseTableTo}:{$BaseTableTo}"); // if (!in_array($BaseTableTo, $this->tablesUsed)) $this->tablesUsed[] = $BaseTableTo;
if ($resolveDepth) {
$feature = $this->addChild($node, "default_db__x3A__{$row['REMOTE_TABLE']}:{$row['REMOTE_TABLE']}");
$this->addAttribute($feature, 'fid', "{$row['REMOTE_TABLE']}.{$row['REMOTE_ID']}");
$this->addChild($feature, "default_db__x3A__{$row['REMOTE_TABLE']}:ID", $row['REMOTE_ID']);
if ($relation) $this->addChild($feature, "relation_from", $this->relationName($relation));
//$query = "select `ID2` from `BI_audit_ALL_ref` where `ID1` = {$ID}";
//$where = $relation ? "and ({$relation} & `RELATION_ID`) != {$relation}" : "";
//$query = "select `ID2`, `RELATION_ID` from `BI_audit_ALL_ref` where `ID1` = {$ID} {$where}";
//$result = DB::getPDO()->fetchAll($query);
//foreach ($result as $row)
// $this->findRelations($feature, $row['ID2'], $resolveDepth - 1, $row['RELATION_ID'],);
findRelations_base($node, $ID, $resolveDepth, $relation = null, $this->BaseStruct,$BaseTableTo) ;
} else {
$xlink = $this->addChild($node, "default_db__x3A__{$BaseTableTo}:{$BaseTableTo}");
$this->addAttribute($xlink, 'xlink:href', "https://biuro.biall-net.pl/wfs/default_db/".$BaseTableTo."?BI_audit_ALL_ref_RELATIONS={$BaseTableTo}#{$BaseTableTo}.{$row[$this->BaseStruct['primaryKey']]}");
}
array_pop($this->path);
} else {
// $row = [ 'REMOTE_TABLE' => BI_audit_KRS_person, 'REMOTE_ID' => 366074 ]
$this->addRootXmlnsTablePrefix("default_db__x3A__{$row['REMOTE_TABLE']}:{$row['REMOTE_TABLE']}"); // if (!in_array($row['REMOTE_TABLE'], $this->tablesUsed)) $this->tablesUsed[] = $row['REMOTE_TABLE'];
if ($resolveDepth) {
$featureNode = $this->addChild($node, "default_db__x3A__{$row['REMOTE_TABLE']}:{$row['REMOTE_TABLE']}");
$this->addAttribute($featureNode, 'fid', "{$row['REMOTE_TABLE']}.{$row['REMOTE_ID']}");
$this->addChild($featureNode, "default_db__x3A__{$row['REMOTE_TABLE']}:ID", $row['REMOTE_ID']);
if ($relation) $this->addChild($featureNode, "relation_from", $this->relationName($relation));
//$query = "select `ID2` from `BI_audit_ALL_ref` where `ID1` = {$ID}";
$where = $relation ? "and ({$relation} & `RELATION_ID`) != {$relation}" : "";
$query = "select `ID2`, `RELATION_ID` from `BI_audit_ALL_ref` where `ID1` = {$ID} {$where}";
$result = DB::getPDO()->fetchAll($query);
foreach ($result as $childRow) $this->findRelations($featureNode, $childRow['ID2'], $resolveDepth - 1, $childRow['RELATION_ID']);
$this->addAclInfo(
$dataNode = $featureNode,
$typeName = "default_db__x3A__{$row['REMOTE_TABLE']}:{$row['REMOTE_TABLE']}",
$primaryKey = $row['REMOTE_ID'],
$skipFields = [ 'ID' ],
$resolveDepth - 1
);
} else {
$xlink = $this->addChild($node, "default_db__x3A__{$row['REMOTE_TABLE']}:{$row['REMOTE_TABLE']}");
$this->addAttribute($xlink, 'xlink:href', "https://biuro.biall-net.pl/wfs/default_db/{$row['REMOTE_TABLE']}?BI_audit_ALL_ref_RELATIONS={$relation}#{$row['REMOTE_TABLE']}.{$row['REMOTE_ID']}");
}
array_pop($this->path);
}
}
public function addAclInfo($dataNode, $typeName, $primaryKey, $skipFields = [], $resolveDepth = 0) {
try {
$acl = ACL::getAclByTypeName($typeName);
list($nsPrefix, $nsBaseName) = explode(':', $typeName);
// list($nsSourceName, $nsBaseTable) = explode('__x3A__', $nsPrefix);
$searchParams = [
'cols' => array_values($acl->getFieldListByIdZasob())
];
// echo "TODO: \$typeName({$typeName}) \$resolveDepth({$resolveDepth})\n";
if ($resolveDepth > 0) {
$filterFields = implode("/", array_fill(0, $resolveDepth + 1, "*"));
// echo "TODO: \$typeName({$typeName}) \$resolveDepth({$resolveDepth}) \$filterFields({$filterFields})\n";
$schemaCache = array();
try {
Lib::loadClass('Api_Wfs_GetFeature');
$searchParams['cols'] = Api_Wfs_GetFeature::convertOgcPropertyListToFeatureQueryCols($schemaCache, [ $filterFields ], $acl, $isRoot = $args['root']); // convert $args['filterFields'] to field list
// print_r($searchParams);
} catch (Exception $e) {
DBG::log($e);
throw $e;
}
}
$item = $acl->buildQuery($searchParams)->getItem($primaryKey);
if (!$item) throw new Exception("Item not found {$primaryKey}");
// $item = Array( [ID] => 56977, [krs] => 0000080725 , ... )
// $item[default_db__x3A__BI_audit_MSIG_address:BI_audit_MSIG_address] => Array( [0] => [ 'xlink' => ${url} ] )
// $item[default_db__x3A__BI_audit_MSIG_address:BI_audit_MSIG_address] => Array( [11] => [ 'p5:links' => ${p5Links} ] )
// $p5Links = Array( 'p5:next' => ${p5NextLink} )
// $p5NextLink = Array(
// [@typeName] => default_db__x3A__BI_audit_KRS_person:BI_audit_KRS_person
// [@backRefNS] => default_db/BI_audit_KRS/BI_audit_KRS
// [@backRefPK] => 56977
// [@startIndex] => 10
// [@maxFeatures] => 10
// [value] => https://biuro.biall-net.pl/dev-pl/se-master/index.php?SERVICE=WFS&VERSION=1.0.0&TYPENAME=default_db__x3A__BI_audit_KRS_person:BI_audit_KRS_person&REQUEST=GetFeature&backRefNS=default_db/BI_audit_KRS/BI_audit_KRS&backRefPK=56977&backRefField=default_db__x3A__BI_audit_KRS_person:BI_audit_KRS_person&maxFeatures=10&startIndex=10
// $dataNode = $this->addChild($featureNode, "default_db__x3A__{$row['REMOTE_TABLE']}:{$row['REMOTE_TABLE']}");
DBG::log(['item'=>$item,'searchParams'=>$searchParams], 'array', "DBG WfsBiAudit \$item");
foreach ($item as $fieldName => $value) {
if (in_array($fieldName, $skipFields)) continue;
// $this->addAttribute($dataNode, 'xlink:href', "https://biuro.biall-net.pl/wfs/default_db/{$row['REMOTE_TABLE']}?BI_audit_ALL_ref_RELATIONS={$relation}#{$row['REMOTE_TABLE']}.{$row['REMOTE_ID']}");
if (is_scalar($value)) {
$this->addChild($dataNode, "{$nsPrefix}:{$fieldName}", $value);
} else if (is_array($value) && false !== strpos($fieldName, ':')) {
$this->addRootXmlnsTablePrefix($fieldName);
//
//
//
foreach ($value as $refKey => $refValue) {
if (is_array($refValue) && 1 === count($refValue) && !empty($refValue['xlink'])) {
list($refPrefix, $refBaseName) = explode(':', $fieldName);
list($refSourceName, $refBaseTable) = explode('__x3A__', $refPrefix);
$xlink = $this->addChild($dataNode, $fieldName);
$this->addAttribute($xlink, 'xlink:href', $refValue['xlink']); // "https://biuro.biall-net.pl/wfs/default_db/{$refBaseTable}#{$refBaseName}.{$row['REMOTE_ID']}");
} else if (is_array($refValue) && empty($refValue)) {
// skip empty array
} else if (is_array($refValue) && 1 === count($refValue) && !empty($refValue['p5:links'])) {
$p5LinkNode = $this->addChild($dataNode, 'p5:links');
foreach ($refValue['p5:links'] as $p5LinkKey => $p5LinkValue) {
if ('p5:next' === $p5LinkKey) {
$p5NextLinkNode = $this->addChild($p5LinkNode, 'p5:next', str_replace('&', '&', $p5LinkValue['value']));
foreach ($p5LinkValue as $p5NextKey => $p5NextValue) {
if ('@' === $p5NextKey[0]) {
$this->addAttribute($p5NextLinkNode, "p5:" . substr($p5NextKey, 1), $p5NextValue);
} else {
// skip
}
}
} else {
$this->addChild($dataNode, $fieldName, "");
}
}
} else {
$this->addChild($dataNode, $fieldName, "");
}
}
} else if (NULL === $value) {
$this->addChild($dataNode, "{$nsPrefix}:{$fieldName}"); // xs:nil ?
} else {
$this->addChild($dataNode, $fieldName, "");
}
}
// add backRef links
$namespace = $acl->getNamespace();
$backRefList = ACL::getBackRefList($namespace);
DBG::log($backRefList, 'array', "\$backRefList for({$namespace};{$primaryKey})");
$backRefStats = array_map(function ($backRef) use ($namespace, $primaryKey) { // [ namespace, idInstance ], @returns { namespace, idInstance, label, shortName, total }
$label = $backRef['namespace']; // TODO: get DESC from Zasoby
$nameShort = explode("/", $label);
$nameShort = array_pop($nameShort);
$nameShort = (strlen($nameShort) > 20) ? substr($nameShort, 0, 20) . "..." : $nameShort;
$total = 0;
try {
$total = ACL::fetchBackRefs($namespace, $primaryKey, $backRef['namespace'], [ 'total' => true ]);
} catch (Exception $e) {
DBG::log($e);
}
return array_merge($backRef, [
'primaryKey' => $primaryKey,
'label' => $label,
'shortName' => $nameShort,
'total' => $total,
]);
}, $backRefList);
DBG::log($backRefStats, 'array', "\$backRefStats for({$namespace};{$primaryKey})");
$foundBackRef = array_filter($backRefStats, function ($statsBackRef) {
return ($statsBackRef['total'] > 0);
});
DBG::log($foundBackRef, 'array', "\$foundBackRef for({$namespace};{$primaryKey})");
// $rowFunList[] = [
// 'ico' => 'glyphicon glyphicon-random',
// 'href' => Router::getRoute('ViewTableAjax')->getLink('', [
// 'namespace' => $backRef['namespace'],
// 'childRefNS' => $acl->getNamespace(),
// 'childRefPK' => $id,
// ]),
// 'title' => "Wyszukaj powiązania z '{$backRefLabel}'",
// 'label' => "Wyszukaj powiązania z '{$backRefShort}' {$totalBackRefs}",
// ];
if (!empty($foundBackRef)) {
$p5LinkNode = $this->addChild($dataNode, 'p5:links');
foreach ($foundBackRef as $backRef) {
$linkBackRef = null; // TODO: generate back ref link
$p5BackRefNode = $this->addChild($p5LinkNode, 'p5:backRef', $linkBackRef);
$this->addAttribute($p5BackRefNode, "p5:total", $backRef['total']);
$this->addAttribute($p5BackRefNode, "p5:label", $backRef['label']);
$this->addAttribute($p5BackRefNode, "p5:shortName", $backRef['shortName']);
$this->addAttribute($p5BackRefNode, "p5:namespace", $backRef['namespace']);
$this->addAttribute($p5BackRefNode, "p5:primaryKey", $backRef['primaryKey']);
$this->addAttribute($p5BackRefNode, "p5:from", $namespace);
$this->addAttribute($p5BackRefNode, "p5:to", $backRef['namespace']);
}
}
} catch (Exception $e) {
DBG::log($e);
}
}
public function defaultAction() {
$TYPENAME = V::get('TYPENAME', '', $_GET);
$primaryKey = V::get('primaryKey', 0, $_GET, 'int');
$resolveDepth = V::get('resolveDepth', 1, $_GET, 'int');
$TYPENAME_exploded = explode(":", $TYPENAME);
if (!(count($TYPENAME_exploded) == 2 && $primaryKey && $resolveDepth >= 1 && $resolveDepth <= self::maxResolveDepth)) self::throwServiceException("WFS request error");
$table = $TYPENAME_exploded[1];
try {
$this->dom = new DOMDocument('1.0', 'UTF-8');
$this->dom->preserveWhiteSpace = false;
$this->dom->formatOutput = true;
$attrs = [
'xmlns:wfs' => 'http://www.opengis.net/wfs',
'xmlns' => 'http://www.opengis.net/wfs',
'xmlns:gml' => 'http://www.opengis.net/gml',
'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance',
'xmlns:xlink' => 'http://www.w3.org/1999/xlink',
];
$wfs = $this->addChild($this->dom, 'wfs:FeatureCollection');
$this->setRootNode($wfs);
foreach ($attrs as $name => $value) $this->addAttribute($wfs, $name, $value);
$gml = $this->addChild($wfs, 'gml:featureMember');
$query = "select `ID` from `BI_audit_ALL` where `REMOTE_TABLE` = " . DB::getPDO()->quote($table) . " and `REMOTE_ID` = {$primaryKey}";
if (!($ID = DB::getPDO()->fetchValue($query))) {
error_log('#233 default base passing');
// $this->BaseStruct=$this->objectStructureAction("default_db/".$table."/".$table );
//
// $query = "select `".$this->BaseStruct['primaryKey']."` from `".$table."` where ".$this->BaseStruct['primaryKey']." = {$primaryKey}";
// if (!($ID = DB::getPDO()->fetchValue($query))) {
// self::throwServiceException("Błąd danych z BaseStruct ");
// }
// $this->findRelations_base($gml, $ID, $resolveDepth, $table, $this->BaseStruct, $table);
$featureNode = $this->addChild($gml, $TYPENAME);
$this->addRootXmlnsTablePrefix($TYPENAME);
list($nsPrefix, $nsBaseName) = explode(':', $TYPENAME);
$this->addAttribute($featureNode, 'fid', "{$nsBaseName}.{$primaryKey}");
$this->addAclInfo(
$dataNode = $featureNode,
$typeName = $TYPENAME,
$primaryKey = $primaryKey,
$skipFields = [],
$resolveDepth
);
// foreach ($this->tablesUsed as $table) $this->addAttribute($wfs, "xmlns:default_db__x3A__{$table}", "https://biuro.biall-net.pl/wfs/default_db/{$table}");
$attrs = [
'numberMatched' => 'unknown',
'numberReturned' => '1',
];
foreach ($attrs as $name => $value) $this->addAttribute($wfs, $name, $value);
$xml = $this->dom->saveXML();
self::output($xml);
} else {
error_log('#254 default passing');
$this->findRelations($gml, $ID, $resolveDepth);
// foreach ($this->tablesUsed as $table) $this->addAttribute($wfs, "xmlns:default_db__x3A__{$table}", "https://biuro.biall-net.pl/wfs/default_db/{$table}");
$attrs = [
'numberMatched' => 'unknown',
'numberReturned' => '1',
];
foreach ($attrs as $name => $value) $this->addAttribute($wfs, $name, $value);
$xml = $this->dom->saveXML();
self::output($xml);
}
} catch (Exception $e) {
//$this->objectStructureAction('default_db/BI_audit_CEIDG_pelnomocnicy/BI_audit_CEIDG_pelnomocnicy');
self::throwServiceException($e->getMessage());
}
}
}