BiAuditGraph.php 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413
  1. <?php
  2. Lib::loadClass('Api_WfsNs');
  3. Lib::loadClass('Response');
  4. class Route_UrlAction_BiAuditGraph extends RouteBase {
  5. function defaultAction() {
  6. $args = [];
  7. $args['raportId'] = V::get('raportId', 0, $_GET, 'int');
  8. $args['featureId'] = V::get('featureId', '', $_GET);
  9. $args['primaryKey'] = V::get('primaryKey', '', $_GET);
  10. if ($args['raportId']) return UI::layout([$this, 'raportView'], [ 'args' => $args ]);
  11. UI::layout([$this, 'defaultView']);
  12. }
  13. function defaultView() {
  14. // typeName = "default_db__x3A__BI_audit_KRS_person:BI_audit_KRS_person"
  15. $namespace = 'default_db/BI_audit_KRS_person/BI_audit_KRS_person'; // V::get('namespace', '', $_GET);
  16. if (!$namespace) throw new Exception("Missing namespace");
  17. $primaryKey = V::get('primaryKey', '', $_GET);
  18. if (!$primaryKey) throw new Exception("Missing primaryKey");
  19. echo UI::h('div', [ 'id' => "ref_graph_node", 'style' => "width:98%; height:500px; border:1px solid silver; margin:8px auto; padding:0" ], [
  20. "Pobieranie danych..."
  21. ]);
  22. echo UI::h('script', [ 'src' => "static/visjs/vis.min.js" ]);
  23. echo UI::h('style', [ 'type' => "text/css", 'src' => "static/visjs/vis.min.css" ]);
  24. UI::inlineJS(__FILE__ . '.view.js', [
  25. 'HTML_ID_REF_GRAPH' => 'ref_graph_node',
  26. 'TYPENAME' => Api_WfsNs::typeName($namespace),
  27. 'PRIMARY_KEY' => $primaryKey,
  28. 'WFS_URL' => Router::getRoute('WfsBiAudit')->getLink(),
  29. 'DBG' => (V::get('DBG', 0, $_GET, 'int') > 0),
  30. ]);
  31. }
  32. function raportOutputMatrixAction() {
  33. $args = [];
  34. $args['raportId'] = V::get('raportId', 0, $_GET, 'int');
  35. $args['outputFormat'] = V::get('outputFormat', '', $_GET, 'word');
  36. try {
  37. if (!$args['raportId']) throw new Exception("Wrong param raportId");
  38. } catch (\Exception $e) {
  39. switch ($args['outputFormat']) {
  40. case 'json': return $this->sendJsonErrorMsg($e->getMessage());
  41. case 'xml': return $this->sendXmlErrorMsg($e->getMessage());
  42. case 'html':
  43. default: {
  44. return $this->sendHtmlErrorMsg($e->getMessage());
  45. }
  46. }
  47. }
  48. $matrix = $this->getRaportOutputMatrix($args['raportId']);
  49. switch ($args['outputFormat']) {
  50. case 'json': return $this->sendJsonMatrix($args['raportId'], $matrix);
  51. case 'xml': return $this->sendXmlMatrix($args['raportId'], $matrix);
  52. case 'html':
  53. default: {
  54. return $this->sendHtmlMatrix($args['raportId'], $matrix);
  55. }
  56. }
  57. }
  58. function sendJsonMatrix($raportId, $matrix) { // TODO: ..
  59. print_r($matrix);
  60. }
  61. function sendXmlMatrix($raportId, $matrix) { // TODO: ...
  62. print_r($matrix);
  63. }
  64. function sendHtmlMatrix($raportId, $matrix) {
  65. UI::gora();
  66. UI::table([
  67. 'caption' => "Wyniki raportu Nr {$raportId}",
  68. 'rows' => $matrix,
  69. ]);
  70. UI::dol();
  71. }
  72. function sendJsonErrorMsg($msg) { // TODO: ..
  73. echo $e->getMessage();
  74. }
  75. function sendXmlErrorMsg($msg) { // TODO: ...
  76. echo $e->getMessage();
  77. }
  78. function sendHtmlErrorMsg($msg) {
  79. UI::gora();
  80. UI::alert('danger', $e->getMessage());
  81. UI::dol();
  82. }
  83. function raportOutputStatsAction() {
  84. session_write_close();
  85. $args = [];
  86. $args['raportId'] = V::get('raportId', 0, $_GET, 'int');
  87. $args['outputFormat'] = V::get('outputFormat', '', $_GET, 'word');
  88. try {
  89. if (!$args['raportId']) throw new Exception("Wrong param raportId");
  90. } catch (\Exception $e) {
  91. switch ($args['outputFormat']) {
  92. case 'json': return $this->sendJsonErrorMsg($e->getMessage());
  93. case 'xml': return $this->sendXmlErrorMsg($e->getMessage());
  94. case 'html':
  95. default: {
  96. return $this->sendHtmlErrorMsg($e->getMessage());
  97. }
  98. }
  99. }
  100. $stats = $this->getOutputStats($args['raportId']);
  101. switch ($args['outputFormat']) {
  102. case 'json': return $this->sendJsonStats($args['raportId'], $stats);
  103. case 'xml': return $this->sendXmlStats($args['raportId'], $stats);
  104. case 'html':
  105. default: {
  106. return $this->sendHtmlStats($args['raportId'], $stats);
  107. }
  108. }
  109. }
  110. function getOutputStats($raportId) {
  111. $matrix = $this->getRaportOutputMatrix($raportId);
  112. $listObjectsNs = $this->_getListPointChildNs();
  113. $listPointChildAlias = $this->_getListPointChildAlias();
  114. $getPointFeatureIdFromPath = function ($item) {
  115. $listPointChildAlias = $this->_getListPointChildAlias();
  116. return array_reduce($listPointChildAlias, function ($ret, $objAlias) use ($item) {
  117. $pk = V::get("pk_{$objAlias}", 0, $item);
  118. if ($pk) $ret = "{$objAlias}.{$pk}";
  119. return $ret;
  120. }, null);
  121. };
  122. $lastPkPath = 0;
  123. $lastPos = 0;
  124. $fidMatrix = array_map(function ($item) use ($getPointFeatureIdFromPath, &$lastPkPath, &$lastPos) {
  125. if ($lastPkPath != $item['pk_Path']) {
  126. $lastPos = 0;
  127. }
  128. $lastPos += 1;
  129. $lastPkPath = $item['pk_Path'];
  130. return [
  131. 'pk_Path' => $item['pk_Path'],
  132. 'pos' => $lastPos,
  133. 'fid' => $getPointFeatureIdFromPath($item),
  134. ];
  135. }, $matrix);
  136. DBG::log($fidMatrix, 'array', '$fidMatrix');
  137. $listPathLength = array_reduce($matrix, function ($ret, $item) {
  138. $ret[ $item['pk_Path'] ] = 1 + V::get($item['pk_Path'], 0, $ret);
  139. return $ret;
  140. }, []);
  141. $listPathPk = array_keys($listPathLength);
  142. $pointOccurs = array_reduce($matrix, function ($ret, $item) use ($listPointChildAlias) {
  143. foreach ($listPointChildAlias as $alias) {
  144. $pkField = "pk_{$alias}";
  145. if ($item[$pkField]) {
  146. $featureId = "{$alias}.{$item[$pkField]}";
  147. $ret[$featureId] = 1 + V::getValue($ret[$featureId], 0);
  148. }
  149. }
  150. return $ret;
  151. }, []);
  152. asort($pointOccurs);
  153. DBG::log($pointOccurs, 'array', '$pointOccurs');
  154. $prevItem = [];
  155. $edges = array_reduce($matrix, function ($ret, $item) use (&$prevItem, $getPointFeatureIdFromPath) {
  156. if (!empty($prevItem) && $prevItem['pk_Path'] === $item['pk_Path']) {
  157. $ret[] = [ 'source' => $getPointFeatureIdFromPath($prevItem), 'target' => $getPointFeatureIdFromPath($item), 'pathId' => $item['pk_Path'] ];
  158. $prevItem = array_merge([], $item);
  159. return $ret;
  160. } else {
  161. $prevItem = array_merge([], $item);
  162. return $ret;
  163. }
  164. }, []);
  165. DBG::log("edges - done");
  166. $prevFeaturesOnPath = [];
  167. $prevPathId = 0;
  168. $allToAllEdges = array_reduce($matrix, function ($ret, $item) use (&$prevFeaturesOnPath, &$prevPathId, $getPointFeatureIdFromPath) {
  169. $curFeatureId = $getPointFeatureIdFromPath($item);
  170. if (!empty($prevFeaturesOnPath) && $prevPathId === $item['pk_Path']) {
  171. foreach ($prevFeaturesOnPath as $idx => $prevFeatureId) {
  172. $ret[] = [ 'source' => $prevFeatureId, 'target' => $curFeatureId, 'pathId' => $item['pk_Path'], 'length' => (1 + $idx) ];
  173. }
  174. array_unshift($prevFeaturesOnPath, $curFeatureId);
  175. $prevPathId = $item['pk_Path'];
  176. return $ret;
  177. } else {
  178. $prevFeaturesOnPath = [ $curFeatureId ];
  179. $prevPathId = $item['pk_Path'];
  180. return $ret;
  181. }
  182. }, []);
  183. DBG::log("edges_all_to_all - done");
  184. $stats = [];
  185. // $stats['path_length'] = $listPathLength;
  186. $stats['path_total'] = count($listPathLength);
  187. $stats['point_total'] = count($matrix);
  188. $stats['point_occurs'] = $pointOccurs;
  189. $stats['edges_all_to_all'] = $allToAllEdges;
  190. $stats['edges'] = $edges;
  191. $stats['nodes'] = array_map([ $this, 'getFeature' ], array_keys($pointOccurs));
  192. $stats['path_list'] = array_values(array_reduce($fidMatrix, function ($ret, $item) {
  193. $pkPath = $item['pk_Path'];
  194. if (!array_key_exists($pkPath, $ret)) $ret[ $pkPath ] = [ 'pkPath' => $pkPath, 'fids' => [] ];
  195. $ret[ $pkPath ][ 'fids' ][] = $item['fid'];
  196. return $ret;
  197. }, []));
  198. return $stats;
  199. }
  200. function getFeature($featureId) {
  201. list($objectName, $primaryKey) = explode(".", $featureId);
  202. if (!$objectName) throw new Exception("Wrong featureId '{$featureId}' - missing objectName");
  203. if (!$primaryKey) throw new Exception("Wrong featureId '{$featureId}' - missing primaryKey");
  204. $tableName = $objectName;
  205. $item = DB::getPDO()->fetchFirst(" select * from `{$tableName}` where id = :id ", [ ':id' => $primaryKey ]);
  206. $getLabel = [ $this, '_getFeatureLabel' ];
  207. return array_merge($item, [
  208. '@label' => $getLabel($objectName, $item), // TODO: label depend on table / later format from xsd
  209. '@object' => $objectName,
  210. '@primaryKey' => $primaryKey,
  211. ]);
  212. }
  213. function _getFeatureLabel($objectName, $item) {
  214. $primaryKey = $item['@primaryKey'];
  215. switch ($objectName) {
  216. case 'BI_audit_ENERGA_RUM_KONTRAHENCI': return V::get('Pelna_nazwa_kontrahenta', $primaryKey, $item);
  217. case 'BI_audit_MSIG': return V::get('nazwa', $primaryKey, $item);
  218. case 'BI_audit_MSIG_person': return V::getValue(
  219. implode(" ", array_filter([
  220. V::get('imiona', '', $item),
  221. V::get('nazwisko', '', $item)
  222. ], 'strlen'))
  223. , "{$objectName} Nr {$primaryKey}"
  224. );
  225. case 'BI_audit_CEIDG': return V::get('firma', $primaryKey, $item);
  226. case 'BI_audit_KRS': return V::get('nazwa', $primaryKey, $item);
  227. case 'BI_audit_KRS_person': return V::getValue(
  228. implode(" ", array_filter([
  229. V::get('imiona', '', $item),
  230. V::get('nazwisko', '', $item)
  231. ], 'strlen'))
  232. , "{$objectName} Nr {$primaryKey}"
  233. );
  234. case 'BI_audit_MSIG_company': return V::get('nazwa', $primaryKey, $item);
  235. case 'BI_audit_KRS_company': return V::get('nazwa', $primaryKey, $item);
  236. case 'TERYT_adresy': return "TERYT({$item['TERYT_SYM']}/{$item['TERYT_SYM_UL']})";
  237. case 'BI_audit_MSIG_address': return V::getValue(
  238. implode(", ", array_filter([
  239. implode(" ", array_filter([
  240. V::get('A_kod', '', $item),
  241. V::get('S_miejscowosc', '', $item)
  242. ], 'strlen')),
  243. implode(" ", array_filter([
  244. V::get('A_nrDomu', '', $item),
  245. V::get('A_nrDomu', '', $item),
  246. V::get('A_nrLokalu', '', $item)
  247. ], 'strlen'))
  248. ], 'strlen'))
  249. , "{$objectName} Nr {$primaryKey}"
  250. );
  251. default: return "TODO: {$objectName} Nr {$primaryKey}";
  252. }
  253. }
  254. function sendJsonStats($raportId, $stats) {
  255. Response::sendJson([
  256. 'type' => "success",
  257. 'msg' => "OK",
  258. 'body' => $stats
  259. ]);
  260. die();
  261. }
  262. function sendXmlStats($raportId, $stats) {
  263. print_r($stats);
  264. }
  265. function sendHtmlStats($raportId, $stats) {
  266. UI::gora();
  267. DBG::nicePrint($stats, "\$stats");
  268. $dbgNode = function ($item) {
  269. return [
  270. 'object' => $item['@object'],
  271. 'primaryKey' => $item['@primaryKey'],
  272. 'label' => $item['@label'],
  273. ];
  274. };
  275. UI::table([ 'rows' => array_map($dbgNode, $stats['nodes']) ]);
  276. UI::dol();
  277. }
  278. function raportView($args) {
  279. $raportId = V::get('raportId', 0, $args, 'int');
  280. $featureId = V::get('featureId', '', $args, '');
  281. $h = [ 'UI', 'h' ];
  282. echo $h('div', [ 'id' => "bi_audit_raport-network_graph" ], "TODO: loading data...");
  283. echo $h('script', ['src'=>"static/vendor.js?v=a76e2988", 'type'=>"text/javascript"]);
  284. echo $h('script', [ 'src' => "static/visjs/vis.min.js" ]);
  285. echo UI::h('link', [ 'href' => 'static/react-bootstrap-typeahead.min.css', 'type' => 'text/css', 'rel' => 'stylesheet' ]);
  286. UI::inlineJS(__FILE__ . '.network-graph.js', [
  287. 'HTML_ID_REF_GRAPH' => 'bi_audit_raport-network_graph',
  288. // 'TYPENAME' => Api_WfsNs::typeName($namespace),
  289. // 'PRIMARY_KEY' => $primaryKey,
  290. // 'WFS_URL' => Router::getRoute('WfsBiAudit')->getLink(),
  291. 'RAPORT_ID' => $raportId,
  292. 'API_URL' => $this->getLink('raportOutputStats', [ 'outputFormat' => "json", 'raportId' => $raportId ]),
  293. 'STATS' => $this->getOutputStats($raportId),
  294. 'DATA_MATRIX' => $this->getRaportOutputMatrix($raportId),
  295. 'DBG' => (V::get('DBG', 0, $_GET, 'int') > 0),
  296. ]);
  297. $this->getRaportOutputMatrix($raportId); // TODO: DBG
  298. }
  299. function getRaportNetworkGraphDataAjaxAction() {
  300. }
  301. function _getListPointChildNs() {
  302. $listObjectsNs = [];
  303. $listObjectsNs[] = 'default_db__x3A__BI_audit_CEIDG:BI_audit_CEIDG';
  304. $listObjectsNs[] = 'default_db__x3A__BI_audit_CEIDG_pelnomocnicy:BI_audit_CEIDG_pelnomocnicy';
  305. $listObjectsNs[] = 'default_db__x3A__BI_audit_CEIDG_powiazania:BI_audit_CEIDG_powiazania';
  306. $listObjectsNs[] = 'default_db__x3A__BI_audit_ENERGA_PRACOWNICY:BI_audit_ENERGA_PRACOWNICY';
  307. $listObjectsNs[] = 'default_db__x3A__BI_audit_ENERGA_PRACOWNICY_adresy:BI_audit_ENERGA_PRACOWNICY_adresy';
  308. $listObjectsNs[] = 'default_db__x3A__BI_audit_ENERGA_RUM_KONTRAHENCI:BI_audit_ENERGA_RUM_KONTRAHENCI';
  309. $listObjectsNs[] = 'default_db__x3A__BI_audit_KRS:BI_audit_KRS';
  310. $listObjectsNs[] = 'default_db__x3A__BI_audit_KRS_address:BI_audit_KRS_address';
  311. $listObjectsNs[] = 'default_db__x3A__BI_audit_KRS_company:BI_audit_KRS_company';
  312. $listObjectsNs[] = 'default_db__x3A__BI_audit_KRS_person:BI_audit_KRS_person';
  313. $listObjectsNs[] = 'default_db__x3A__BI_audit_KW_requested_person:BI_audit_KW_requested_person';
  314. $listObjectsNs[] = 'default_db__x3A__BI_audit_MSIG:BI_audit_MSIG';
  315. $listObjectsNs[] = 'default_db__x3A__BI_audit_MSIG_address:BI_audit_MSIG_address';
  316. $listObjectsNs[] = 'default_db__x3A__BI_audit_MSIG_company:BI_audit_MSIG_company';
  317. $listObjectsNs[] = 'default_db__x3A__BI_audit_MSIG_person:BI_audit_MSIG_person';
  318. $listObjectsNs[] = 'default_db__x3A__TERYT_adresy:TERYT_adresy';
  319. return $listObjectsNs;
  320. }
  321. function _getListPointChildAlias() {
  322. return array_map(function ($objNs) {
  323. // return str_replace([ 'BI_audit_' ], '', substr($objNs, strrpos($objNs, ':') + 1));
  324. return substr($objNs, strrpos($objNs, ':') + 1);
  325. }, $this->_getListPointChildNs());
  326. }
  327. function getRaportOutputMatrix($raportId) {
  328. // Main Raport Acl NS: default_db__x3A__BI_audit_ENERGA_RUM_KONTRAHENCI_POWIAZANIA:BI_audit_ENERGA_RUM_KONTRAHENCI_POWIAZANIA
  329. // - Found Paths in: default_db__x3A__BI_audit_ENERGA_RUM_KONTRAHENCI_POWIAZANIA_row:BI_audit_ENERGA_RUM_KONTRAHENCI_POWIAZANIA_row
  330. // - Path Points in: default_db__x3A__BI_audit_ENERGA_RUM_KONTRAHENCI_POWIAZANIA_row_object:BI_audit_ENERGA_RUM_KONTRAHENCI_POWIAZANIA_row_object
  331. $mainNs = [
  332. 'Raport' => 'default_db__x3A__BI_audit_ENERGA_RUM_KONTRAHENCI_POWIAZANIA:BI_audit_ENERGA_RUM_KONTRAHENCI_POWIAZANIA',
  333. 'Path' => 'default_db__x3A__BI_audit_ENERGA_RUM_KONTRAHENCI_POWIAZANIA_row:BI_audit_ENERGA_RUM_KONTRAHENCI_POWIAZANIA_row',
  334. 'Point' => 'default_db__x3A__BI_audit_ENERGA_RUM_KONTRAHENCI_POWIAZANIA_row_object:BI_audit_ENERGA_RUM_KONTRAHENCI_POWIAZANIA_row_object',
  335. ];
  336. $listObjectsNs = $this->_getListPointChildNs();
  337. $outRefTables = array_merge(
  338. [ [ 'label' => 'Raport_to_Path', 'table' => ACL::getRefTable(Api_WfsNs::toNamespace($mainNs['Raport']), $mainNs['Path']) ] ],
  339. [ [ 'label' => 'Path_to_Point', 'table' => ACL::getRefTable(Api_WfsNs::toNamespace($mainNs['Path']), $mainNs['Point']) ] ],
  340. array_map(function ($objNs) use ($mainNs) {
  341. $objLabel = str_replace([ 'BI_audit_' ], '', substr($objNs, strrpos($objNs, ':') + 1));
  342. return [ 'label' => "Point_to_{$objLabel}", 'table' => ACL::getRefTable(Api_WfsNs::toNamespace($mainNs['Point']), $objNs) ];
  343. }, $listObjectsNs)
  344. );
  345. $nsToTableName = function ($objNs) {
  346. return substr($objNs, strrpos($objNs, ':') + 1);
  347. };
  348. $mainTables = array_map($nsToTableName, array_merge($mainNs));
  349. $refFromPointTables = array_map($nsToTableName, $listObjectsNs);
  350. $allTables = array_merge($mainTables, $refFromPointTables);
  351. DBG::log($allTables, 'array', '$allTables');
  352. $refTables = array_combine( array_map(V::makePick('label'), $outRefTables), array_map(V::makePick('table'), $outRefTables) );
  353. DBG::log($refTables, 'array', '$refTables');
  354. $listPointChildAlias = $this->_getListPointChildAlias();
  355. DBG::log($listPointChildAlias, 'array', '$listPointChildAlias');
  356. $sqlSelect = implode("\n , ", array_merge(
  357. array_map(function ($tbl, $key) {
  358. return "t_{$key}.ID as pk_{$key}";
  359. }, $mainTables, array_keys($mainTables)),
  360. array_map(function ($tbl, $key) use ($listPointChildAlias) {
  361. return "t_{$key}.ID as pk_{$listPointChildAlias[$key]}";
  362. }, $refFromPointTables, array_keys($refFromPointTables))
  363. ));
  364. $sqlTablesFrom = [];
  365. // return "\n" . "join `{$tableName}` `t_{$key}` on ( `t_{$key}`.ID = `t_{}` ) ";
  366. $sqlListFromJoin = [];
  367. $fromPointRefTables = array_slice(array_values($refTables), 2);
  368. for ($i = 0; $i < count($listObjectsNs); $i++) {
  369. $sqlListFromJoin[] = "
  370. left join `{$fromPointRefTables[$i]}` as r_Point_to_{$i} on ( r_Point_to_{$i}.PRIMARY_KEY = t_Point.ID )
  371. left join `{$allTables[$i]}` as t_{$i} on ( t_{$i}.ID = r_Point_to_{$i}.REMOTE_PRIMARY_KEY )
  372. ";
  373. }
  374. $sqlFromJoin = implode("\n", $sqlListFromJoin);
  375. $sql = "
  376. select {$sqlSelect}
  377. from `{$allTables['Raport']}` as t_Raport
  378. left join `{$refTables['Raport_to_Path']}` as r_Raport_to_Path on ( r_Raport_to_Path.PRIMARY_KEY = t_Raport.ID )
  379. left join `{$allTables['Path']}` as t_Path on ( t_Path.ID = r_Raport_to_Path.REMOTE_PRIMARY_KEY )
  380. left join `{$refTables['Path_to_Point']}` as r_Path_to_Point on ( r_Path_to_Point.PRIMARY_KEY = t_Path.ID )
  381. left join `{$allTables['Point']}` as t_Point on ( t_Point.ID = r_Path_to_Point.REMOTE_PRIMARY_KEY )
  382. {$sqlFromJoin}
  383. where t_Raport.ID = {$raportId}
  384. ";
  385. return DB::getPDO()->fetchAll($sql);
  386. }
  387. }