BiAuditGraph.php 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390
  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. $listPathLength = array_reduce($matrix, function ($ret, $item) {
  115. $ret[ $item['pk_Path'] ] = 1 + V::get($item['pk_Path'], 0, $ret);
  116. return $ret;
  117. }, []);
  118. $listPathPk = array_keys($listPathLength);
  119. $pointOccurs = array_reduce($matrix, function ($ret, $item) use ($listPointChildAlias) {
  120. foreach ($listPointChildAlias as $alias) {
  121. $pkField = "pk_{$alias}";
  122. if ($item[$pkField]) {
  123. $featureId = "{$alias}.{$item[$pkField]}";
  124. $ret[$featureId] = 1 + V::getValue($ret[$featureId], 0);
  125. }
  126. }
  127. return $ret;
  128. }, []);
  129. asort($pointOccurs);
  130. DBG::log($pointOccurs, 'array', '$pointOccurs');
  131. $getPointFeatureIdFromPath = function ($item) {
  132. $listPointChildAlias = $this->_getListPointChildAlias();
  133. return array_reduce($listPointChildAlias, function ($ret, $objAlias) use ($item) {
  134. $pk = V::get("pk_{$objAlias}", 0, $item);
  135. if ($pk) $ret = "{$objAlias}.{$pk}";
  136. return $ret;
  137. }, null);
  138. };
  139. $prevItem = [];
  140. $edges = array_reduce($matrix, function ($ret, $item) use (&$prevItem, $getPointFeatureIdFromPath) {
  141. if (!empty($prevItem) && $prevItem['pk_Path'] === $item['pk_Path']) {
  142. $ret[] = [ 'source' => $getPointFeatureIdFromPath($prevItem), 'target' => $getPointFeatureIdFromPath($item), 'pathId' => $item['pk_Path'] ];
  143. $prevItem = array_merge([], $item);
  144. return $ret;
  145. } else {
  146. $prevItem = array_merge([], $item);
  147. return $ret;
  148. }
  149. }, []);
  150. DBG::log("edges - done");
  151. $prevFeaturesOnPath = [];
  152. $prevPathId = 0;
  153. $allToAllEdges = array_reduce($matrix, function ($ret, $item) use (&$prevFeaturesOnPath, &$prevPathId, $getPointFeatureIdFromPath) {
  154. $curFeatureId = $getPointFeatureIdFromPath($item);
  155. if (!empty($prevFeaturesOnPath) && $prevPathId === $item['pk_Path']) {
  156. foreach ($prevFeaturesOnPath as $idx => $prevFeatureId) {
  157. $ret[] = [ 'source' => $prevFeatureId, 'target' => $curFeatureId, 'pathId' => $item['pk_Path'], 'length' => (1 + $idx) ];
  158. }
  159. array_unshift($prevFeaturesOnPath, $curFeatureId);
  160. $prevPathId = $item['pk_Path'];
  161. return $ret;
  162. } else {
  163. $prevFeaturesOnPath = [ $curFeatureId ];
  164. $prevPathId = $item['pk_Path'];
  165. return $ret;
  166. }
  167. }, []);
  168. DBG::log("edges_all_to_all - done");
  169. $stats = [];
  170. // $stats['path_length'] = $listPathLength;
  171. $stats['path_total'] = count($listPathLength);
  172. $stats['point_total'] = count($matrix);
  173. $stats['point_occurs'] = $pointOccurs;
  174. $stats['edges_all_to_all'] = $allToAllEdges;
  175. $stats['edges'] = $edges;
  176. $stats['nodes'] = array_map([ $this, 'getFeature' ], array_keys($pointOccurs));
  177. return $stats;
  178. }
  179. function getFeature($featureId) {
  180. list($objectName, $primaryKey) = explode(".", $featureId);
  181. if (!$objectName) throw new Exception("Wrong featureId '{$featureId}' - missing objectName");
  182. if (!$primaryKey) throw new Exception("Wrong featureId '{$featureId}' - missing primaryKey");
  183. $tableName = $objectName;
  184. $item = DB::getPDO()->fetchFirst(" select * from `{$tableName}` where id = :id ", [ ':id' => $primaryKey ]);
  185. $getLabel = [ $this, '_getFeatureLabel' ];
  186. return array_merge($item, [
  187. '@label' => $getLabel($objectName, $item), // TODO: label depend on table / later format from xsd
  188. '@object' => $objectName,
  189. '@primaryKey' => $primaryKey,
  190. ]);
  191. }
  192. function _getFeatureLabel($objectName, $item) {
  193. $primaryKey = $item['@primaryKey'];
  194. switch ($objectName) {
  195. case 'BI_audit_ENERGA_RUM_KONTRAHENCI': return V::get('Pelna_nazwa_kontrahenta', $primaryKey, $item);
  196. case 'BI_audit_MSIG': return V::get('nazwa', $primaryKey, $item);
  197. case 'BI_audit_MSIG_person': return V::getValue(
  198. implode(" ", array_filter([
  199. V::get('imiona', '', $item),
  200. V::get('nazwisko', '', $item)
  201. ], 'strlen'))
  202. , "{$objectName} Nr {$primaryKey}"
  203. );
  204. case 'BI_audit_CEIDG': return V::get('firma', $primaryKey, $item);
  205. case 'BI_audit_KRS': return V::get('nazwa', $primaryKey, $item);
  206. case 'BI_audit_KRS_person': return V::getValue(
  207. implode(" ", array_filter([
  208. V::get('imiona', '', $item),
  209. V::get('nazwisko', '', $item)
  210. ], 'strlen'))
  211. , "{$objectName} Nr {$primaryKey}"
  212. );
  213. case 'BI_audit_MSIG_company': return V::get('nazwa', $primaryKey, $item);
  214. case 'BI_audit_KRS_company': return V::get('nazwa', $primaryKey, $item);
  215. case 'TERYT_adresy': return "TERYT({$item['TERYT_SYM']}/{$item['TERYT_SYM_UL']})";
  216. case 'BI_audit_MSIG_address': return V::getValue(
  217. implode(", ", array_filter([
  218. implode(" ", array_filter([
  219. V::get('A_kod', '', $item),
  220. V::get('S_miejscowosc', '', $item)
  221. ], 'strlen')),
  222. implode(" ", array_filter([
  223. V::get('A_nrDomu', '', $item),
  224. V::get('A_nrDomu', '', $item),
  225. V::get('A_nrLokalu', '', $item)
  226. ], 'strlen'))
  227. ], 'strlen'))
  228. , "{$objectName} Nr {$primaryKey}"
  229. );
  230. default: return "TODO: {$objectName} Nr {$primaryKey}";
  231. }
  232. }
  233. function sendJsonStats($raportId, $stats) {
  234. Response::sendJson([
  235. 'type' => "success",
  236. 'msg' => "OK",
  237. 'body' => $stats
  238. ]);
  239. die();
  240. }
  241. function sendXmlStats($raportId, $stats) {
  242. print_r($stats);
  243. }
  244. function sendHtmlStats($raportId, $stats) {
  245. UI::gora();
  246. DBG::nicePrint($stats, "\$stats");
  247. $dbgNode = function ($item) {
  248. return [
  249. 'object' => $item['@object'],
  250. 'primaryKey' => $item['@primaryKey'],
  251. 'label' => $item['@label'],
  252. ];
  253. };
  254. UI::table([ 'rows' => array_map($dbgNode, $stats['nodes']) ]);
  255. UI::dol();
  256. }
  257. function raportView($args) {
  258. $raportId = V::get('raportId', 0, $args, 'int');
  259. $featureId = V::get('featureId', '', $args, '');
  260. $h = [ 'UI', 'h' ];
  261. echo $h('div', [ 'id' => "bi_audit_raport-network_graph" ], "TODO: loading data...");
  262. echo $h('script', ['src'=>"static/vendor.js?v=a76e2988", 'type'=>"text/javascript"]);
  263. echo $h('script', [ 'src' => "static/visjs/vis.min.js" ]);
  264. $stats = $this->getOutputStats($raportId);
  265. echo UI::h('link', [ 'href' => 'static/react-bootstrap-typeahead.min.css', 'type' => 'text/css', 'rel' => 'stylesheet' ]);
  266. UI::inlineJS(__FILE__ . '.network-graph.js', [
  267. 'HTML_ID_REF_GRAPH' => 'bi_audit_raport-network_graph',
  268. // 'TYPENAME' => Api_WfsNs::typeName($namespace),
  269. // 'PRIMARY_KEY' => $primaryKey,
  270. // 'WFS_URL' => Router::getRoute('WfsBiAudit')->getLink(),
  271. 'RAPORT_ID' => $raportId,
  272. 'API_URL' => $this->getLink('raportOutputStats', [ 'outputFormat' => "json", 'raportId' => $raportId ]),
  273. 'STATS' => $stats,
  274. 'DBG' => (V::get('DBG', 0, $_GET, 'int') > 0),
  275. ]);
  276. $this->getRaportOutputMatrix($raportId); // TODO: DBG
  277. }
  278. function getRaportNetworkGraphDataAjaxAction() {
  279. }
  280. function _getListPointChildNs() {
  281. $listObjectsNs = [];
  282. $listObjectsNs[] = 'default_db__x3A__BI_audit_CEIDG:BI_audit_CEIDG';
  283. $listObjectsNs[] = 'default_db__x3A__BI_audit_CEIDG_pelnomocnicy:BI_audit_CEIDG_pelnomocnicy';
  284. $listObjectsNs[] = 'default_db__x3A__BI_audit_CEIDG_powiazania:BI_audit_CEIDG_powiazania';
  285. $listObjectsNs[] = 'default_db__x3A__BI_audit_ENERGA_PRACOWNICY:BI_audit_ENERGA_PRACOWNICY';
  286. $listObjectsNs[] = 'default_db__x3A__BI_audit_ENERGA_PRACOWNICY_adresy:BI_audit_ENERGA_PRACOWNICY_adresy';
  287. $listObjectsNs[] = 'default_db__x3A__BI_audit_ENERGA_RUM_KONTRAHENCI:BI_audit_ENERGA_RUM_KONTRAHENCI';
  288. $listObjectsNs[] = 'default_db__x3A__BI_audit_KRS:BI_audit_KRS';
  289. $listObjectsNs[] = 'default_db__x3A__BI_audit_KRS_address:BI_audit_KRS_address';
  290. $listObjectsNs[] = 'default_db__x3A__BI_audit_KRS_company:BI_audit_KRS_company';
  291. $listObjectsNs[] = 'default_db__x3A__BI_audit_KRS_person:BI_audit_KRS_person';
  292. $listObjectsNs[] = 'default_db__x3A__BI_audit_KW_requested_person:BI_audit_KW_requested_person';
  293. $listObjectsNs[] = 'default_db__x3A__BI_audit_MSIG:BI_audit_MSIG';
  294. $listObjectsNs[] = 'default_db__x3A__BI_audit_MSIG_address:BI_audit_MSIG_address';
  295. $listObjectsNs[] = 'default_db__x3A__BI_audit_MSIG_company:BI_audit_MSIG_company';
  296. $listObjectsNs[] = 'default_db__x3A__BI_audit_MSIG_person:BI_audit_MSIG_person';
  297. $listObjectsNs[] = 'default_db__x3A__TERYT_adresy:TERYT_adresy';
  298. return $listObjectsNs;
  299. }
  300. function _getListPointChildAlias() {
  301. return array_map(function ($objNs) {
  302. // return str_replace([ 'BI_audit_' ], '', substr($objNs, strrpos($objNs, ':') + 1));
  303. return substr($objNs, strrpos($objNs, ':') + 1);
  304. }, $this->_getListPointChildNs());
  305. }
  306. function getRaportOutputMatrix($raportId) {
  307. // Main Raport Acl NS: default_db__x3A__BI_audit_ENERGA_RUM_KONTRAHENCI_POWIAZANIA:BI_audit_ENERGA_RUM_KONTRAHENCI_POWIAZANIA
  308. // - Found Paths in: default_db__x3A__BI_audit_ENERGA_RUM_KONTRAHENCI_POWIAZANIA_row:BI_audit_ENERGA_RUM_KONTRAHENCI_POWIAZANIA_row
  309. // - Path Points in: default_db__x3A__BI_audit_ENERGA_RUM_KONTRAHENCI_POWIAZANIA_row_object:BI_audit_ENERGA_RUM_KONTRAHENCI_POWIAZANIA_row_object
  310. $mainNs = [
  311. 'Raport' => 'default_db__x3A__BI_audit_ENERGA_RUM_KONTRAHENCI_POWIAZANIA:BI_audit_ENERGA_RUM_KONTRAHENCI_POWIAZANIA',
  312. 'Path' => 'default_db__x3A__BI_audit_ENERGA_RUM_KONTRAHENCI_POWIAZANIA_row:BI_audit_ENERGA_RUM_KONTRAHENCI_POWIAZANIA_row',
  313. 'Point' => 'default_db__x3A__BI_audit_ENERGA_RUM_KONTRAHENCI_POWIAZANIA_row_object:BI_audit_ENERGA_RUM_KONTRAHENCI_POWIAZANIA_row_object',
  314. ];
  315. $listObjectsNs = $this->_getListPointChildNs();
  316. $outRefTables = array_merge(
  317. [ [ 'label' => 'Raport_to_Path', 'table' => ACL::getRefTable(Api_WfsNs::toNamespace($mainNs['Raport']), $mainNs['Path']) ] ],
  318. [ [ 'label' => 'Path_to_Point', 'table' => ACL::getRefTable(Api_WfsNs::toNamespace($mainNs['Path']), $mainNs['Point']) ] ],
  319. array_map(function ($objNs) use ($mainNs) {
  320. $objLabel = str_replace([ 'BI_audit_' ], '', substr($objNs, strrpos($objNs, ':') + 1));
  321. return [ 'label' => "Point_to_{$objLabel}", 'table' => ACL::getRefTable(Api_WfsNs::toNamespace($mainNs['Point']), $objNs) ];
  322. }, $listObjectsNs)
  323. );
  324. $nsToTableName = function ($objNs) {
  325. return substr($objNs, strrpos($objNs, ':') + 1);
  326. };
  327. $mainTables = array_map($nsToTableName, array_merge($mainNs));
  328. $refFromPointTables = array_map($nsToTableName, $listObjectsNs);
  329. $allTables = array_merge($mainTables, $refFromPointTables);
  330. DBG::log($allTables, 'array', '$allTables');
  331. $refTables = array_combine( array_map(V::makePick('label'), $outRefTables), array_map(V::makePick('table'), $outRefTables) );
  332. DBG::log($refTables, 'array', '$refTables');
  333. $listPointChildAlias = $this->_getListPointChildAlias();
  334. DBG::log($listPointChildAlias, 'array', '$listPointChildAlias');
  335. $sqlSelect = implode("\n , ", array_merge(
  336. array_map(function ($tbl, $key) {
  337. return "t_{$key}.ID as pk_{$key}";
  338. }, $mainTables, array_keys($mainTables)),
  339. array_map(function ($tbl, $key) use ($listPointChildAlias) {
  340. return "t_{$key}.ID as pk_{$listPointChildAlias[$key]}";
  341. }, $refFromPointTables, array_keys($refFromPointTables))
  342. ));
  343. $sqlTablesFrom = [];
  344. // return "\n" . "join `{$tableName}` `t_{$key}` on ( `t_{$key}`.ID = `t_{}` ) ";
  345. $sqlListFromJoin = [];
  346. $fromPointRefTables = array_slice(array_values($refTables), 2);
  347. for ($i = 0; $i < count($listObjectsNs); $i++) {
  348. $sqlListFromJoin[] = "
  349. left join `{$fromPointRefTables[$i]}` as r_Point_to_{$i} on ( r_Point_to_{$i}.PRIMARY_KEY = t_Point.ID )
  350. left join `{$allTables[$i]}` as t_{$i} on ( t_{$i}.ID = r_Point_to_{$i}.REMOTE_PRIMARY_KEY )
  351. ";
  352. }
  353. $sqlFromJoin = implode("\n", $sqlListFromJoin);
  354. $sql = "
  355. select {$sqlSelect}
  356. from `{$allTables['Raport']}` as t_Raport
  357. left join `{$refTables['Raport_to_Path']}` as r_Raport_to_Path on ( r_Raport_to_Path.PRIMARY_KEY = t_Raport.ID )
  358. left join `{$allTables['Path']}` as t_Path on ( t_Path.ID = r_Raport_to_Path.REMOTE_PRIMARY_KEY )
  359. left join `{$refTables['Path_to_Point']}` as r_Path_to_Point on ( r_Path_to_Point.PRIMARY_KEY = t_Path.ID )
  360. left join `{$allTables['Point']}` as t_Point on ( t_Point.ID = r_Path_to_Point.REMOTE_PRIMARY_KEY )
  361. {$sqlFromJoin}
  362. where t_Raport.ID = {$raportId}
  363. ";
  364. return DB::getPDO()->fetchAll($sql);
  365. }
  366. }