_table = $table;
$this->_sql_parent_id_col = 'PARENT_ID';
$this->_params = array();
$this->cookie_name = 'TREE_' . $table;
// TODO: fun name must be uniq to show couple tree's on one site
$this->js_tree_hide_fun = 'TREE_' . $table . '_hide';
$this->js_tree_open_rec_fun = 'TREE_' . $table . '_open_rec';
$this->_limit = 0;
$this->_deep_limit = 0;
$this->_opened_nodes_to_save = array();
}
function set_parent_id_col( $p_id_col ) {
$this->_sql_parent_id_col = $p_id_col;
}
function get_item_p_id(&$r) {
if (isset($r->{$this->_sql_parent_id_col})) {
return $r->{$this->_sql_parent_id_col};
}
return null;
}
function is_closed( $id ) {
static $c;
if (!$c) {
$c = explode(' ', V::get($this->cookie_name, '', $_COOKIE));
}
if ($this->get_param('lazy_open_rec')) {
if (!in_array($id, $c)) {
$this->lazy_open($id);
}
return false;
}
return !in_array($id, $c);
}
function show() {
//echo'
';print_r(explode(' ', $_COOKIE[$this->cookie_name]));echo'';
$this->show_css();
$this->show_js();
echo "\n".''."\n";
$this->show_rec();
echo '
'."\n";
$this->_save_lazy_opened_nodes();
echo"\n".''."\n";
}
/*
* Save collapsed nodes in cookie
* @see _save_lazy_opened_nodes
*/
function lazy_open($id) {
$this->_opened_nodes_to_save[$id] = true;
}
/*
* Save collapsed nodes in cookie
* @see lazy_open
*/
function _save_lazy_opened_nodes() {
if (!empty($this->_opened_nodes_to_save)) {
$opened = array();
if (!empty($_COOKIE[$this->cookie_name]) && $_COOKIE[$this->cookie_name] != '') {
$opened = explode(' ', $_COOKIE[$this->cookie_name]);
}
foreach ($opened as $id) {
$this->_opened_nodes_to_save [$id] = true;
}//end foreach
$_COOKIE[$this->cookie_name] = implode(' ', array_keys($this->_opened_nodes_to_save));
echo'';
}
}
function showSubTree( $id = 0 ) {
$this->show_css();
$this->show_js();
echo "\n".''."\n";
$ids = explode(',', $id);
foreach ($ids as $id) {
$parents = array();
$this->get_parents_rec( $id, $parents );
//echo'
';print_r($parents);echo'
';
$this->set_param('show_state', 'parents');
$r = null;
if (($r = reset($parents)) != null && $this->get_item_p_id($r) == -1) {
echo'
'."Kosz".'';
}
foreach ($parents as $r) {
$cls = ' class="tree-last"';
echo'
'."\n";
$item_id_html_id = ' id="TREE'.$r->ID.'"';
echo '- ';
if ($r->ID == $id) break;
$this->show_item( $r );
}//end foreach
$this->set_param('show_state', 'items');
if ($r) {
$this->show_item( $r );
} else {
if ($this->get_param('is_trash')) {// is _trash
echo''."Kosz".'';
} else {
echo''."Brak danych".'';
}
}
//TODO: get item and if exists then show parents and childrens
$this->show_rec( $id );
foreach ($parents as $r) {
echo '
'."\n";
echo'
';
}//end foreach
echo '
';
}
echo '
'."\n";
}
/*
* Wyszukiwanie ID w drzewie.
*/
function showSearchNode( $id ) {
$parents = array();
$this->get_parents_rec( $id, $parents );
if (empty($parents)) {
echo'Rekord id="'.$id.'" nie istnieje.
';
} else {
// TODO: drzewo ZWIN, trzeba teraz zmienic zawartosc cookie!
//echo'TODO: wyszukaj "'.$id.'" {'.implode(',', $parent_ids).'}
';
echo'';
$js = "return scrollToProces('".$id."');";
echo''."Przejdz do ID ".$id."".'';
echo'
';
// TODO: sprawdzi czy aby na pewno dziala poprawnie, test szukaj 901, nie otwiera 892
foreach ($parents as $r) {
$this->lazy_open( $r->ID );
}//end foreach
$this->_save_lazy_opened_nodes();
}
$this->show();
}
/**
* TODO: Np. do menu, czy filtrowania drzewa.
* @see task_CRM_MENU
* @param items - array of items to show, array(ID => $r)
* @param show_item_callback - inna funkcja do wypisywania - TODO: jest $tree->set_param('show_item_callback');
*/
function showItems( &$base_items, $show_item_callback = null ) {
$items = array();
// get paretns flat
$items_flat = array();
foreach ($base_items as $p_id => $p) {
$items [$p->ID] = $p;
$items_flat [$p->ID] = $p->PARENT_ID;
$items_flat [$this->get_item_p_id($p)] = null;
}
$user_menu_tree_created = TreeHelper::build_tree_flat( $this->_table, $items_flat );
$user_menu_tree = TreeHelper::get_tree_from_flat( $items_flat );
$this->fetch_data($items, $items_flat);
if (!empty($user_menu_tree[0])) {
$this->show_css();
echo'';
$this->show_rec_by_tree( $user_menu_tree[0], $items );
echo'
';
} else {
//
}
}
function show_rec_by_tree( &$tree, &$items ) {
if (empty($tree)) {
return;
}
echo'';
$i = 0; $cnt = count($tree);
foreach ($tree as $k_id => $v_arr) {
$r = (isset($items[$k_id]))? $items[$k_id] : null;
if ($r) {
$cls = array();
if ($this->is_closed($r->ID)) $cls['tree-close'] = true;
if (++$i == $cnt) {
$cls['tree-last'] = true;
}
if (empty($v_arr)) {
$cls['tree-leaf'] = true;
}
$cls = (!empty($cls))? ' class="'.implode(' ', array_keys($cls)).'"' : '';
$item_id_html_id = ' id="TREE'.$r->ID.'"';
echo '- ';
if (isset($r->has_childrens) && $r->has_childrens) {
echo'';
}
$this->show_item($r);
$this->show_rec_by_tree( $v_arr, $items );
echo'
';
}
}//end foreach
echo'
';
}
function fetch_data( &$items, $tree_flat ) {
$sql_ids = array();
// find only not set
foreach ($tree_flat as $k_id => $v) {
if (empty($items[$k_id])) {
$sql_ids []= $k_id;
}
}//end foreach
// add tree parent proces info
if (!empty($sql_ids)) {
$sql = "select p.* from `".$this->_table."` as p where p.`ID` in (".implode(", ", $sql_ids)."); ";
$res = DB::query( $sql );
while ($r = DB::fetch( $res )) {
$items[$r->ID] = $r;
}
}
}
/*
* Open all nodes recursive.
*/
function show_rec_all( $parent_id = 0, $deep = 0 ) {
$this->set_param('lazy_open_rec', true);// @see is_closed
$this->lazy_open($parent_id);
$this->show_rec($parent_id, $deep);
$this->_save_lazy_opened_nodes();
}
function show_rec( $parent_id = 0, $deep = 0 ) {
//if ($this->_deep_limit > 0 && $deep > $this->_deep_limit) {
// return;
//}
$list = $this->get_childrens($parent_id);
if (empty($list)) return;
echo ''."\n";
$list_total = count($list);
foreach ($list as $r) {
$cls = array();
if (!--$list_total) $cls['tree-last'] = true;
if (!$this->get_param('rozwin')) {
if ($this->is_closed($r->ID)) $cls['tree-close'] = true;
}
if ($this->_deep_limit > 0 && $deep >= $this->_deep_limit) {
$cls['tree-close'] = true;
}
if (!$r->has_childrens) {
$cls['tree-leaf'] = true;
if (isset($cls['tree-close'])) unset($cls['tree-close']);// show wskazniki on leaf
}
$cls = array_keys($cls);// uniq array
// reopen nodes marked as open, but hide by default or deep, etc., @see show_js: tree_..._ajax_reopen
$btn_open_cls_add = '';
if (in_array('tree-close', $cls) && $this->is_closed($r->ID) == false) {
$btn_open_cls_add = ' ajax-reopen';
}
//$cls []= 'deep-'.$deep;
$cls = (empty($cls))? '' : ' class="'.implode(' ', $cls).'"';
$item_id_html_id = '';
if ($this->get_item_p_id($r) == $parent_id) {// tylko normalny, a nie P_ID2, czy P_ID3, etc
$item_id_html_id = ' id="TREE'.$r->ID.'"';
}
echo '- ';
if ($this->get_param('rozwin')) {
if ($r->has_childrens) {
if ($this->_deep_limit > 0 && $deep + 1 > $this->_deep_limit) {
//echo' ';
echo'';
}
}
} else {
if ($r->has_childrens) {
//echo' ';
echo'';
}
}
$this->show_item($r);
if ($r->has_childrens) {
$this->show_rec($r->ID, $deep + 1);
}
echo '
'."\n";
}//end foreach
echo '
'."\n";
}
function show_item( &$r ) {
if ($callback = $this->get_param('show_item_callback')) {
$callback( $r, $this );
} else {
echo'- ';
echo ''.$r->ID.'';
echo'
';
}
}
function &get_childrens( $parent_id ) {
$ret = array();
// check tree limit - load more by ajax
// mved to show_rec
// if ($this->_limit > 0 && $this->_nodes_from_db > $this->_limit) {
// return $ret;
// }
$sql = new stdClass();
$sql->select = array();
$sql->select [] = "t.*";
// has_childrens
if ($this->_table == 'CRM_LISTA_ZASOBOW') {
$sql->select [] = "IF(t.`".$this->_sql_parent_id_col."`='".$parent_id."' and t2.`ID` is not null, 1, 0) as has_childrens";
} else {
$sql->select [] = "IF(t2.`ID` is not null, 1, 0) as has_childrens";
}
// PARENT_TYPE dla tabeli CRM_LISTA_ZASOBOW
if ($this->_table == 'CRM_LISTA_ZASOBOW') {
$sql->select [] = "
IF( t.`".$this->_sql_parent_id_col."`='".$parent_id."'
, 'P_ID'
, IF( (FIND_IN_SET('".$parent_id."', t.`PARENT_ID_ACCESS`) > 0)
, 'P_ID_ACCESS'
, IF( (FIND_IN_SET('".$parent_id."', t.`PARENT_ID_MAP`) > 0)
, 'P_ID_MAP'
, 'P_ID_UNKNOWN'
)
)
) as PARENT_TYPE
";
$sql->select [] = "IF(t.`ALIAS_ID` > 0
, (select concat_ws('.', zap.`DESC`, za.`DESC`)
from `CRM_LISTA_ZASOBOW` as za
left join `CRM_LISTA_ZASOBOW` as zap on(zap.`ID`=za.`PARENT_ID`)
where za.`ID`=t.`ALIAS_ID`
limit 1
)
, ''
) as ALIAS_NAME
";
}
$sql->filter = array();
$sql->join_filter = array();
$sql->filter []= "(t.`".$this->_sql_parent_id_col."`='".$parent_id."')";
$sql->join_filter []= "(t2.`".$this->_sql_parent_id_col."`=t.`ID`)";
if ($this->_table == 'CRM_LISTA_ZASOBOW') {
// TODO: $this->get_param('TREE_SHOW_P_ID2') $this->get_param('TREE_SHOW_P_ID3')
if ($_SESSION['TREE_SHOW_P_ID2'] || $_SESSION['TREE_SHOW_P_ID3']) {
if ($_SESSION['TREE_SHOW_P_ID2']) {
$sql->filter []= "(FIND_IN_SET('".$parent_id."', t.`PARENT_ID_ACCESS`) > 0)";
$sql->join_filter []= "(FIND_IN_SET(t.`ID`, t2.`PARENT_ID_ACCESS`) > 0)";
}
if ($_SESSION['TREE_SHOW_P_ID3']) {
$sql->filter []= "(FIND_IN_SET('".$parent_id."', t.`PARENT_ID_MAP`) > 0)";
$sql->join_filter []= "(FIND_IN_SET(t.`ID`, t2.`PARENT_ID_MAP`) > 0)";
}
}
}
$sql->select = implode("\n, ", $sql->select);
$sql->where = implode(" or ", $sql->filter);
$sql->join_filter = implode(" or ", $sql->join_filter);
// filtr_status
if ($this->_table == 'IN7_MK_BAZA_DYSTRYBUCJI') {
$sql_status = array();
if ($this->get_param('filtr_status') == 'NORMAL') {
$sql_status []= "'NORMAL'";
} else if ($this->get_param('filtr_status') == 'WAITING') {
$sql_status []= "'NORMAL'";
$sql_status []= "'WAITING'";
}
if (!empty($sql_status)) {
$sql->where = "(".$sql->where.") and t.`A_STATUS` in(".implode(',', $sql_status).") ";
}
}
if (in_array($this->_table, array('CRM_PROCES','CRM_LISTA_ZASOBOW'))) {
$sql->order_by = "order by t.`SORT_PRIO` asc, t.`ID` asc";
} else {
$sql->order_by = "order by t.`ID` asc";
}
$sql = "select
".$sql->select."
from `".$this->_table."` as t
left join `".$this->_table."` as t2 on(".$sql->join_filter.")
where
".$sql->where."
group by t.`ID`
".$sql->order_by."
";
$res = DB::query( $sql );
$ile = 0;
while ($r = DB::fetch( $res )) {
$ret[$r->ID] = $r;
$ile++;
}
$this->_nodes_from_db += $ile;
return $ret;
}
function &get_parents_rec( $id, &$arr ) {
$sql = "select
t.*
, '1' as has_childrens
, 'P_ID' as PARENT_TYPE
from `".$this->_table."` as t
where
t.`ID`='".$id."'
";
$res = DB::query( $sql );
if ($r = DB::fetch( $res )) {
array_unshift($arr, $r);
if ($this->get_item_p_id($r) == null || $this->get_item_p_id($r)=='0') {
return $arr;
} else {
$this->get_parents_rec( $this->get_item_p_id($r), $arr );
}
}
return $arr;
}
function set_param( $key, $value ) {
$this->_params[ $key ] = $value;
}
function get_param( $key ) {
if (array_key_exists($key, $this->_params)) {
return $this->_params[ $key ];
}
return null;
}
function show_css() {
static $_run_only_once;
if ($_run_only_once) {
return;
}
$_run_only_once = true;
echo "\n".''."\n";
}
function show_js() {
echo ''."\n";
}
}// class