superedit-GRAPH_VIEW_PROCES copy.php 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516
  1. <?php
  2. function GRAPH_VIEW_PROCES() {
  3. $id_proces = V::get('id_proces', '', $_REQUEST, 'int');
  4. if ($id_proces <= 0) {
  5. echo'<p class="err box box-red">'."Wrong ID".'</p>';
  6. return;
  7. }
  8. $db = DB::getDB();
  9. $proces = $db->get_by_id('CRM_PROCES', $id_proces);
  10. if (!$proces) {
  11. echo'<p class="err box box-red">'."Process {$id_proces} not exists".'</p>';
  12. return;
  13. }
  14. $ajaxTask = V::get('ajaxTask', '', $_REQUEST);
  15. if ($ajaxTask == 'getInfo') {
  16. $id = V::get('id', 0, $_REQUEST, 'int');
  17. if ($id > 0) {
  18. $step = $db->get_by_id('CRM_PROCES', $id);
  19. //echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;"> (' . __CLASS__ . '::' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r($step);echo'</pre>';
  20. ?>
  21. <p><code><?php echo $step->ID; ?></code> <?php echo $step->DESC; ?></p>
  22. <p><?php echo $step->OPIS; ?></p>
  23. <?php
  24. }
  25. exit;
  26. }
  27. $graph = new stdClass();
  28. $graph->htmlID = 'graph_proces_id_' . $id_proces;
  29. $graph->procesTreeFlat = array();
  30. $graph->procesTreeGoto = array();
  31. $graph->treeItems = array();
  32. $graph->elements = new stdClass();
  33. $graph->elements->nodes = array();
  34. $graph->elements->edges = array();
  35. /* elements: {
  36. nodes: [
  37. { data: { id: 'j', name: 'Jerry' } },
  38. { data: { id: 'e', name: 'Elaine' } },
  39. { data: { id: 'k', name: 'Kramer' } },
  40. { data: { id: 'g', name: 'George' } }
  41. ],
  42. edges: [
  43. { data: { source: 'j', target: 'e' } },
  44. { data: { source: 'j', target: 'k' } },
  45. { data: { source: 'j', target: 'g' } },
  46. { data: { source: 'e', target: 'j' } },
  47. { data: { source: 'e', target: 'k' } },
  48. { data: { source: 'k', target: 'j' } },
  49. { data: { source: 'k', target: 'e' } },
  50. { data: { source: 'k', target: 'g' } },
  51. { data: { source: 'g', target: 'j' } }
  52. ]
  53. },
  54. */
  55. function graph__addNodeID($id, &$graph,$name=null,&$path,$parent=null,$type) {
  56. if (!array_key_exists($id, $graph->treeItems)) {
  57. $graph->treeItems[$id]= true;
  58. if(empty($name)) $name=$id;
  59. if(!empty($path)) { $name=$name." ".implode(',', $path);// $path=array();
  60. }
  61. //DEBUG_S(-3,'added id,name,path,parent',array($id,$name,$path,$parent),__FILE__,__FUNCTION__,__LINE__);
  62. if($type=='PROCES_INIT') $type_init='procesInit'; else $type_init=null;
  63. //echo $type_init.$id;
  64. $graph->elements->nodes[] = array('data'=>array('id'=>"".$id."", 'name'=>$name , 'type'=>$type_init));
  65. if(!empty($parent)) $graph->elements->edges[] = array('data'=>array('source'=>$parent, 'target'=>$id ));
  66. //echo "<br> w AddNode:";
  67. }
  68. }
  69. class crm_proces_paser {
  70. // var $this->get_proces_init=array();
  71. // [proces_init] - A
  72. // [step] - flat 0
  73. // [step] - flat 3 , tree 2 , cut
  74. // [step] - flat 0 , tree 0
  75. // [step] - flat 1 , tree 1
  76. // [step] - flat 1 , tree 1
  77. // [step] - flat 0 , tree 0
  78. // [step] - flat 1 , tree 1
  79. // [step] - flat 0 , tree 0
  80. function TestIfHasDeep($id_proces_step) {
  81. $sql="select `ID`,`IF_TRUE_GOTO` from `CRM_PROCES` where `PARENT_ID`=$id_proces_step and `A_STATUS` in ('WAITING','NORMAL') ";
  82. $res=DB::query($sql);
  83. while($h=DB::fetch($res)) {
  84. $ret[$h->ID]='PARENT_ID';
  85. }
  86. $sql="select `ID`,`IF_TRUE_GOTO`,`IF_TRUE_GOTO_FLAG` from `CRM_PROCES` where `ID`=$id_proces_step and `IF_TRUE_GOTO`>0 and `A_STATUS` in ('WAITING','NORMAL') ";
  87. $res=DB::query($sql);
  88. while($h=DB::fetch($res)) {
  89. $ret[$h->IF_TRUE_GOTO]=$h->IF_TRUE_GOTO_FLAG;
  90. }
  91. return $ret;
  92. }
  93. //funckcja do szukania proces_init
  94. function get_proces_init() {
  95. $sql= "select p.`ID`,`DESC` from `CRM_PROCES` as p where p.`A_STATUS` in('WAITING','NORMAL') and p.`TYPE`='PROCES_INIT' and ID=994 limit 1";
  96. echo $sql;
  97. $res=DB::query($sql);
  98. while($h=DB::fetch($res)) {
  99. $this->get_proces_init[]=$h->ID;
  100. }
  101. return $this->get_proces_init;
  102. }
  103. function build_proces_init_tree($id_proces) {
  104. // $tree->Childs[$id_proces]=true;
  105. $tree->Childs[$id_proces]->PARENT=0;
  106. $tree->Parents[0]->CHILD[$id_proces]=$id_proces;
  107. $obj=DB::get_by_id('CRM_PROCES',$id_proces);
  108. $tree->Childs[$id_proces]->TYPE=$obj->TYPE;
  109. self::build_tree_for_proces($tree,$id_proces);
  110. return $tree;
  111. }
  112. function build_tree_for_proces(&$tree,$cursor) {
  113. $sql="select `ID`,`IF_TRUE_GOTO`,`IF_TRUE_GOTO_FLAG` , `TYPE` from `CRM_PROCES` where PARENT_ID={$cursor} and `A_STATUS` in ('WAITING','NORMAL')";
  114. // echo "<br>sql: ".$sql;
  115. $res=DB::query($sql);
  116. while ($h=DB::fetch($res)) {
  117. $tree->Childs[$h->ID]->PARENT=$cursor;
  118. $tree->Parents[$cursor]->CHILD[$h->ID]=$h->ID;
  119. $tree->Childs[$h->ID]->TYPE=$h->TYPE;
  120. if($h->IF_TRUE_GOTO>0) {
  121. $tree->Childs[$h->ID]->GOTO_FLAG=$h->IF_TRUE_GOTO_FLAG;
  122. $tree->Childs[$h->ID]->IF_TRUE_GOTO=$h->IF_TRUE_GOTO;
  123. }
  124. self::build_tree_for_proces($tree,$h->ID);
  125. }
  126. }
  127. function build_tree_flat_info(&$tree,$flat) {
  128. /* >> zbudowanie ile ma dzieci <<
  129. $tree->Childs[3208] => stdClass Object
  130. (
  131. [PARENT] => 3123
  132. [CHILD] => Array
  133. (
  134. >> [3219] => 1 <<
  135. >> [3237] => 0 <<
  136. >> [3209] => 0 <<
  137. */
  138. foreach($tree->Childs as $id=>$obj) {
  139. //sprawdzmy czy nasz parent wymaga wyswietlenia osobnego podkroku w widoku szczegolowego procesu
  140. foreach($tree->Parents[$id]->CHILD as $child) {
  141. $tree->Childs[$id]->CHILD[$child]=count($tree->Parents[$child]->CHILD);
  142. }
  143. }
  144. }
  145. function detect_tree_where_to_detail_cut(&$tree) {
  146. foreach($tree->Childs as $id=>$obj) {
  147. //sprawdzmy czy nasz parent wymaga wyswietlenia osobnego podkroku w widoku szczegolowego procesu
  148. $control=0;
  149. foreach($obj->CHILD as $child) {
  150. if($child>0) $control++;
  151. }
  152. if($control>1) $tree->Childs[$id]->TO_DETAIL_CUT_FLAG=true;
  153. }
  154. }
  155. function search_parent_ids_till_cut($tree,$init,&$find) {
  156. if(!isset($tree->Childs[$init]->TO_DETAIL_CUT_FLAG)) {
  157. $find[]=$init;
  158. // self::zoom_process_links($tree,$init);
  159. foreach($tree->Childs[$init]->CHILD as $id=>$count) {
  160. self::search_parent_ids_till_cut($tree,$id,$find);
  161. }
  162. }
  163. }
  164. function zoom_process_links($tree,$id,$root_id) {
  165. if(isset($tree->Childs[$id]->GOTO_FLAG)) {
  166. if(isset( $tree->Childs[$tree->Childs[$id]->IF_TRUE_GOTO])) {
  167. //adding internal link to the same process
  168. $tree->Viev_Zpc[$id]->INTERNAL_LINK[$tree->Childs[$id]->IF_TRUE_GOTO]=$tree->Childs[$id]->IF_TRUE_GOTO;
  169. } else { echo "<br>Links zewnetrzny do ".$id." - ".$tree->Childs[$id]->IF_TRUE_GOTO;
  170. $tree->Viev_Zpc[$id]->EXTERNAL_LINK[$tree->Childs[$id]->IF_TRUE_GOTO]=$tree->Childs[$id]->IF_TRUE_GOTO;
  171. }
  172. }
  173. }
  174. function build_path_zoom_proces_cut(&$tree,$init,$path_zpc=array()) {
  175. //funkcja do pokazania procesow wyplaszczonych, z wypunktowanymi rozgalezieniami - buduje drzewo w sposob inteligentny
  176. //szukam rekordow z gory do pierwszego CUT
  177. foreach($tree->Childs as $id=>$obj) {
  178. if(!isset($tree->Viev_Zpc_found[$id])) {
  179. //echo "<br>szukam parentow dla ".$id;
  180. self::search_parent_ids_till_cut($tree,$id,$find);
  181. //echo "<br>find:";print_r($find);
  182. foreach($find as $find_id) {
  183. $tree->Viev_Zpc_found[$find_id]=$find[0];
  184. }
  185. $tree->Viev_Zpc[$id]->PATH=$find;
  186. unset($find);
  187. }
  188. }
  189. }
  190. }
  191. $cp=new crm_proces_paser;
  192. $PROC_GET=1349;
  193. $PROC_GET=$id_proces;
  194. $init=$cp->get_proces_init();
  195. $tree=$cp->build_proces_init_tree($PROC_GET);
  196. $cp->build_tree_flat_info($tree,null);
  197. $cp->detect_tree_where_to_detail_cut($tree);
  198. $cp->build_path_zoom_proces_cut($tree,$PROC_GET);
  199. DEBUG_S(-3,'get_proces_init',$init);
  200. DEBUG_S(-3,'tree->childs',$tree->Childs);
  201. DEBUG_S(-3,'tree->Parents',$tree->Parents);
  202. DEBUG_S(-3,'tree->Viev_Zpc',$tree->Viev_Zpc);
  203. graph__addNodeID(0, &$graph,$name=null,$path,null);
  204. foreach($tree->Viev_Zpc as $id=>$obj) {
  205. graph__addNodeID($id, &$graph,$name=null,$obj->PATH,$tree->Childs[$id]->PARENT,$tree->Childs[$id]->TYPE);
  206. foreach($obj->INTERNAL_LINK as $link) graph__addNodeID($id, &$graph,$name=null,$obj->PATH,$link,null);
  207. }
  208. /*
  209. $db = DB::getDB();
  210. $sql= "select p.`ID`,`DESC` from `CRM_PROCES` as p where p.`A_STATUS` in('WAITING','NORMAL') and p.`TYPE`='PROCES_INIT' and ID=994 limit 1";
  211. $res=DB::query($sql);
  212. while($h=DB::fetch($res)) {
  213. SearchParentsWithExits($h->ID,$h->ID,$graph,'Proces '.$h->ID,0);
  214. //graph__addNodeID($h->ID, $graph);
  215. graph__addNodeID('1', $graph,'1');
  216. // graph__addNodeID($h->ID, $graph,$h->ID);
  217. // graph__addNodeID('100', $graph,'100');
  218. //$graph->treeItems[$h->ID] = true;
  219. //$graph->treeItems[101] = true;
  220. // $graph->elements->nodes[] = array('data'=>array('id'=>$h->ID, 'name'=>$h->ID , 'type'=>'procesInit'));
  221. // $graph->elements->nodes[] = array('data'=>array('id'=>101, 'name'=>101 , 'type'=>'procesInit'));
  222. // $graph->elements->edges[] = array('data'=>array('source'=>994, 'target'=>101));
  223. }
  224. */
  225. foreach($graph->elements->nodes as $var) {
  226. // echo "<br>\n NODE".$var[data][id];
  227. $nodes[$var[data][id]]=$var[data][id];
  228. }
  229. foreach($graph->elements->edges as $var) {
  230. echo "<br>\n".$var[data][source]." ".$var[data][target]." ";
  231. if(isset($nodes[$var[data][source]])) echo "OK1"; else echo "FAIL1";
  232. if(isset($nodes[$var[data][target]])) echo "OK2"; else echo "FAIL2";
  233. }
  234. DEBUG_S(-3,'nodes',$graph->elements->nodes);
  235. DEBUG_S(-3,'edges',$graph->elements->edges);
  236. /*
  237. $sql = "select p.`ID`, p.`PARENT_ID`
  238. from `CRM_PROCES` as p
  239. where p.`A_STATUS` in('WAITING','NORMAL')
  240. ";
  241. $res = $db->query($sql);
  242. while ($r = $db->fetch($res)) {
  243. $graph->procesTreeFlat[$r->PARENT_ID] []= $r->ID;
  244. }
  245. $sql = "select p.`IF_TRUE_GOTO` as ID, p.`ID` as PARENT_ID
  246. from `CRM_PROCES` as p
  247. where p.`A_STATUS` in('WAITING','NORMAL')
  248. and p.IF_TRUE_GOTO>0
  249. -- and p.IF_TRUE_GOTO_FLAG='GOTO_AND_RETURN'
  250. ";
  251. $res = $db->query($sql);
  252. while ($r = $db->fetch($res)) {
  253. $graph->procesTreeGoto[$r->PARENT_ID] []= $r->ID;
  254. }
  255. function createGraphRec($id, $tree, &$graph, $lvl = 0) {
  256. $graph->treeItems[$id] = true;
  257. settype($id, 'string');
  258. if ($id == 3122) {
  259. $graph->elements->nodes[] = array('data'=>array('id'=>$id, 'name'=>$id, 'type'=>'procesInit', 'lvl'=>$lvl));
  260. } else {
  261. $graph->elements->nodes[] = array('data'=>array('id'=>$id, 'name'=>$id, 'lvl'=>$lvl));
  262. }
  263. if ($lvl > 1) {
  264. // return;
  265. }
  266. if (!empty($tree[$id])) {
  267. foreach ($tree[$id] as $vChildID) {
  268. $graph->elements->edges[] = array('data'=>array('source'=>$id, 'target'=>$vChildID));
  269. createGraphRec($vChildID, $tree, $graph, $lvl + 1);
  270. }
  271. }
  272. }
  273. createGraphRec($id_proces, $graph->procesTreeFlat, $graph);
  274. */
  275. /*
  276. // addGraphGoto
  277. foreach ($graph->procesTreeGoto as $kID => $vGotoIds) {
  278. //$graph->treeItems[$id] = true;
  279. if (array_key_exists($kID, $graph->treeItems)) {
  280. foreach ($vGotoIds as $vGotoID) {
  281. graph__addNodeID($vGotoID, $graph);
  282. $graph->elements->edges[] = array('data'=>array('source'=>$kID, 'target'=>$vGotoID, 'type'=>'GOTO'));
  283. }
  284. } else {
  285. foreach ($vGotoIds as $vGotoID) {
  286. if (array_key_exists($vGotoID, $graph->treeItems)) {
  287. //echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;"> (' . __CLASS__ . '::' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r("TODO: add node ($kID); add edge from $kID to $vGotoID");echo'</pre>';
  288. graph__addNodeID($kID, $graph);
  289. //$graph->elements->edges[] = array('data'=>array('source'=>$kID, 'target'=>$vGotoID, 'type'=>'GOTO'));
  290. }
  291. }
  292. }
  293. }
  294. */
  295. ?>
  296. <style type="text/css">
  297. #<?php echo $graph->htmlID; ?>_wrap {
  298. position:relative;
  299. width:1100px;
  300. margin:0 auto;
  301. border:1px solid #ccc;
  302. }
  303. #<?php echo $graph->htmlID; ?> {
  304. height:560px;
  305. border-bottom:1px solid #ccc;
  306. }
  307. #<?php echo $graph->htmlID; ?>_info {
  308. padding:3px;
  309. }
  310. #<?php echo $graph->htmlID; ?>_wrap .actions { position:absolute; top:20px; left:-40px; margin:0; padding:0; list-style:none; }
  311. #<?php echo $graph->htmlID; ?>_wrap .actions button { border-radius:0; background:#fff; border:1px solid #ccc; }
  312. </style>
  313. <script src="./stuff/cytoscape.js/arbor.js"></script>
  314. <script src="./stuff/cytoscape.js/cytoscape.js"></script>
  315. <script>
  316. jQuery(loadInfo = function(nodeID){
  317. $.ajax({
  318. url: 'index.php?MENU_INIT=GRAPH_VIEW_PROCES&id_proces=<?php echo $id_proces; ?>&ajaxTask=getInfo&id=' + nodeID + '&HEADER_NOT_INIT=YES',
  319. type: 'GET',
  320. dataType: 'text',
  321. data: '',
  322. async: true,
  323. success: function (data) {
  324. jQuery('#<?php echo $graph->htmlID; ?>_info').html(data);
  325. },
  326. error: function (err) {
  327. console.log('err');
  328. }
  329. });
  330. });
  331. jQuery(loadCy = function(){
  332. jQuery('#<?php echo $graph->htmlID; ?>').cytoscape({
  333. layout: {
  334. name: 'arbor'
  335. },
  336. style: cytoscape.stylesheet()
  337. .selector('node')
  338. .css({
  339. 'shape': 'rectangle',
  340. 'width': '46px', 'height': '26px',
  341. 'font-size': '10px',
  342. 'content': 'data(name)',
  343. 'text-valign': 'center',
  344. 'color': 'white',
  345. 'text-outline-width': 2,
  346. 'text-outline-color': '#888'
  347. })
  348. .selector('edge')
  349. .css({
  350. 'target-arrow-shape': 'triangle'
  351. })
  352. .selector(':selected')
  353. .css({
  354. 'background-color': 'black',
  355. 'line-color': 'black',
  356. 'target-arrow-color': 'black',
  357. 'source-arrow-color': 'black'
  358. })
  359. .selector('.faded')
  360. .css({
  361. 'opacity': 0.25,
  362. 'text-opacity': 0
  363. })
  364. .selector('edge.neighborhood')
  365. .css({
  366. 'background-color': 'blue',
  367. 'color': 'orange'
  368. })
  369. .selector('node.procesInit')
  370. .css({
  371. 'background-color': 'red',
  372. 'text-outline-color': 'red',
  373. 'font-weight': 'bold'
  374. }),
  375. elements: <?php echo json_encode($graph->elements); ?>,
  376. ready: function(){
  377. var cy = this;
  378. window.cy_<?php echo $graph->htmlID; ?> = this;
  379. cy.elements("node[type = 'procesInit']").addClass('procesInit');
  380. cy.elements("node[lvl > 1]").hide();
  381. cy.elements().unselectify();
  382. cy.on('tap', 'node', function(e){
  383. //console.log('on tap node', e)
  384. var node = e.cyTarget;
  385. var neighborhood = node.neighborhood().add(node);
  386. var nodeID = node.id();
  387. loadInfo(nodeID);
  388. cy.elements().addClass('faded').unselect();
  389. neighborhood.removeClass('faded');
  390. node.select();
  391. cy.edges().removeClass('neighborhood');
  392. node.connectedEdges().addClass('neighborhood');
  393. neighborhood.show();
  394. cy.center(neighborhood);
  395. });
  396. cy.on('tap', function(e){
  397. if (e.cyTarget === cy){
  398. cy.elements().removeClass('faded');
  399. }
  400. });
  401. },
  402. showOverlay: false
  403. });
  404. });
  405. jQuery(document).ready(function(){
  406. loadCy();
  407. var parent = $('#<?php echo $graph->htmlID; ?>')
  408. .parent()
  409. parent.find('.actions .cy-refresh')
  410. .on('mousedown touchstart', function(){
  411. loadCy();
  412. cy.attr('style', '');
  413. });
  414. parent.find('.actions .cy-zoom-plus')
  415. .on('mousedown touchstart', function(){
  416. window.cy_<?php echo $graph->htmlID; ?>.zoom(window.cy_<?php echo $graph->htmlID; ?>.zoom() + 0.1);
  417. });
  418. parent.find('.actions .cy-zoom-minus')
  419. .on('mousedown touchstart', function(){
  420. window.cy_<?php echo $graph->htmlID; ?>.zoom(window.cy_<?php echo $graph->htmlID; ?>.zoom() - 0.1);
  421. });
  422. });
  423. </script>
  424. <div id="<?php echo $graph->htmlID; ?>_wrap">
  425. <div id="<?php echo $graph->htmlID; ?>"></div>
  426. <div id="<?php echo $graph->htmlID; ?>_info"></div>
  427. <ul class="actions">
  428. <li><button class="btn cy-refresh"><i title="Refresh" class="ico-refresh"></i></button></li>
  429. <li><button class="btn cy-zoom-plus"><i title="Zoom +" class="ico-plus"></i></button></li>
  430. <li><button class="btn cy-zoom-minus"><i title="Zoom -" class="ico-minus"></i></button></li>
  431. </ul>
  432. </div>
  433. <?php
  434. }