superedit-GRAPH_VIEW_PROCES.php 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667
  1. <?php
  2. class crm_proces_paser {
  3. // var $this->get_proces_init=array();
  4. // [proces_init] - A
  5. // [step] - flat 0
  6. // [step] - flat 3 , tree 2 , cut
  7. // [step] - flat 0 , tree 0
  8. // [step] - flat 1 , tree 1
  9. // [step] - flat 1 , tree 1
  10. // [step] - flat 0 , tree 0
  11. // [step] - flat 1 , tree 1
  12. // [step] - flat 0 , tree 0
  13. //funckcja do szukania proces_init
  14. function get_proces_init($id_proces) {
  15. $sql= "select p.`ID`,p.`DESC` from `CRM_PROCES` as p
  16. LEFT JOIN _CRM_PROCES_INIT_STATS AS cs ON cs.ID = p.ID
  17. where p.`A_STATUS` in('WAITING','NORMAL') and p.`TYPE`='PROCES_INIT'
  18. and (cs.`path` like '%/".$id_proces."/%' or cs.`path` like '%/".$id_proces."' or cs.`path` like '".$id_proces."/%' )
  19. ";
  20. // echo $sql;
  21. $res=DB::query($sql);
  22. while($h=DB::fetch($res)) {
  23. $this->get_proces_init[]=$h->ID;
  24. }
  25. return $this->get_proces_init;
  26. }
  27. function build_proces_init_tree($id_proces) {
  28. // $tree->Childs[$id_proces]=true;
  29. $tree->Childs[$id_proces]->PARENT=0;
  30. $tree->Childs[$id_proces]->SOURCE='build_tree_for_proces';
  31. $tree->Parents[0]->CHILD[$id_proces]=$id_proces;
  32. $obj=DB::get_by_id('CRM_PROCES',$id_proces);
  33. $tree->Childs[$id_proces]->TYPE=$obj->TYPE;
  34. // echo "here".$id_proces;
  35. self::build_tree_for_proces($tree,$id_proces,$id_proces);
  36. return $tree;
  37. }
  38. function build_tree_for_proces(&$tree,$cursor,$init_once=null) {
  39. if(!empty($init_once)) $sql_or=" or ID={$init_once} "; else $sql_or="";
  40. $sql="select `ID`,`IF_TRUE_GOTO`,`IF_TRUE_GOTO_FLAG` , `TYPE` from `CRM_PROCES` where ( PARENT_ID={$cursor} {$sql_or} ) and `A_STATUS` in ('WAITING','NORMAL')";
  41. // echo "<br>sql: ".$sql;
  42. $res=DB::query($sql);
  43. while ($h=DB::fetch($res)) {
  44. if(empty($init_once)) $tree->Childs[$h->ID]->PARENT=$cursor; //wyzwolenie tylko pozniejsze
  45. if(empty($init_once)) $tree->Parents[$cursor]->CHILD[$h->ID]=$h->ID;
  46. $tree->Childs[$h->ID]->TYPE=$h->TYPE;
  47. $tree->Childs[$h->ID]->SOURCE='build_tree_for_proces';
  48. if($h->IF_TRUE_GOTO>0) {
  49. $tree->Childs[$h->ID]->GOTO_FLAG=$h->IF_TRUE_GOTO_FLAG;
  50. $tree->Childs[$h->ID]->IF_TRUE_GOTO=$h->IF_TRUE_GOTO;
  51. $tree->Childs[$h->IF_TRUE_GOTO]->IS_EXECUTED_BY[$h->ID]=$h->ID;
  52. }
  53. self::build_tree_for_proces($tree,$h->ID,null);
  54. }
  55. }
  56. function build_tree_flat_info(&$tree,$flat) {
  57. /* >> zbudowanie ile ma dzieci <<
  58. $tree->Childs[3208] => stdClass Object
  59. (
  60. [PARENT] => 3123
  61. [CHILD] => Array
  62. (
  63. >> [3219] => 1 <<
  64. >> [3237] => 0 <<
  65. >> [3209] => 0 <<
  66. */
  67. foreach($tree->Childs as $id=>$obj) {
  68. //sprawdzmy czy nasz parent wymaga wyswietlenia osobnego podkroku w widoku szczegolowego procesu
  69. foreach($tree->Parents[$id]->CHILD as $child) {
  70. $tree->Childs[$id]->CHILD[$child]=count($tree->Parents[$child]->CHILD);
  71. }
  72. }
  73. }
  74. function detect_tree_where_to_detail_cut(&$tree,$flag_not_to_cut=null) {
  75. foreach($tree->Childs as $id=>$obj) {
  76. //sprawdzmy czy nasz parent wymaga wyswietlenia osobnego podkroku w widoku szczegolowego procesu
  77. $control=0;
  78. foreach($obj->CHILD as $child) {
  79. if($child>0) $control++;
  80. }
  81. if(empty($flag_not_to_cut)) {
  82. if($control>1) $tree->Childs[$id]->TO_DETAIL_CUT_FLAG=true; //przeciecie jezeli jest wiecej wyjsc niz jedno z zaglebieniami
  83. //przeciecie, jezeli jest wyjscie z kroku procesu do innego
  84. if(isset($tree->Childs[$id]->GOTO_FLAG)) $tree->Childs[$id]->TO_DETAIL_CUT_FLAG=true;
  85. //trzeba zbadac tez czy nie jest do niego dowiazywany w jakims miejscu proces
  86. if(isset($tree->Childs[$id]->IS_EXECUTED_BY)) { $tree->Childs[$id]->TO_DETAIL_CUT_FLAG=true;
  87. //echo "<br> Is executed by CUT!";
  88. }
  89. } else $tree->Childs[$id]->NO_CUT_FLAG=true;
  90. }
  91. }
  92. function search_parent_ids_till_cut(&$tree,$init,&$find) {
  93. //szukam lancuchow do optymalizacji do miejsca flagi CUT, kojarzac od razu linki
  94. if(isset($tree->Childs[$init]->TO_DETAIL_CUT_FLAG)) {
  95. //if(!empty($find))
  96. //if($init==2444)
  97. self::zoom_process_links($tree,$init,$init);
  98. }
  99. // $tree->Viev_Zpc_Parent_cut[$init]=$find[0];
  100. if(!isset($tree->Childs[$init]->TO_DETAIL_CUT_FLAG)) {
  101. $find[]=$init;
  102. self::zoom_process_links($tree,$init,$find[0]);
  103. foreach($tree->Childs[$init]->CHILD as $id=>$count) {
  104. self::search_parent_ids_till_cut($tree,$id,$find);
  105. }
  106. } //else
  107. // return $find;
  108. }
  109. function zoom_process_links($tree,$id,$root_id) {
  110. //dobudowuje znaczniki dotyczace LINKOW oraz brakujace ID z tym zwiazane
  111. //echo "<br>testuje zoom dla ".$id." root:".$root_id;
  112. if(isset($tree->Childs[$id]->GOTO_FLAG)) {
  113. if(isset( $tree->Childs[$tree->Childs[$id]->IF_TRUE_GOTO])) {
  114. //adding internal link to the same process
  115. //TODO trzeba przemyslec, czy dowiazywac linki do zagregowanych krokow, czy trzeba robic cut w tych miejscach - na ten moment domyslnie CUT
  116. // if(empty($tree->Childs[$id]->NO_CUT_FLAG)) //tylko linki zewnetrzne jak flaga NOCUT!
  117. //echo "... dodaje 218: ".$tree->Childs[$id]->IF_TRUE_GOTO;
  118. if(isset($tree->Childs[$tree->Childs[$id]->IF_TRUE_GOTO]->SOURCE)) {
  119. $tree->Viev_Zpc[$root_id]->INTERNAL_LINK[$tree->Childs[$id]->IF_TRUE_GOTO]=$tree->Childs[$id]->IF_TRUE_GOTO;
  120. //echo "dodalem Linka dla ".$root_id;
  121. } else { //echo "To jest link external - bo referencyjny ID{$tree->Childs[$id]->IF_TRUE_GOTO}nie byl w procesie";
  122. $tree->Viev_Zpc[$root_id]->EXTERNAL_LINK[$tree->Childs[$id]->IF_TRUE_GOTO]=$tree->Childs[$id]->IF_TRUE_GOTO;
  123. }
  124. } else { //echo "<br>Links zewnetrzny do ".$id." - ".$tree->Childs[$id]->IF_TRUE_GOTO;
  125. $tree->Viev_Zpc[$root_id]->EXTERNAL_LINK[$tree->Childs[$id]->IF_TRUE_GOTO]=$tree->Childs[$id]->IF_TRUE_GOTO;
  126. //$tree->Viev_Zpc_found[$tree->Childs[$id]->IF_TRUE_GOTO]=$tree->Childs[$id]->IF_TRUE_GOTO; //zeby tego rekordu nie przetwarzal ? TODO ?
  127. $obj=DB::get_by_id('CRM_PROCES',$tree->Childs[$id]->IF_TRUE_GOTO);
  128. $tree->Viev_Zpc[$tree->Childs[$id]->IF_TRUE_GOTO]->DESC="{".$obj->ID."}".substr($obj->DESC,0,50);
  129. if($tree->Childs[$id]->GOTO_FLAG=='GOTO_AND_RETURN') { //dodanie zwrotnej strzalki TODO dac inny typ strzalki!!
  130. $tree->Viev_Zpc[$tree->Childs[$id]->IF_TRUE_GOTO]->EXTERNAL_LINK[$root_id]=$root_id;
  131. //echo "<br> GOTO_AND_RETURN!!!".$tree->Childs[$id]->IF_TRUE_GOTO." -- ".$root_id;
  132. }
  133. }
  134. }
  135. }
  136. function build_path_zoom_proces_cut(&$tree,$init,$path_zpc=array()) {
  137. //funkcja do pokazania procesow wyplaszczonych, z wypunktowanymi rozgalezieniami - buduje drzewo w sposob inteligentny
  138. //szukam rekordow z gory do pierwszego CUT
  139. foreach($tree->Childs as $id=>$obj) {
  140. if(!isset($tree->Viev_Zpc_found[$id])) {
  141. //echo "<br>szukam parentow dla ".$id;
  142. self::search_parent_ids_till_cut($tree,$id,$find);
  143. // echo "<br>find:238 for id {$id} ".implode(',', $find)." EOL. ";
  144. if(empty($find)) { //echo " - Find empty for ".$id." adding ".$tree->Childs[$id]->PARENT;
  145. //trzeba przeskanowac w find jest dany parent -> Viev_Zpc_found
  146. // if(isset($tree->Childs[$id]->PARENT))
  147. // $tree->Viev_Zpc_Parent[$id]=$tree->Childs[$id]->PARENT;
  148. }
  149. foreach($find as $find_id) {
  150. $tree->Viev_Zpc_found[$find_id]=$find[0];
  151. if($find_id<>$find[0]) $tree->Viev_Zpc_Parent[$find_id]=$find[0]; //todo moze byc to z bledem jak nadrzedny bedzie zbitym ciagiem
  152. else $tree->Viev_Zpc_Parent[$find_id]=$tree->Childs[$find_id]->PARENT;
  153. }
  154. $tree->Viev_Zpc[$id]->PATH=$find;
  155. //wykrycie parenta polega na znalezieniu jego naturalnego parenta i poszukaniu w ktorej jest grupie
  156. //$tree->Viev_Zpc[$id]->PARENT=$tree->Viev_Zpc_Parent[$tree->Childs[$id]->PARENT] ;
  157. $obj=DB::get_by_id('CRM_PROCES',$id);
  158. $tree->Viev_Zpc[$id]->DESC="{".$id."}".substr($obj->DESC,0,50)."...";
  159. unset($find);
  160. }
  161. }
  162. //parenty trzeba zrobic za drugim rzutem
  163. foreach($tree->Viev_Zpc as $id=>$obj) {
  164. // echo "<br>256 wykrywam parenta dla {$id}";
  165. {
  166. //skanujemy wszystkie rekordy w Viev_Zpc w celu znalezienia czy danego ID parent nie jest w ktoryms z ID - tego szukamy
  167. if(!isset($obj->PARENT)) //tylko dla tych ktore nie maja parentow
  168. foreach($tree->Viev_Zpc as $id_=>$obj_) {
  169. if(isset($tree->Childs[$id_]->SOURCE))
  170. if(in_array($tree->Childs[$id]->PARENT, $obj_->PATH)) {
  171. // echo "<br>206 Skanuje dla brakujacego parenta dla ".$id." i znalazlem".$id_;
  172. $tree->Viev_Zpc[$id]->PARENT=$id_;
  173. } //else echo "<br>&nbsp;&nbsp; 199: nie znalazlem w ".$id_." path:".implode(',', $obj_->PATH);
  174. }
  175. if(!isset($tree->Viev_Zpc[$id]->PARENT)) { //jezeli nie znaleziono ta metoda to znaczy ze parent jest naturalny
  176. $tree->Viev_Zpc[$id]->PARENT=$tree->Childs[$id]->PARENT;
  177. // echo " - 204 ustawilem ostatecznie ".$tree->Childs[$id]->PARENT;
  178. }
  179. }
  180. }
  181. }
  182. }
  183. function GRAPH_VIEW_PROCES() {
  184. $id_proces = V::get('id_proces', '', $_REQUEST, 'int');
  185. // $id_proces = $_REQUEST['id_proces'];
  186. //TOOD bug funkcji V nie mozna dac INT=0!!!
  187. // if (empty($id_proces)) {
  188. // echo'<p class="err box box-red">'."Wrong ID".'</p>';
  189. // return;
  190. // }
  191. $db = DB::getDB();
  192. //$proces = $db->get_by_id('CRM_PROCES', $id_proces);
  193. //if (empty($proces)) {
  194. // echo'<p class="err box box-red">'."Process {$id_proces} not exists".'</p>';
  195. // return;
  196. //}
  197. $ajaxTask = V::get('ajaxTask', '', $_REQUEST);
  198. if ($ajaxTask == 'getInfo') {
  199. $id = V::get('id', 0, $_REQUEST, 'int');
  200. if ($id > 0) {
  201. //TODO najlepiej wyslac to od razu w jsonie i przekazac jakos do uzycia do wykresu!
  202. $step = $db->get_by_id('CRM_PROCES', $id);
  203. $cp=new crm_proces_paser;
  204. $tree=$cp->build_proces_init_tree($id);
  205. $cp->build_tree_flat_info($tree,null);
  206. $cp->detect_tree_where_to_detail_cut($tree);
  207. $cp->build_path_zoom_proces_cut($tree,$id);
  208. //echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;"> (' . __CLASS__ . '::' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r($step);echo'</pre>';
  209. ?>
  210. <?php if($step->TYPE=='PROCES_INIT') echo "<a href=?FUNCTION_INIT=GRAPH_VIEW_PROCES&id_proces={$step->PARENT_ID}&PROCES_INIT_SCAN=1>Widok mapy {$step->PARENT_ID}</a>"; ?>
  211. <p><code><?php echo "<a href=?FUNCTION_INIT=GRAPH_VIEW_PROCES&id_proces={$id}>".$step->ID."</a> - ".$step->DESC; ?></code> <?php echo $step->DESC; ?></p>
  212. <p><?php echo $step->OPIS; ?></p>
  213. <?php foreach ($tree->Viev_Zpc[$id]->PATH as $ind=>$id_include) {
  214. if($ind==0) continue; //pierwszy wiersz wyswietlony wyzej
  215. $step = $db->get_by_id('CRM_PROCES', $id_include);
  216. echo "<p><b>".$step->ID."</a> - ".$step->DESC."</b> <font size=-3>".$step->OPIS."</font></p>";
  217. } ?>
  218. <?php
  219. }
  220. exit;
  221. }
  222. $graph = new stdClass();
  223. $graph->htmlID = 'graph_proces_id_' . $id_proces;
  224. $graph->procesTreeFlat = array();
  225. $graph->procesTreeGoto = array();
  226. $graph->treeItems = array();
  227. $graph->elements = new stdClass();
  228. $graph->elements->nodes = array();
  229. $graph->elements->edges = array();
  230. /* elements: {
  231. nodes: [
  232. { data: { id: 'j', name: 'Jerry' } },
  233. { data: { id: 'e', name: 'Elaine' } },
  234. { data: { id: 'k', name: 'Kramer' } },
  235. { data: { id: 'g', name: 'George' } }
  236. ],
  237. edges: [
  238. { data: { source: 'j', target: 'e' } },
  239. { data: { source: 'j', target: 'k' } },
  240. { data: { source: 'j', target: 'g' } },
  241. { data: { source: 'e', target: 'j' } },
  242. { data: { source: 'e', target: 'k' } },
  243. { data: { source: 'k', target: 'j' } },
  244. { data: { source: 'k', target: 'e' } },
  245. { data: { source: 'k', target: 'g' } },
  246. { data: { source: 'g', target: 'j' } }
  247. ]
  248. },
  249. */
  250. function graph__addNodeID($id, &$graph,$name=null,$path,$parent=null,$type) {
  251. if (!array_key_exists($id, $graph->treeItems)) {
  252. $graph->treeItems[$id]= true;
  253. if(empty($name)) $name=$id;
  254. if(!empty($path)) { $name=$name." ".implode(',', $path);// $path=array();
  255. }
  256. //DEBUG_S(-3,'added id,name,path,parent',array($id,$name,$path,$parent),__FILE__,__FUNCTION__,__LINE__);
  257. if($type=='PROCES_INIT') $type_init='procesInit'; else $type_init=null;
  258. //echo $type_init.$id;
  259. $graph->elements->nodes[] = array('data'=>array('id'=>"".$id."", 'name'=>$name , 'type'=>$type_init));
  260. //echo "<br> w AddNode:ID".$id." parent".$parent;
  261. }
  262. if(!empty($parent)) $graph->elements->edges[] = array('data'=>array('source'=>$parent, 'target'=>$id ));
  263. }
  264. $PROCES_INIT_SCAN = V::get('PROCES_INIT_SCAN', '', $_REQUEST, 'int');
  265. if(!empty($PROCES_INIT_SCAN)) {
  266. //mapa procesow
  267. $cp=new crm_proces_paser;
  268. $PROCES_INIT_SCAN_STANOWISKO = V::get('PROCES_INIT_SCAN_STANOWISKO', '', $_REQUEST, 'int');
  269. $PROCES_INIT_SCAN_USER = V::get('PROCES_INIT_SCAN_USER', '', $_REQUEST, 'int');
  270. if(!empty($PROCES_INIT_SCAN_STANOWISKO)) {
  271. Lib::loadClass('ProcesHelper');
  272. $proces_list_obj = ProcesHelper::get_procesy_by_stanowiska( array($PROCES_INIT_SCAN_STANOWISKO) );
  273. foreach($proces_list_obj as $obj) {
  274. $init[$obj->ID]=$obj->ID;
  275. }
  276. } else if(!empty($PROCES_INIT_SCAN_USER)) {
  277. Lib::loadClass('UsersHelper');
  278. $proces_list_obj = UsersHelper::get_group_by_user($PROCES_INIT_SCAN_USER,array('SHOW_IN_PERIOD_MARK'=>'YES'));
  279. //echo "here";
  280. foreach($proces_list_obj as $obj) {
  281. $init[$obj->ID]=$obj->ID;
  282. }
  283. } else {
  284. $init=$cp->get_proces_init($id_proces);
  285. }
  286. DEBUG_S(3,'lista procesow init',$init);
  287. foreach($init as $id_proces) {
  288. $tree=$cp->build_proces_init_tree($id_proces);
  289. $cp->build_tree_flat_info($tree,null);
  290. $cp->detect_tree_where_to_detail_cut($tree,'nocut');
  291. $cp->build_path_zoom_proces_cut($tree,$id_proces);
  292. DEBUG_S(3,'get_proces_init',$init);
  293. DEBUG_S(3,'tree->childs',$tree->Childs);
  294. DEBUG_S(3,'tree->Parents',$tree->Parents);
  295. DEBUG_S(3,'tree->Viev_Zpc',$tree->Viev_Zpc);
  296. DEBUG_S(3,'tree->Viev_Zpc_Parent',$tree->Viev_Zpc_Parent);
  297. graph__addNodeID(0, $graph,$name=null,$path,null);
  298. foreach($tree->Viev_Zpc as $id=>$obj) {
  299. graph__addNodeID($id, $graph,$obj->DESC,null,((isset($obj->PARENT)) ? $obj->PARENT : null),$tree->Childs[$id]->TYPE);
  300. // foreach($obj->INTERNAL_LINK as $link) graph__addNodeID($id, &$graph,$tree->Viev_Zpc[$link]->DESC,null,$link,null);
  301. foreach($obj->EXTERNAL_LINK as $link) graph__addNodeID($link, $graph,$tree->Viev_Zpc[$link]->DESC,null,$id,'PROCES_INIT');
  302. }
  303. unset($tree);
  304. }
  305. }else {
  306. //dokladnie 1 proces
  307. $cp=new crm_proces_paser;
  308. $tree=$cp->build_proces_init_tree($id_proces);
  309. $cp->build_tree_flat_info($tree,null);
  310. $cp->detect_tree_where_to_detail_cut($tree);
  311. $cp->build_path_zoom_proces_cut($tree,$id_proces);
  312. DEBUG_S(3,'get_proces_init',$init);
  313. DEBUG_S(3,'tree->childs',$tree->Childs);
  314. DEBUG_S(3,'tree->Parents',$tree->Parents);
  315. DEBUG_S(3,'tree->Viev_Zpc',$tree->Viev_Zpc);
  316. DEBUG_S(3,'tree->Viev_Zpc_Parent',$tree->Viev_Zpc_Parent);
  317. DEBUG_S(3,'tree->Viev_Zpc_Parent_cut',$tree->Viev_Zpc_Parent_cut);
  318. DEBUG_S(3,'tree->Viev_Zpc_found',$tree->Viev_Zpc_found);
  319. graph__addNodeID(0, $graph,$name=null,$path,null);
  320. foreach($tree->Viev_Zpc as $id=>$obj) {
  321. //echo "<br> tst edg:".$id." / ".$tree->Childs[$id]->PARENT;
  322. // : $tree->Viev_Zpc[$tree->Childs[$id]->PARENT])
  323. graph__addNodeID($id, $graph,$obj->DESC,null,((isset($obj->PARENT)) ? $obj->PARENT : null),$tree->Childs[$id]->TYPE);
  324. foreach($obj->INTERNAL_LINK as $link) graph__addNodeID($id, $graph,$tree->Viev_Zpc[$link]->DESC,null,$link,null);
  325. foreach($obj->EXTERNAL_LINK as $link) graph__addNodeID($link, $graph,$tree->Viev_Zpc[$link]->DESC,null,$id,'PROCES_INIT');
  326. }
  327. }
  328. /*
  329. $db = DB::getDB();
  330. $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";
  331. $res=DB::query($sql);
  332. while($h=DB::fetch($res)) {
  333. SearchParentsWithExits($h->ID,$h->ID,$graph,'Proces '.$h->ID,0);
  334. //graph__addNodeID($h->ID, $graph);
  335. graph__addNodeID('1', $graph,'1');
  336. // graph__addNodeID($h->ID, $graph,$h->ID);
  337. // graph__addNodeID('100', $graph,'100');
  338. //$graph->treeItems[$h->ID] = true;
  339. //$graph->treeItems[101] = true;
  340. // $graph->elements->nodes[] = array('data'=>array('id'=>$h->ID, 'name'=>$h->ID , 'type'=>'procesInit'));
  341. // $graph->elements->nodes[] = array('data'=>array('id'=>101, 'name'=>101 , 'type'=>'procesInit'));
  342. // $graph->elements->edges[] = array('data'=>array('source'=>994, 'target'=>101));
  343. }
  344. */
  345. foreach($graph->elements->nodes as $var) {
  346. // echo "<br>\n NODE".$var[data][id];
  347. $nodes[$var[data][id]]=$var[data][id];
  348. }
  349. foreach($graph->elements->edges as $var) {
  350. //echo "<br>\n".$var[data][source]." ".$var[data][target]." ";
  351. if(!isset($nodes[$var[data][source]])) echo "<br>FAIL1 ".$var[data][source];
  352. if(!isset($nodes[$var[data][target]])) echo "<br>FAIL2 ".$var[data][target];
  353. }
  354. DEBUG_S(3,'nodes',$graph->elements->nodes);
  355. DEBUG_S(3,'edges',$graph->elements->edges);
  356. /*
  357. $sql = "select p.`ID`, p.`PARENT_ID`
  358. from `CRM_PROCES` as p
  359. where p.`A_STATUS` in('WAITING','NORMAL')
  360. ";
  361. $res = $db->query($sql);
  362. while ($r = $db->fetch($res)) {
  363. $graph->procesTreeFlat[$r->PARENT_ID] []= $r->ID;
  364. }
  365. $sql = "select p.`IF_TRUE_GOTO` as ID, p.`ID` as PARENT_ID
  366. from `CRM_PROCES` as p
  367. where p.`A_STATUS` in('WAITING','NORMAL')
  368. and p.IF_TRUE_GOTO>0
  369. -- and p.IF_TRUE_GOTO_FLAG='GOTO_AND_RETURN'
  370. ";
  371. $res = $db->query($sql);
  372. while ($r = $db->fetch($res)) {
  373. $graph->procesTreeGoto[$r->PARENT_ID] []= $r->ID;
  374. }
  375. function createGraphRec($id, $tree, &$graph, $lvl = 0) {
  376. $graph->treeItems[$id] = true;
  377. settype($id, 'string');
  378. if ($id == 3122) {
  379. $graph->elements->nodes[] = array('data'=>array('id'=>$id, 'name'=>$id, 'type'=>'procesInit', 'lvl'=>$lvl));
  380. } else {
  381. $graph->elements->nodes[] = array('data'=>array('id'=>$id, 'name'=>$id, 'lvl'=>$lvl));
  382. }
  383. if ($lvl > 1) {
  384. // return;
  385. }
  386. if (!empty($tree[$id])) {
  387. foreach ($tree[$id] as $vChildID) {
  388. $graph->elements->edges[] = array('data'=>array('source'=>$id, 'target'=>$vChildID));
  389. createGraphRec($vChildID, $tree, $graph, $lvl + 1);
  390. }
  391. }
  392. }
  393. createGraphRec($id_proces, $graph->procesTreeFlat, $graph);
  394. */
  395. /*
  396. // addGraphGoto
  397. foreach ($graph->procesTreeGoto as $kID => $vGotoIds) {
  398. //$graph->treeItems[$id] = true;
  399. if (array_key_exists($kID, $graph->treeItems)) {
  400. foreach ($vGotoIds as $vGotoID) {
  401. graph__addNodeID($vGotoID, $graph);
  402. $graph->elements->edges[] = array('data'=>array('source'=>$kID, 'target'=>$vGotoID, 'type'=>'GOTO'));
  403. }
  404. } else {
  405. foreach ($vGotoIds as $vGotoID) {
  406. if (array_key_exists($vGotoID, $graph->treeItems)) {
  407. //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>';
  408. graph__addNodeID($kID, $graph);
  409. //$graph->elements->edges[] = array('data'=>array('source'=>$kID, 'target'=>$vGotoID, 'type'=>'GOTO'));
  410. }
  411. }
  412. }
  413. }
  414. */
  415. ?>
  416. <style type="text/css">
  417. #<?php echo $graph->htmlID; ?>_wrap {
  418. position:relative;
  419. width:1100px;
  420. margin:0 auto;
  421. border:1px solid #ccc;
  422. }
  423. #<?php echo $graph->htmlID; ?> {
  424. height:560px;
  425. border-bottom:1px solid #ccc;
  426. }
  427. #<?php echo $graph->htmlID; ?>_info {
  428. padding:3px;
  429. }
  430. #<?php echo $graph->htmlID; ?>_wrap .actions { position:absolute; top:20px; left:-40px; margin:0; padding:0; list-style:none; }
  431. #<?php echo $graph->htmlID; ?>_wrap .actions button { border-radius:0; background:#fff; border:1px solid #ccc; }
  432. </style>
  433. <script src="./stuff/cytoscape.js/arbor.js"></script>
  434. <script src="./stuff/cytoscape.js/cytoscape.js"></script>
  435. <script>
  436. jQuery(loadInfo = function(nodeID){
  437. $.ajax({
  438. url: 'index.php?MENU_INIT=GRAPH_VIEW_PROCES&id_proces=<?php echo $id_proces; ?>&ajaxTask=getInfo&id=' + nodeID + '&HEADER_NOT_INIT=YES',
  439. type: 'GET',
  440. dataType: 'text',
  441. data: '',
  442. async: true,
  443. success: function (data) {
  444. jQuery('#<?php echo $graph->htmlID; ?>_info').html(data);
  445. },
  446. error: function (err) {
  447. console.log('err');
  448. }
  449. });
  450. });
  451. jQuery(loadCy = function(){
  452. jQuery('#<?php echo $graph->htmlID; ?>').cytoscape({
  453. layout: {
  454. name: 'arbor'
  455. },
  456. style: cytoscape.stylesheet()
  457. .selector('node')
  458. .css({
  459. 'shape': 'rectangle',
  460. 'width': '100px', 'height': '8px',
  461. 'font-size': '10px',
  462. 'content': 'data(name)',
  463. 'text-valign': 'center',
  464. 'color': 'white',
  465. 'text-outline-width': 2,
  466. 'text-outline-color': '#888'
  467. })
  468. .selector('edge')
  469. .css({
  470. 'target-arrow-shape': 'triangle'
  471. })
  472. .selector(':selected')
  473. .css({
  474. 'background-color': 'black',
  475. 'line-color': 'black',
  476. 'target-arrow-color': 'black',
  477. 'source-arrow-color': 'black'
  478. })
  479. .selector('.faded')
  480. .css({
  481. 'opacity': 0.25,
  482. 'text-opacity': 0
  483. })
  484. .selector('edge.neighborhood')
  485. .css({
  486. 'background-color': 'blue',
  487. 'color': 'orange'
  488. })
  489. .selector('node.procesInit')
  490. .css({
  491. 'background-color': 'red',
  492. 'text-outline-color': 'red',
  493. 'font-weight': 'bold'
  494. }),
  495. elements: <?php echo json_encode($graph->elements); ?>,
  496. ready: function(){
  497. var cy = this;
  498. window.cy_<?php echo $graph->htmlID; ?> = this;
  499. cy.elements("node[type = 'procesInit']").addClass('procesInit');
  500. cy.elements("node[lvl > 1]").hide();
  501. cy.elements().unselectify();
  502. cy.on('tap', 'node', function(e){
  503. //console.log('on tap node', e)
  504. var node = e.cyTarget;
  505. var neighborhood = node.neighborhood().add(node);
  506. var nodeID = node.id();
  507. loadInfo(nodeID);
  508. cy.elements().addClass('faded').unselect();
  509. neighborhood.removeClass('faded');
  510. node.select();
  511. cy.edges().removeClass('neighborhood');
  512. node.connectedEdges().addClass('neighborhood');
  513. neighborhood.show();
  514. cy.center(neighborhood);
  515. });
  516. cy.on('tap', function(e){
  517. if (e.cyTarget === cy){
  518. cy.elements().removeClass('faded');
  519. }
  520. });
  521. },
  522. showOverlay: false
  523. });
  524. });
  525. jQuery(document).ready(function(){
  526. loadCy();
  527. var parent = $('#<?php echo $graph->htmlID; ?>')
  528. .parent()
  529. parent.find('.actions .cy-refresh')
  530. .on('mousedown touchstart', function(){
  531. loadCy();
  532. cy.attr('style', '');
  533. });
  534. parent.find('.actions .cy-zoom-plus')
  535. .on('mousedown touchstart', function(){
  536. window.cy_<?php echo $graph->htmlID; ?>.zoom(window.cy_<?php echo $graph->htmlID; ?>.zoom() + 0.1);
  537. });
  538. parent.find('.actions .cy-zoom-minus')
  539. .on('mousedown touchstart', function(){
  540. window.cy_<?php echo $graph->htmlID; ?>.zoom(window.cy_<?php echo $graph->htmlID; ?>.zoom() - 0.1);
  541. });
  542. });
  543. </script>
  544. <div id="<?php echo $graph->htmlID; ?>_wrap">
  545. <div id="<?php echo $graph->htmlID; ?>"></div>
  546. <div id="<?php echo $graph->htmlID; ?>_info"></div>
  547. <ul class="actions">
  548. <li><button class="btn cy-refresh"><i title="Refresh" class="ico-refresh"></i></button></li>
  549. <li><button class="btn cy-zoom-plus"><i title="Zoom +" class="ico-plus"></i></button></li>
  550. <li><button class="btn cy-zoom-minus"><i title="Zoom -" class="ico-minus"></i></button></li>
  551. </ul>
  552. </div>
  553. <?php
  554. }