WfsBiAudit.php 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  1. <?php
  2. Lib::loadClass('RouteBase');
  3. class Route_WfsBiAudit extends RouteBase {
  4. const maxResolveDepth = 3;
  5. private $dom, $path = [], $relations = [], $tablesUsed = [];
  6. public function handleAuth() {
  7. if (!empty($_GET['sid'])) {
  8. session_write_close();
  9. session_id($_GET['sid']); // TODO: security BUG
  10. error_log('wfs-data.php _GET[sid] was read' .$_GET['sid'].' ; ');
  11. session_start();
  12. session_write_close();
  13. }
  14. if (!User::logged()) throw new HttpException('Unauthorized', 401);
  15. }
  16. private static function output($output) {
  17. header("Content-Type: application/xml");
  18. header("Content-Transfer-Encoding: binary");
  19. header("Content-Length: " . strlen($output));
  20. echo $output;
  21. }
  22. private static function throwServiceException($message) {
  23. $xml = <<<EOT
  24. <?xml version="1.0" encoding="UTF-8"?>
  25. <ServiceExceptionReport xmlns="http://www.opengis.net/ogc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/ogc http://schemas.opengis.net/wfs/1.0.0/OGC-exception.xsd" version="1.2.0">
  26. <ServiceException>{$message}</ServiceException>
  27. </ServiceExceptionReport>
  28. EOT;
  29. self::output($xml);
  30. die();
  31. }
  32. public function objectStructureAction($namespace) { // objectStructAction
  33. Lib::loadClass('SchemaFactory');
  34. Lib::loadClass('ACL');
  35. try {
  36. error_log('objectStructureAction for '.$namespace);
  37. if (empty($namespace)) throw new Exception("Missing param namespace");
  38. $item = SchemaFactory::loadDefaultObject('SystemObject')->getItem($namespace, [ 'propertyName' => '*,field' ]);
  39. $return=$this->objectStructView($item);
  40. return $return;
  41. } catch (Exception $e) {
  42. //error_log('danger', "Error #" . $e->getCode() . "|" . $e->getLine() . ": " . $e->getMessage());
  43. DBG::log($e);
  44. }
  45. }
  46. //input param $item['namespace']='default_db/BI_audit_CEIDG_powiazania/BI_audit_CEIDG_powiazania'
  47. public function objectStructView($item) {
  48. $namespace = $item['namespace'];
  49. $thisGetLink = [ $this, 'getLink' ];
  50. $getBackRefList=ACL::getBackRefList($item['namespace']);
  51. foreach($getBackRefList as $ind=>$backref) {
  52. $exploded_ns = explode('/', $backref['namespace']);
  53. $return['backrefs'][]=$exploded_ns[1].'__x3A__'.$exploded_ns[2].':'.$exploded_ns[3];
  54. }
  55. foreach($item['field'] as $ind=>$refs) {
  56. $return['refs'] []=$refs['fieldNamespace'];
  57. $return['refs__rootTableName'][]=$refs['_rootTableName'];
  58. $return['refs__objectNamespace'][]=$refs['objectNamespace'];
  59. }
  60. $return['table']=$item['name'];
  61. $return['primaryKey']=$item['primaryKey'];
  62. //print_r($this->BaseStruct);
  63. return $return;
  64. }
  65. private function addChild($node, $name, $value = null) {
  66. $child = $this->dom->createElement($name, $value);
  67. $node->appendChild($child);
  68. return $child;
  69. }
  70. private function addAttribute($node, $name, $value) {
  71. $attr = $this->dom->createAttribute($name);
  72. $attr->value = $value;
  73. $node->appendChild($attr);
  74. }
  75. private function relationName($ID) {
  76. if (!isset($this->relations[$ID])) {
  77. $query = "select `RELATION` from `BI_audit_ALL_ref_RELATIONS` where `ID` & {$ID} order by `ID`";
  78. $result = DB::getPDO()->fetchAll($query);
  79. $rels = array_map('reset', $result);
  80. $this->relations[$ID] = implode(", ", $rels);
  81. }
  82. return $this->relations[$ID];
  83. }
  84. private function findRelations_base($node, $ID, $resolveDepth, $relation = null, $BaseStruct=null,$table=null) {
  85. if (in_array($ID, $this->path)) return;
  86. $this->path[] = $ID;
  87. error_log('#208 findRelations_base passing');
  88. foreach($BaseStruct['refs__objectNamespace'] as $ind=>$refs){
  89. $getRefTable=ACL::getRefTable('default_db/'.$table.'/'.$table,$refs);
  90. $query = "select `REMOTE_PRIMARY_KEY` from `".$getRefTable."` where `PRIMARY_KEY` = {$ID}";
  91. error_log('#114 findRelations_base passing query '.$query);
  92. if (!($row = DB::getPDO()->fetchFirst($query))) {
  93. } else {
  94. /*{
  95. $this->objectStructureAction('default_db/BI_audit_CEIDG_pelnomocnicy/BI_audit_CEIDG_pelnomocnicy');
  96. self::throwServiceException("Błąd danych #102 findRelations_base");
  97. }*/
  98. if (!in_array($BaseStruct['_rootTableName'][$ind], $this->tablesUsed)) $this->tablesUsed[] = $BaseStruct['_rootTableName'][$ind];
  99. }
  100. if ($resolveDepth) {
  101. $feature = $this->addChild($node, $BaseStruct['refs'][$ind]);
  102. $this->addAttribute($feature, 'fid', $BaseStruct['_rootTableName'][$ind].$row['REMOTE_PRIMARY_KEY']);
  103. $this->addChild($feature, "default_db__x3A__".$BaseStruct['_rootTableName'][$ind].":ID", $row['REMOTE_PRIMARY_KEY']);
  104. if ($relation) $this->addChild($feature, "relation_from", $this->relationName($relation));
  105. //$query = "select `ID2` from `BI_audit_ALL_ref` where `ID1` = {$ID}";
  106. //$where = $relation ? "and ({$relation} & `RELATION_ID`) != {$relation}" : "";
  107. $RefBaseStruct=$this->objectStructureAction($BaseStruct['objectNamespace'][$ind]);
  108. $query = "select `".$RefBaseStruct['primaryKey']."` from `".$RefBaseStruct['table']."` where `".$RefBaseStruct['primaryKey']."` = ".$row['REMOTE_PRIMARY_KEY'] ;
  109. $result = DB::getPDO()->fetchAll($query);
  110. foreach ($result as $row) $this->findRelations($feature, $row['REMOTE_PRIMARY_KEY'], $resolveDepth - 1, null,$BaseStruct['table'],$RefBaseStruct['table']);
  111. } else {
  112. $xlink = $this->addChild($node, $BaseStruct['refs'][$ind]);
  113. $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']}");
  114. }
  115. array_pop($this->path);
  116. }
  117. }
  118. private function findRelations($node, $ID, $resolveDepth, $relation = null,$BaseTableFrom,$BaseTableTo) {
  119. if (in_array($ID, $this->path)) return;
  120. $this->path[] = $ID;
  121. if(isset($BaseTableFrom)) {
  122. $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
  123. } else {
  124. $query = "select `REMOTE_TABLE`, `REMOTE_ID` from `BI_audit_ALL` where `ID` = {$ID}";
  125. }
  126. if (!($row = DB::getPDO()->fetchFirst($query)))
  127. {
  128. //$this->objectStructureAction('default_db/BI_audit_CEIDG_pelnomocnicy/BI_audit_CEIDG_pelnomocnicy');
  129. // self::throwServiceException("Błąd danych findRelations #130");
  130. $this->BaseStruct=$this->objectStructureAction("default_db/".$BaseTableTo."/".$BaseTableTo );
  131. $query = "select `".$this->BaseStruct['primaryKey']."` from `".$BaseTableTo."` where ".$this->BaseStruct['primaryKey']." = {$ID}";
  132. if (!($ID = DB::getPDO()->fetchValue($query))) {
  133. self::throwServiceException("Błąd danych z BaseStruct/findRelations #162 ");
  134. }
  135. if (!in_array($BaseTableTo, $this->tablesUsed)) $this->tablesUsed[] = $BaseTableTo;
  136. if ($resolveDepth) {
  137. $feature = $this->addChild($node, "default_db__x3A__{$row['REMOTE_TABLE']}:{$row['REMOTE_TABLE']}");
  138. $this->addAttribute($feature, 'fid', "{$row['REMOTE_TABLE']}.{$row['REMOTE_ID']}");
  139. $this->addChild($feature, "default_db__x3A__{$row['REMOTE_TABLE']}:ID", $row['REMOTE_ID']);
  140. if ($relation) $this->addChild($feature, "relation_from", $this->relationName($relation));
  141. //$query = "select `ID2` from `BI_audit_ALL_ref` where `ID1` = {$ID}";
  142. //$where = $relation ? "and ({$relation} & `RELATION_ID`) != {$relation}" : "";
  143. //$query = "select `ID2`, `RELATION_ID` from `BI_audit_ALL_ref` where `ID1` = {$ID} {$where}";
  144. //$result = DB::getPDO()->fetchAll($query);
  145. //foreach ($result as $row)
  146. // $this->findRelations($feature, $row['ID2'], $resolveDepth - 1, $row['RELATION_ID'],);
  147. findRelations_base($node, $ID, $resolveDepth, $relation = null, $this->BaseStruct,$BaseTableTo) ;
  148. } else {
  149. $xlink = $this->addChild($node, "default_db__x3A__{$BaseTableTo}:{$BaseTableTo}");
  150. $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']]}");
  151. }
  152. array_pop($this->path);
  153. } else {
  154. if (!in_array($row['REMOTE_TABLE'], $this->tablesUsed)) $this->tablesUsed[] = $row['REMOTE_TABLE'];
  155. if ($resolveDepth) {
  156. $feature = $this->addChild($node, "default_db__x3A__{$row['REMOTE_TABLE']}:{$row['REMOTE_TABLE']}");
  157. $this->addAttribute($feature, 'fid', "{$row['REMOTE_TABLE']}.{$row['REMOTE_ID']}");
  158. $this->addChild($feature, "default_db__x3A__{$row['REMOTE_TABLE']}:ID", $row['REMOTE_ID']);
  159. if ($relation) $this->addChild($feature, "relation_from", $this->relationName($relation));
  160. //$query = "select `ID2` from `BI_audit_ALL_ref` where `ID1` = {$ID}";
  161. $where = $relation ? "and ({$relation} & `RELATION_ID`) != {$relation}" : "";
  162. $query = "select `ID2`, `RELATION_ID` from `BI_audit_ALL_ref` where `ID1` = {$ID} {$where}";
  163. $result = DB::getPDO()->fetchAll($query);
  164. foreach ($result as $row) $this->findRelations($feature, $row['ID2'], $resolveDepth - 1, $row['RELATION_ID']);
  165. } else {
  166. $xlink = $this->addChild($node, "default_db__x3A__{$row['REMOTE_TABLE']}:{$row['REMOTE_TABLE']}");
  167. $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']}");
  168. }
  169. array_pop($this->path);
  170. }
  171. }
  172. public function defaultAction() {
  173. $TYPENAME = V::get('TYPENAME', '', $_GET);
  174. $primaryKey = V::get('primaryKey', 0, $_GET, 'int');
  175. $resolveDepth = V::get('resolveDepth', 1, $_GET, 'int');
  176. $TYPENAME_exploded = explode(":", $TYPENAME);
  177. if (!(count($TYPENAME_exploded) == 2 && $primaryKey && $resolveDepth >= 1 && $resolveDepth <= self::maxResolveDepth)) self::throwServiceException("WFS request error");
  178. $table = $TYPENAME_exploded[1];
  179. try {
  180. $this->dom = new DOMDocument('1.0', 'UTF-8');
  181. $this->dom->preserveWhiteSpace = false;
  182. $this->dom->formatOutput = true;
  183. $attrs = [
  184. 'xmlns:wfs' => 'http://www.opengis.net/wfs',
  185. 'xmlns' => 'http://www.opengis.net/wfs',
  186. 'xmlns:gml' => 'http://www.opengis.net/gml',
  187. 'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance',
  188. 'xmlns:xlink' => 'http://www.w3.org/1999/xlink',
  189. ];
  190. $wfs = $this->addChild($this->dom, 'wfs:FeatureCollection');
  191. foreach ($attrs as $name => $value) $this->addAttribute($wfs, $name, $value);
  192. $gml = $this->addChild($wfs, 'gml:featureMember');
  193. $query = "select `ID` from `BI_audit_ALL` where `REMOTE_TABLE` = " . DB::getPDO()->quote($table) . " and `REMOTE_ID` = {$primaryKey}";
  194. if (!($ID = DB::getPDO()->fetchValue($query))) {
  195. error_log('#233 default base passing');
  196. $this->BaseStruct=$this->objectStructureAction("default_db/".$table."/".$table );
  197. $query = "select `".$this->BaseStruct['primaryKey']."` from `".$table."` where ".$this->BaseStruct['primaryKey']." = {$primaryKey}";
  198. if (!($ID = DB::getPDO()->fetchValue($query))) {
  199. self::throwServiceException("Błąd danych z BaseStruct ");
  200. }
  201. $this->findRelations_base($gml, $ID, $resolveDepth,$table,$this->BaseStruct,$table);
  202. foreach ($this->tablesUsed as $table) $this->addAttribute($wfs, "xmlns:default_db__x3A__{$table}", "https://biuro.biall-net.pl/wfs/default_db/{$table}");
  203. $attrs = [
  204. 'numberMatched' => 'unknown',
  205. 'numberReturned' => '1',
  206. ];
  207. foreach ($attrs as $name => $value) $this->addAttribute($wfs, $name, $value);
  208. $xml = $this->dom->saveXML();
  209. self::output($xml);
  210. } else {
  211. error_log('#254 default passing');
  212. $this->findRelations($gml, $ID, $resolveDepth);
  213. foreach ($this->tablesUsed as $table) $this->addAttribute($wfs, "xmlns:default_db__x3A__{$table}", "https://biuro.biall-net.pl/wfs/default_db/{$table}");
  214. $attrs = [
  215. 'numberMatched' => 'unknown',
  216. 'numberReturned' => '1',
  217. ];
  218. foreach ($attrs as $name => $value) $this->addAttribute($wfs, $name, $value);
  219. $xml = $this->dom->saveXML();
  220. self::output($xml);
  221. }
  222. } catch (Exception $e) {
  223. //$this->objectStructureAction('default_db/BI_audit_CEIDG_pelnomocnicy/BI_audit_CEIDG_pelnomocnicy');
  224. self::throwServiceException($e->getMessage());
  225. }
  226. }
  227. }