{$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()); } } }