<?php


class UserAcl {

	var $_user_id;
	var $_use_cache = false;
	/**
	 * User groups (cached)
	 */
	var $_groups = array();
	var $_proces_ids = array();
	var $_proces_tree_flat = array();
	var $_proces_used_ids = array();
	var $_proces_used_map = array();
	var $_proces_init_used_ids = array();

	function __construct($user_id, $use_cache = false) {
		$this->_user_id = $user_id;
		$this->_use_cache = $use_cache;

		$this->_cache_init();
	}

	function fetchGroups() {
		if ($this->_user_id < 0) return false;
		if (!empty($this->_groups)) {
			return $this->_groups;
		}

		$this->_groups = $this->_cache_read('_groups');
		if ($this->_groups != null) {
			return $this->_groups;
		}
		$this->_groups = array();

		Lib::loadClass('UsersHelper');
		$this->_groups = UsersHelper::get_group_by_user($this->_user_id);

		$this->_cache_save('_groups', $this->_groups);

		return $this->_groups;
	}

	function getProcesIds() {
		if (!empty($this->_proces_ids)) {
			return $this->_proces_ids;
		}
		Lib::loadClass('DB');
		$db = DB::getDB();
		$groups = $this->fetchGroups();
		if (empty($groups)) {
			return false;
		}
		$sql = "select p.`ID`
			from `CRM_PROCES` as p
				left join `CRM_WSKAZNIK` as w on(p.`ID`=w.`ID_PROCES`)
			where
				w.`ID_ZASOB` in(" . implode(",", array_keys($groups)) . ")
				and w.`A_STATUS` in('NORMAL', 'WAITING')
				and p.`A_STATUS` in('NORMAL', 'WAITING')
		";
		$res = $db->query($sql);
		while ($r = $db->fetch($res)) {
			$this->_proces_ids [$r->ID] = true;
		}
		$this->_proces_ids = array_keys($this->_proces_ids);
		return $this->_proces_ids;
	}

	function getProcesTree() {
		if (!empty($this->_proces_tree_flat)) {
			return $this->_proces_tree_flat;
		}

		Lib::loadClass('DB');
		$db = DB::getDB();
		$sql = "select p.`ID`, p.`PARENT_ID`
				from `CRM_PROCES` as p
				where p.`A_STATUS` in('WAITING','NORMAL')
			union
				select p.`IF_TRUE_GOTO` as ID, p.`ID` as PARENT_ID
				from `CRM_PROCES` as p
				where p.`A_STATUS` in('WAITING','NORMAL')
					and p.IF_TRUE_GOTO>0
					and p.IF_TRUE_GOTO_FLAG='GOTO_AND_RETURN'
		";
		//	union select '83','122'		  union select p.`ID` as ID, p.`IF_TRUE_GOTO` as PARENT_ID from `CRM_PROCES` as p where p.`A_STATUS` in('WAITING','NORMAL') and p.IF_TRUE_GOTO>0 
		//union select '83','122'	
		//union select '83','2025'	
		$res = $db->query($sql);
		while ($r = $db->fetch($res)) {
			$this->_proces_tree_flat[$r->PARENT_ID][] = $r->ID;
		}
		return $this->_proces_tree_flat;
	}

	private function _createUsedProcesMap() {
		if (!empty($this->_proces_used_ids)) {
			return;
		}

		$this->_proces_used_ids = $this->_cache_read('_proces_used_ids');
		$this->_proces_used_map = $this->_cache_read('_proces_used_map');
		if ($this->_proces_used_ids != null && $this->_proces_used_map != null) {
			return;
		}

		$this->_proces_used_ids = array();// find path from proces_id connected with user to the end of process
		$this->_proces_used_map = array();
		$dbg = false;

		$ID_PROCESOW_USERA = $this->getProcesIds();
		if (empty($ID_PROCESOW_USERA)) {
			return;
		}
		$CRM_PROCESS_TREE = $this->getProcesTree();
		// ! rekursywnie szukam sciezek procesow powiazanych dla usera procesow
		foreach ($ID_PROCESOW_USERA as $proces_id) {
			$this->_proces_used_ids[$proces_id] = true;
			if ($dbg) echo '<div style="border:1px solid blue;background-color:#eee;">' . "<b>find_rec(CRM_PROCESS_TREE, {$proces_id}, 'init') {</b>\n";
			$CRM_PROCES_USERA_UZYTY_FIND = array();
			$this->find_in_tree_parent_rec($CRM_PROCESS_TREE, $proces_id, $CRM_PROCES_USERA_UZYTY_FIND, $dbg);
			if ($dbg) echo '</div>';
			$this->_proces_used_ids[$proces_id] = true;//trzeba dodac sam proces, bo go brakuje w indeksach
			$this->_proces_used_map[$proces_id][] = $proces_id;//trzeba dodac sam proces, bo go brakowalo w indeksach
			if (is_array($CRM_PROCES_USERA_UZYTY_FIND)) {
				foreach ($CRM_PROCES_USERA_UZYTY_FIND as $INDEX => $proces_id_found ) {
					$this->_proces_used_ids[$proces_id_found] = true;
					$this->_proces_used_map[$proces_id][] = $proces_id_found;//tworze mape procesow od glownego w dol
				}
			}
		}
		$this->_proces_used_ids = array_keys($this->_proces_used_ids);

		$this->_cache_save('_proces_used_ids', $this->_proces_used_ids);
		$this->_cache_save('_proces_used_map', $this->_proces_used_map);
	}

	public function getUsedProcesMap() {
		$this->_createUsedProcesMap();
		return $this->_proces_used_map;
	}

	public function getUsedProcesIds($procesID = null) {
		$this->_createUsedProcesMap();
		$usedProcesListIds = $this->_proces_used_ids;

		if ($procesID > 0) {
			$map = $this->getUsedProcesMap();
			if (!array_key_exists($procesID, $map)) {
				return false;
			}
			$usedProcesListIds = $map[$procesID];
		}

		return $usedProcesListIds;
	}

	public function getUsedProcesInitIds() {// function admin_fetch_CRM_PROCES_USERA_UZYTY_MAP_PROCES_INIT() {
		if (!empty($this->_proces_init_used_ids)) {
			return $this->_proces_init_used_ids;
		}

		$map = $this->getUsedProcesMap();
		if (!empty($map)) {
			Lib::loadClass('DB');
			$db = DB::getDB();
			$sql = "select `ID` from `CRM_PROCES` where `TYPE`='PROCES_INIT' and `ID` in (" . implode(",", array_keys($map)) . ") ";
			$res = $db->query($sql);
			while ($h = $db->fetch($res)) {
				$this->_proces_init_used_ids[] = $h->ID;
			}
		}
		return $this->_proces_init_used_ids;
	}

	function old_fixed() {
		if ($this->_user_id < 0) {
			// TODO: set error brak user_id
			return false;
		}

		$groups = $this->fetchGroups();
		if (empty($groups)) {
			// TODO: set error brak grup
			// echo '<p style="color:red">' . "Brak przypisanego stanowiska!" . " Zaktualizuj je <a href='procesy5.php?task=USER_EDIT&_user_id=".$_SESSION['ADM_ID']."&_p=0'>tutaj w menu</a> </p>";
			return false;
		}

		$ID_ZASOBOW_USERA = array_keys($groups);
		echo '<p>' . "1. ID_ZASOBOW_USERA: [" . implode(', ', $ID_ZASOBOW_USERA) . "]"  .'</p>';

		$ID_PROCESOW_USERA = $this->getProcesIds();

		echo '<p>' . "2. ID_PROCESOW_USERA: [" . implode(', ', $ID_PROCESOW_USERA) . "]"  .'</p>';

		// ! zapisuje cala tabele procesow do arraya (i procesy powiazane GOTO z IF_TRUE_GOTO_FLAG=1)
		$CRM_PROCESS_TREE = $this->getProcesTree();// [PARENT_ID] = ID
echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;">3. CRM_PROCESS_TREE (F.' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r($CRM_PROCESS_TREE);echo'</pre>';

		$CRM_PROCES_USERA_UZYTY = $this->getUsedProcesIds();
		$CRM_PROCES_USERA_UZYTY_MAP = $this->getUsedProcesMap();
		echo '<p>' . "4. CRM_PROCES_USERA_UZYTY: [" . implode(', ', $CRM_PROCES_USERA_UZYTY) . "]"  .'</p>';
		if (empty($CRM_PROCES_USERA_UZYTY)) {
			// TODO: brak procesow usera
			return false;
		}

		Lib::loadClass('DB');
		$db = DB::getDB();

		//$TREE_CRM_WSKAZNIK = array();
		$CRM_TREE_WSKAZNIK_NARZEDZIE = array();
		//$TREE_CRM_WSKAZNIK_DESC = array();
		$TREE_CRM_WSKAZNIK_CONF = array();
		$TREE_CRM_WSKAZNIK_SORT_PRIO = array();

		// ! dla sciezek procesow wyszukuje powiazanych zasobow aby dac im permy
	$zap_sql = "select t1.`ID_PROCES`
				, t1.`ID_ZASOB`
				, replace(t2.`FORM_TREAT`, ',', '') as FORM_TREAT 
				, t3.`DESC` as ZASOB_DESC
				, t3.`TYPE`
				, t4.`DESC` as PARENT_ZASOB_DESC
				, t4.`TYPE` as PARENT_TYPE
				, t3.`SORT_PRIO` as z__SORT_PRIO
				, t3.`OPIS` as ZASOB_OPIS , t1.`ID` as ID_WSKAZNIK
			from `CRM_WSKAZNIK` as t1
				left join `CRM_PRZYPADEK` as t2 on (t1.ID_PRZYPADEK=t2.ID)
				left join `CRM_LISTA_ZASOBOW` as t3 on (t3.ID=t1.ID_ZASOB)
				left join `CRM_LISTA_ZASOBOW` as t4 on (t4.ID=t3.PARENT_ID)
			where
				(
					( t3.`TYPE`='KOMORKA' and t4.`TYPE`='TABELA' )
					or (t3.`TYPE`='NARZEDZIE') or (t3.`TYPE`='URL')
				)
				and t1.`A_STATUS` in('NORMAL', 'WAITING')
				and t1.`ID_PROCES` in(" . implode(",", $CRM_PROCES_USERA_UZYTY) . ")
		";
		$res = $db->query($zap_sql);
		while ($r = $db->fetch($res)) {
			if ($r->TYPE == 'NARZEDZIE') { //@2012-10-15 walka z warningami sqix
				  if(isset($CRM_TREE_WSKAZNIK_NARZEDZIE[$r->ID_ZASOB]))
						$CRM_TREE_WSKAZNIK_NARZEDZIE[$r->ID_ZASOB] .= $r->FORM_TREAT;
				  else $CRM_TREE_WSKAZNIK_NARZEDZIE[$r->ID_ZASOB] = $r->FORM_TREAT;
				 $CRM_WSKAZNIK_PROCES_WSKAZNIK_TREE[$r->ID_PROCES][]=$r->ID_WSKAZNIK; //ustawiam wskaznik od procesu, jak user wybierze proces do roboty, to ja poznam co moze mu sie pojawic

			} else if ($r->TYPE == 'URL') { 
				  $CRM_WSKAZNIK_PROCES_WSKAZNIK_TREE[$r->ID_PROCES][]=$r->ID_WSKAZNIK; //ustawiam wskaznik od procesu, jak user wybierze proces do roboty, to ja poznam co moze mu sie pojawic
				    $_SESSION['MENU_SELECT_PROCES_DATA']['MENU_COLUMN'][$r->ID_ZASOB]['TYPE']=$r->TYPE;
					$_SESSION['MENU_SELECT_PROCES_DATA']['MENU_COLUMN'][$r->ID_ZASOB]['DESC']=$r->ZASOB_DESC;
					$_SESSION['MENU_SELECT_PROCES_DATA']['MENU_COLUMN'][$r->ID_ZASOB]['OPIS']=$r->ZASOB_OPIS;

			} else {
				//$TREE_CRM_WSKAZNIK[$r->ID_ZASOB] .= $r->FORM_TREAT;
				//$TREE_CRM_WSKAZNIK_DESC[$r->ID_ZASOB] = $r->ZASOB_DESC;

				if ($r->PARENT_TYPE == 'TABELA') {
					$CRM_WSKAZNIK_PROCES_WSKAZNIK_TREE[$r->ID_PROCES][]=$r->ID_WSKAZNIK; //ustawiam wskaznik od procesu, jak user wybierze proces do roboty, to ja poznam co moze mu sie pojawic
					 if(isset($r->FORM_TREAT)) { //@2012-10-15 walka z warningami sqix
						  if(isset($TREE_CRM_WSKAZNIK_CONF[$r->PARENT_ZASOB_DESC][$r->ZASOB_DESC])) 
							$TREE_CRM_WSKAZNIK_CONF[$r->PARENT_ZASOB_DESC][$r->ZASOB_DESC] .= $r->FORM_TREAT;
						  else $TREE_CRM_WSKAZNIK_CONF[$r->PARENT_ZASOB_DESC][$r->ZASOB_DESC] = $r->FORM_TREAT;
						 // echo "<br. . . Dodaje dla:".$r->PARENT_ZASOB_DESC." ".$r->ZASOB_DESC." = ".$r->FORM_TREAT;
					  }
					  $TREE_CRM_WSKAZNIK_SORT_PRIO[$r->PARENT_ZASOB_DESC][$r->ZASOB_DESC] = $r->z__SORT_PRIO;


							//@2012-10-10 by SQIX : dodajemy opus kolumny z opisu zasobow
					if($r->ZASOB_OPIS) $_SESSION[$r->PARENT_ZASOB_DESC."_COLUMN"]['DESC_TO_LANG'][$r->ZASOB_DESC]=$r->ZASOB_OPIS;
					else if(isset($_SESSION[$r->PARENT_ZASOB_DESC."_COLUMN"]['DESC_TO_LANG'][$r->ZASOB_DESC])&&(strlen($_SESSION[$r->PARENT_ZASOB_DESC."_COLUMN"]['DESC_TO_LANG'][$r->ZASOB_DESC])>1)) 
							echo "<BR> DODAJ opis dla zasobu ".$r->ID_ZASOB." w postaci <pre>".$_SESSION[$r->PARENT_ZASOB_DESC."_COLUMN"]['DESC_TO_LANG'][$r->ZASOB_DESC]."</pre>";
				}
			}
		}
echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;">5. TREE_CRM_WSKAZNIK_CONF (F.' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r($TREE_CRM_WSKAZNIK_CONF);echo'</pre>';

echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;">6. CRM_PROCES_USERA_UZYTY ('.count($CRM_PROCES_USERA_UZYTY).') (F.' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r($CRM_PROCES_USERA_UZYTY);echo'</pre>';
echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;">6. CRM_PROCES_USERA_UZYTY_MAP ('.count($CRM_PROCES_USERA_UZYTY_MAP).') (F.' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r($CRM_PROCES_USERA_UZYTY_MAP);echo'</pre>';
echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;">6. CRM_TREE_WSKAZNIK_NARZEDZIE ('.count($CRM_TREE_WSKAZNIK_NARZEDZIE).') (F.' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r($CRM_TREE_WSKAZNIK_NARZEDZIE);echo'</pre>';
echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;">6. CRM_WSKAZNIK_PROCES_WSKAZNIK_TREE ('.count($CRM_WSKAZNIK_PROCES_WSKAZNIK_TREE).') (F.' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r($CRM_WSKAZNIK_PROCES_WSKAZNIK_TREE);echo'</pre>';

		// ! tutaj poszukamy co jest proces_init tylko z CRM_PROCES_USERA_UZYTY_MAP
		if (!empty($CRM_PROCES_USERA_UZYTY_MAP)) {
			$sql="select `ID`,`DESC` from `CRM_PROCES` where `TYPE`='PROCES_INIT' and ID in (".implode(",", array_keys($CRM_PROCES_USERA_UZYTY_MAP)).") ";
			$res = $db->query($sql);
			$CRM_PROCES_USERA_UZYTY_MAP_PROCES_INIT = array();
			while($r = $db->fetch($res)) {
				$CRM_PROCES_USERA_UZYTY_MAP_PROCES_INIT[] = $r->ID;
			}
		}

echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;">6. CRM_PROCES_USERA_UZYTY_MAP_PROCES_INIT ('.count($CRM_PROCES_USERA_UZYTY_MAP_PROCES_INIT).') (F.' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r($CRM_PROCES_USERA_UZYTY_MAP_PROCES_INIT);echo'</pre>';

	}

	function old() {
		if ($this->_user_id < 0) return false;

	echo '<p>{User id: '.$this->_user_id.'}</p>';

		Lib::loadClass('DB');
		$db = DB::getDB();

		$ID_ZASOBOW_USERA = array();
		// ! szukam jakimi user jestem zasobami - jakie stanowiska - wlaczenie uprawnien w oparciu o uprawnienia z SE!!
		$zap_sql = "select up.`ID_ZASOB`
			from  `ADMIN_USERS` AS u
				left join `CRM_AUTH_PROFILE` AS up on(up.`REMOTE_ID`=u.`ID` and up.`REMOTE_TABLE`='ADMIN_USERS') 
			where
				up.`A_STATUS` in('WAITING','NORMAL')
				and u.`ID`='{$this->_user_id}'
		";

		//Indeksuje kto co moze zrobic
		//szukam procesów
		$res = $db->query($zap_sql);
		while ($r = $db->fetch($res)) {
			$ID_ZASOBOW_USERA[] = $r->ID_ZASOB;
		}
		echo '<p>' . "1. ID_ZASOBOW_USERA: [" . implode(', ', $ID_ZASOBOW_USERA) . "]"  .'</p>';

	if (empty($ID_ZASOBOW_USERA)) {
		echo '<p style="color:red">' . "Brak przypisanego stanowiska!" . " Zaktualizuj je <a href='procesy5.php?task=USER_EDIT&_user_id=".$_SESSION['ADM_ID']."&_p=0'>tutaj w menu</a> </p>";
	}
	else {
		$ID_PROCESOW_USERA = array();
		$zap_sql="select p.`ID`
			from `CRM_PROCES` as p
				left join `CRM_WSKAZNIK` as w on(p.`ID`=w.`ID_PROCES`)
			where
				w.`ID_ZASOB` in(" . implode(",", $ID_ZASOBOW_USERA) . ")
				and w.`A_STATUS` in('NORMAL', 'WAITING')
				and p.`A_STATUS` in('NORMAL', 'WAITING')
		";
		$res = $db->query($zap_sql);
		while ($r = $db->fetch($res)) {
			$ID_PROCESOW_USERA [$r->ID]= true;
		}
		$ID_PROCESOW_USERA = array_keys($ID_PROCESOW_USERA);

		echo '<p>' . "2. ID_PROCESOW_USERA: [" . implode(', ', $ID_PROCESOW_USERA) . "]"  .'</p>';

		// ! zapisuje cala tabele procesow do arraya (i procesy powiazane GOTO z IF_TRUE_GOTO_FLAG=1)
		$CRM_PROCESS_TREE = array();// [PARENT_ID] = ID
		$zap_sql = "select p.`ID`, p.`PARENT_ID` from `CRM_PROCES` as p where p.`A_STATUS` in('WAITING','NORMAL')
					 union select p.`IF_TRUE_GOTO` as ID, p.`ID` as PARENT_ID from `CRM_PROCES` as p where p.`A_STATUS` in('WAITING','NORMAL') and p.IF_TRUE_GOTO>0 and p.IF_TRUE_GOTO_FLAG='GOTO_AND_RETURN'
					 ";
					 //	union select '83','122'		  union select p.`ID` as ID, p.`IF_TRUE_GOTO` as PARENT_ID from `CRM_PROCES` as p where p.`A_STATUS` in('WAITING','NORMAL') and p.IF_TRUE_GOTO>0 
					//union select '83','122'	
					//union select '83','2025'	
		$res = $db->query($zap_sql);
		while ($r = $db->fetch($res)) {
			$CRM_PROCESS_TREE[$r->PARENT_ID][] = $r->ID;
		}
echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;">3. CRM_PROCESS_TREE (F.' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r($CRM_PROCESS_TREE);echo'</pre>';

		$CRM_PROCES_USERA_UZYTY = array();
		$CRM_PROCES_USERA_UZYTY_MAP = array();
		// ! rekursywnie szukam sciezek procesow powiazanych dla usera procesow
		foreach ($ID_PROCESOW_USERA as $PU) {
			$CRM_PROCES_USERA_UZYTY [$PU] = true;
			if(isset($CRM_PROCES_USERA_UZYTY_FIND))
			unset($CRM_PROCES_USERA_UZYTY_FIND);
			$CRM_PROCES_USERA_UZYTY_FIND = $this->find_in_tree_parent_rec_old($CRM_PROCESS_TREE, $PU,'init');
			if(is_array($CRM_PROCES_USERA_UZYTY_FIND)) {
				$CRM_PROCES_USERA_UZYTY [$PU] = true; //trzeba dodac sam proces, bo go brakuje w indeksach
				$CRM_PROCES_USERA_UZYTY_MAP[$PU][]=$PU; //trzeba dodac sam proces, bo go brakowalo w indeksach
				foreach ($CRM_PROCES_USERA_UZYTY_FIND as $INDEX=>$PU1){
					$CRM_PROCES_USERA_UZYTY [$PU1] = true;
					$CRM_PROCES_USERA_UZYTY_MAP[$PU][]=$PU1; //tworze mape procesow od glownego w dol
				}
			}
		}
		$CRM_PROCES_USERA_UZYTY = array_keys($CRM_PROCES_USERA_UZYTY);

		echo '<p>' . "4. CRM_PROCES_USERA_UZYTY: [" . implode(', ', $CRM_PROCES_USERA_UZYTY) . "]"  .'</p>';

		unset($CRM_PROCESS_TREE);// ???

		//$TREE_CRM_WSKAZNIK = array();
		$CRM_TREE_WSKAZNIK_NARZEDZIE = array();
		//$TREE_CRM_WSKAZNIK_DESC = array();
		$TREE_CRM_WSKAZNIK_CONF = array();
		$TREE_CRM_WSKAZNIK_SORT_PRIO = array();

		// ! dla sciezek procesow wyszukuje powiazanych zasobow aby dac im permy
	$zap_sql = "select t1.`ID_PROCES`
				, t1.`ID_ZASOB`
				, replace(t2.`FORM_TREAT`, ',', '') as FORM_TREAT 
				, t3.`DESC` as ZASOB_DESC
				, t3.`TYPE`
				, t4.`DESC` as PARENT_ZASOB_DESC
				, t4.`TYPE` as PARENT_TYPE
				, t3.`SORT_PRIO` as z__SORT_PRIO
				, t3.`OPIS` as ZASOB_OPIS , t1.`ID` as ID_WSKAZNIK
			from `CRM_WSKAZNIK` as t1
				left join `CRM_PRZYPADEK` as t2 on (t1.ID_PRZYPADEK=t2.ID)
				left join `CRM_LISTA_ZASOBOW` as t3 on (t3.ID=t1.ID_ZASOB)
				left join `CRM_LISTA_ZASOBOW` as t4 on (t4.ID=t3.PARENT_ID)
			where
				(
					( t3.`TYPE`='KOMORKA' and t4.`TYPE`='TABELA' )
					or (t3.`TYPE`='NARZEDZIE') or (t3.`TYPE`='URL')
				)
				and t1.`A_STATUS` in('NORMAL', 'WAITING')
				and t1.`ID_PROCES` in(" . implode(",", $CRM_PROCES_USERA_UZYTY) . ")
		";
		if(sizeof($CRM_PROCES_USERA_UZYTY)>0) {
		$res = $db->query($zap_sql);
		while ($r = $db->fetch($res)) {
			if ($r->TYPE == 'NARZEDZIE') { //@2012-10-15 walka z warningami sqix
				  if(isset($CRM_TREE_WSKAZNIK_NARZEDZIE[$r->ID_ZASOB]))
						$CRM_TREE_WSKAZNIK_NARZEDZIE[$r->ID_ZASOB] .= $r->FORM_TREAT;
				  else $CRM_TREE_WSKAZNIK_NARZEDZIE[$r->ID_ZASOB] = $r->FORM_TREAT;
				 $CRM_WSKAZNIK_PROCES_WSKAZNIK_TREE[$r->ID_PROCES][]=$r->ID_WSKAZNIK; //ustawiam wskaznik od procesu, jak user wybierze proces do roboty, to ja poznam co moze mu sie pojawic

			} else if ($r->TYPE == 'URL') { 
				  $CRM_WSKAZNIK_PROCES_WSKAZNIK_TREE[$r->ID_PROCES][]=$r->ID_WSKAZNIK; //ustawiam wskaznik od procesu, jak user wybierze proces do roboty, to ja poznam co moze mu sie pojawic
				    $_SESSION['MENU_SELECT_PROCES_DATA']['MENU_COLUMN'][$r->ID_ZASOB]['TYPE']=$r->TYPE;
					$_SESSION['MENU_SELECT_PROCES_DATA']['MENU_COLUMN'][$r->ID_ZASOB]['DESC']=$r->ZASOB_DESC;
					$_SESSION['MENU_SELECT_PROCES_DATA']['MENU_COLUMN'][$r->ID_ZASOB]['OPIS']=$r->ZASOB_OPIS;

			} else {
				//$TREE_CRM_WSKAZNIK[$r->ID_ZASOB] .= $r->FORM_TREAT;
				//$TREE_CRM_WSKAZNIK_DESC[$r->ID_ZASOB] = $r->ZASOB_DESC;

				if ($r->PARENT_TYPE == 'TABELA') {
					$CRM_WSKAZNIK_PROCES_WSKAZNIK_TREE[$r->ID_PROCES][]=$r->ID_WSKAZNIK; //ustawiam wskaznik od procesu, jak user wybierze proces do roboty, to ja poznam co moze mu sie pojawic
					 if(isset($r->FORM_TREAT)) { //@2012-10-15 walka z warningami sqix
						  if(isset($TREE_CRM_WSKAZNIK_CONF[$r->PARENT_ZASOB_DESC][$r->ZASOB_DESC])) 
							$TREE_CRM_WSKAZNIK_CONF[$r->PARENT_ZASOB_DESC][$r->ZASOB_DESC] .= $r->FORM_TREAT;
						  else $TREE_CRM_WSKAZNIK_CONF[$r->PARENT_ZASOB_DESC][$r->ZASOB_DESC] = $r->FORM_TREAT;
						 // echo "<br. . . Dodaje dla:".$r->PARENT_ZASOB_DESC." ".$r->ZASOB_DESC." = ".$r->FORM_TREAT;
					  }
					  $TREE_CRM_WSKAZNIK_SORT_PRIO[$r->PARENT_ZASOB_DESC][$r->ZASOB_DESC] = $r->z__SORT_PRIO;


							//@2012-10-10 by SQIX : dodajemy opus kolumny z opisu zasobow
					if($r->ZASOB_OPIS) $_SESSION[$r->PARENT_ZASOB_DESC."_COLUMN"]['DESC_TO_LANG'][$r->ZASOB_DESC]=$r->ZASOB_OPIS;
					else if(isset($_SESSION[$r->PARENT_ZASOB_DESC."_COLUMN"]['DESC_TO_LANG'][$r->ZASOB_DESC])&&(strlen($_SESSION[$r->PARENT_ZASOB_DESC."_COLUMN"]['DESC_TO_LANG'][$r->ZASOB_DESC])>1)) 
							echo "<BR> DODAJ opis dla zasobu ".$r->ID_ZASOB." w postaci <pre>".$_SESSION[$r->PARENT_ZASOB_DESC."_COLUMN"]['DESC_TO_LANG'][$r->ZASOB_DESC]."</pre>";
				}
			}
		}
		}
echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;">5. TREE_CRM_WSKAZNIK_CONF (F.' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r($TREE_CRM_WSKAZNIK_CONF);echo'</pre>';

if(0) {// OFF TEST - nie ustalaj permów SE
		$dbg_set_permy = true;
		// !  inicjalizuje uprawnienia
		foreach ($TREE_CRM_WSKAZNIK_CONF as $ses_column_name => $field_perms_arr) {
			foreach ($field_perms_arr as $k_name => $v_perm) {
				$v_perm = str_split($v_perm);
				$v_perm = array_unique($v_perm);
				$v_perm = implode("", $v_perm);
	
				//if(isset($_SESSION[$ses_column_name."_COLUMN"]['PERMEDIT'][$k_name]))
				 $_SESSION[$ses_column_name."_COLUMN"]['PERMEDIT'][$k_name] = $v_perm;
				 //else $_SESSION[$ses_column_name."_COLUMN"]['PERMEDIT'][$k_name] = $v_perm."RWX"; //dokladamy permy do istniejacych!!! @2012-10-21- najlepsze na okres przejsciowy do generowania procesow!
				$debug_perms[]="_SESSION['".$ses_column_name."_COLUMN']['PERMEDIT'][".$k_name."]']=".$v_perm;

				//jezeli jest w kolumnie ID==W , to znaczy, ze mozna dodawac nowy rekord
				if ($k_name == 'ID' && strstr($v_perm, 'W')) {
					$_SESSION[$ses_column_name."_COLUMN"]['FUNCPERMEDIT']['NEW_RECORD'] = "RWXC";
					$_SESSION[$ses_column_name."_COLUMN"]['FUNCPERMEDIT']['TABLE_INSERTDB'] = "RWXC";
				}

				//jezeli jest funkcja powiazana to uprawnienia dostajemy takie same jak z komorki do tej funkcji!
				if (isset($_SESSION[$ses_column_name."_COLUMN"]['TYPESPECIAL'][$k_name])) {
					$debug_perms[]="_SESSION['".$ses_column_name."_COLUMN']['FUNCPERMEDIT']['".$_SESSION[$ses_column_name."_COLUMN"]['TYPESPECIAL'][$k_name]."']=".$v_perm;
					$_SESSION[$ses_column_name."_COLUMN"]['FUNCPERMEDIT'][$_SESSION[$ses_column_name."_COLUMN"]['TYPESPECIAL'][$k_name]] = $v_perm;
				}
			}

			{// sort DESC by ZASOB.SORT_PRIO
				$desc_to_sort = array();
				if(!isset($_SESSION[$ses_column_name."_COLUMN"]['DESC'])) {} //echo "<br><font color=red>L2375 Brak definicji w systemie opisanej procesami tabeli <b>".$ses_column_name."</b></font>"; //@2012-10-15 sqix walka z warningami
				else 
				foreach ($_SESSION[$ses_column_name."_COLUMN"]['DESC'] as $k_ind => $v_val) {
					$desc_to_sort[$v_val] = $k_ind;
				}

				$TREE_CRM_WSKAZNIK_SORT_PRIO[$ses_column_name];
				asort($TREE_CRM_WSKAZNIK_SORT_PRIO[$ses_column_name]);

				$new_desc = array();
				foreach ($TREE_CRM_WSKAZNIK_SORT_PRIO[$ses_column_name] as $k_name => $v_sort_prio) {
						if(!isset($desc_to_sort[$k_name])) {} //echo "<br><font color=red>Brak spojnosci definicji dla kolumny : ".$ses_column_name."[<b>".$k_name."</b>] </font>";
					 else $new_desc[$desc_to_sort[$k_name]] = $k_name; //@2012-10-15 walka z warningami sqix
				}
				// add columns
				foreach ($desc_to_sort as $k_name => $v_ind) {
					$new_desc[$v_ind] = $k_name;
				}

				$_SESSION[$ses_column_name."_COLUMN"]['DESC'] = $new_desc;
			}// sort DESC by ZASOB.SORT_PRIO

		}
		unset($dbg_set_permy);
}// if(0) - OFF TEST - nie ustalaj permów SE

	$_SESSION['CRM_PROCES_USERA_UZYTY'] = $CRM_PROCES_USERA_UZYTY;
	$_SESSION['CRM_PROCES_USERA_UZYTY_MAP'] = $CRM_PROCES_USERA_UZYTY_MAP;
	$_SESSION['CRM_LISTA_ZASOBOW_TREE'] = $CRM_TREE_WSKAZNIK_NARZEDZIE;//zapisanie jakie zasoby user ma dostepne!!! TODO
	$_SESSION['CRM_WSKAZNIK_PROCES_WSKAZNIK_TREE'] = $CRM_WSKAZNIK_PROCES_WSKAZNIK_TREE;//zapisanie jakie zasoby user ma dostepne!!! TODO

	// ! tutaj poszukamy co jest proces_init tylko z CRM_PROCES_USERA_UZYTY_MAP
	if (count($CRM_PROCES_USERA_UZYTY_MAP) > 0) {
		$sql="select `ID`,`DESC` from `CRM_PROCES` where `TYPE`='PROCES_INIT' and ID in (".implode(",", array_keys($CRM_PROCES_USERA_UZYTY_MAP)).") ";
		$res = $db->query($sql);
		$CRM_PROCES_USERA_UZYTY_MAP_PROCES_INIT = array();
		while($r = $db->fetch($res)) {
			$CRM_PROCES_USERA_UZYTY_MAP_PROCES_INIT[] = $r->ID;
		}
		$_SESSION['CRM_PROCES_USERA_UZYTY_MAP_PROCES_INIT']=$CRM_PROCES_USERA_UZYTY_MAP_PROCES_INIT;
	}
echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;">6. CRM_PROCES_USERA_UZYTY ('.count($CRM_PROCES_USERA_UZYTY).') (F.' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r($CRM_PROCES_USERA_UZYTY);echo'</pre>';
echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;">6. CRM_PROCES_USERA_UZYTY_MAP ('.count($CRM_PROCES_USERA_UZYTY_MAP).') (F.' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r($CRM_PROCES_USERA_UZYTY_MAP);echo'</pre>';
echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;">6. CRM_TREE_WSKAZNIK_NARZEDZIE ('.count($CRM_TREE_WSKAZNIK_NARZEDZIE).') (F.' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r($CRM_TREE_WSKAZNIK_NARZEDZIE);echo'</pre>';
echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;">6. CRM_WSKAZNIK_PROCES_WSKAZNIK_TREE ('.count($CRM_WSKAZNIK_PROCES_WSKAZNIK_TREE).') (F.' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r($CRM_WSKAZNIK_PROCES_WSKAZNIK_TREE);echo'</pre>';
echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;">6. CRM_PROCES_USERA_UZYTY_MAP_PROCES_INIT ('.count($CRM_PROCES_USERA_UZYTY_MAP_PROCES_INIT).') (F.' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r($CRM_PROCES_USERA_UZYTY_MAP_PROCES_INIT);echo'</pre>';

	}
	
	// ! po ustawieniu permow


	
	//nie wiem czy to tu wstawic czy wyzej ??? proba inicjalizacji tabel na bazie uzytych tabel::
						//zerzniete z MENU by PIOTR by sqix
					foreach($_SESSION as $COLUMN_INDEX=>$COLUMN_VAR) {
							if(substr($COLUMN_INDEX,-7)=='_COLUMN') {
								$prems_ok = false;
								if (isset($COLUMN_VAR['PERMEDIT'])) {
									$fields_deafult_R = array('ID','A_RECORD_CREATE_DATE','A_RECORD_CREATE_AUTHOR','A_RECORD_UPDATE_DATE','A_RECORD_UPDATE_AUTHOR');
									foreach ($COLUMN_VAR['PERMEDIT'] as $k_field => $v_perm) {
										if (in_array($k_field, $fields_deafult_R)) {
											continue;
								
										}
										if (false !== strpos($v_perm, 'R')) {
											$prems_ok = true;
					
										}
									}
								}
								if ($prems_ok) {
									if(substr($COLUMN_INDEX,-12)!='_HIST_COLUMN')  { // jezeli nie jest kolumna HIST!!
									 	 $RELATIVEDB_TRG_COLUMN_PARM=""; //parametr do przekazanie do funkcji dla extracolumn wirtualnych
										  if(is_array($COLUMN_VAR))
											if(isset($COLUMN_VAR['RELATIVEDB']))
											 if(isset($COLUMN_VAR['RELATIVEDB']['TRG_COLUMN']))
									 	 	foreach($COLUMN_VAR['RELATIVEDB']['TRG_COLUMN'] as $VCOLUMN=>$VCOLUMN_VAR) {
									 	 		if(empty($RELATIVEDB_TRG_COLUMN_PARM)) $RELATIVEDB_TRG_COLUMN_PARM=$VCOLUMN;
									 	 		else  $RELATIVEDB_TRG_COLUMN_PARM.=" ".$VCOLUMN;									 	 
									 	 	}
										 SEF('USERS_COLUMN_INIT2');
										 if(!in_array(substr($COLUMN_INDEX,0,(strlen($COLUMN_INDEX)-7)),$special_tables_ignore_init)) {
										 //if(!isset($_SESSION[$COLUMN_INDEX]['DESC'])) { 
									 	 	USERS_COLUMN_INIT2(substr($COLUMN_INDEX,0,(strlen($COLUMN_INDEX)-7)),$RELATIVEDB_TRG_COLUMN_PARM,'N','');
									 	 }
									}
					
								}
						    }
						}
	}

	/**
	 * @param str $when_finish - 'init', 'recurs'
	 */
	function find_in_tree_parent_rec_old(&$tree, $parent_id, $when_finish, &$items_array = array(), $dbg = false, $rec_limit = 1) {
		global $special_tables_ignore_init;//,$find_in_tree_parent_rec_return;
		static $find_in_tree_parent_rec_return;

		if ($dbg) { echo '<p style="margin:0;">' . "find_in_tree_parent_rec_old(tree, $parent_id, $when_finish, ret, $dbg, $rec_limit) find_in_tree_parent_rec_return: [" . implode(', ', $find_in_tree_parent_rec_return) . "] found(" . in_array($parent_id, $find_in_tree_parent_rec_return) . ")"  .'</p>'; }

		if ($when_finish == 'init') {
			//zerujemy zmienne
			$find_in_tree_parent_rec_return = array();
		}
		else {
			if (in_array($parent_id, $find_in_tree_parent_rec_return)) {
				return null;
			}
			if (count($find_in_tree_parent_rec_return) > 50) {
				die('Proces Loop limit!');
			}
		}

		$ret = array();
		$crm_proces_usera_uzyty = array();
		$ret_array = array();
		if (isset($tree[$parent_id])) {
			foreach ($tree[$parent_id] as $IND => $CHILD) {
				if (in_array($CHILD, $find_in_tree_parent_rec_return)) {
					continue;
				}

				$crm_proces_usera_uzyty[] = $CHILD;
				if ($dbg) { echo '<p style="margin:0;">' . "-- find_in_tree_parent_rec_old(tree, $parent_id, $when_finish, ret, $dbg, $rec_limit) crm_proces_usera_uzyty: [" . implode(', ', $crm_proces_usera_uzyty) . "]"  .'</p>'; }
				// TODO: $ret_array będize mial tylko wartosci z ostatniego wyszukiwania
				$ret_array = $this->find_in_tree_parent_rec_old($tree, $CHILD, 'recurs', $items_array, $dbg, $rec_limit);
			}
		}
		if (!empty($ret_array)) {
			foreach ($ret_array as $proces_id) {
				$ret[] = $proces_id;
			}
		}
		if (!empty($crm_proces_usera_uzyty)) {
			foreach ($crm_proces_usera_uzyty as $index => $proces_id) {
				$find_in_tree_parent_rec_return[] = $proces_id;
				$ret[] = $proces_id;
			}
		}
		//kiedy jest ostatnia petla wyswietlamy wynik drzewa
		if ($when_finish == 'init') {
			if ($dbg) { echo '<p style="margin:0;color:green;">' . "---- find_in_tree_parent_rec_old find_in_tree_parent_rec(..., $parent_id, $when_finish, ret, $dbg, $rec_limit) ret: [" . implode(', ', $find_in_tree_parent_rec_return) . "]"  .'</p>'; }
			return $find_in_tree_parent_rec_return;
		}
		else {
			if ($dbg) { echo '<p style="margin:0;">' . "---- return find_in_tree_parent_rec_old(..., $parent_id, $when_finish, ret, $dbg, $rec_limit) ret: [" . implode(', ', $ret) . "]"  .'</p>'; }
			return $ret;
		}
	}

	function find_in_tree_parent_rec(&$tree, $parent_id, &$ret_array = array(), $dbg = false, $rec_limit = 1) {
		if ($dbg) { echo '<p style="margin:0;">' . "find_in_tree_parent_rec(tree, $parent_id, ret, $dbg, $rec_limit) find_in_tree_parent_rec_return: [" . implode(', ', $find_in_tree_parent_rec_return) . "] found(" . in_array($parent_id, $ret_array) . ")"  .'</p>'; }

		if (isset($tree[$parent_id])) {
			foreach ($tree[$parent_id] as $IND => $CHILD) {
				if (in_array($CHILD, $ret_array)) {
					continue;
				}

				$ret_array[] = $CHILD;
				if ($dbg) { echo '<p style="margin:0;">' . "-- find_in_tree_parent_rec(tree, $parent_id, ret, $dbg, $rec_limit) crm_proces_usera_uzyty: [" . implode(', ', $ret_array) . "]"  .'</p>'; }
				// TODO: $ret_array będize mial tylko wartosci z ostatniego wyszukiwania
				$this->find_in_tree_parent_rec($tree, $CHILD, $ret_array, $dbg, $rec_limit);
			}
		}
	}

	function _cache_init() {
		if (!$this->_use_cache) return;

		if (!isset($_SESSION['UserAcl_cache'])) {
			$_SESSION['UserAcl_cache'] = array();
		}
		else {
			$user_id = V::get('_user_id', 0, $_SESSION['UserAcl_cache'], 'int');
			if ($user_id > 0) {
				if ($user_id != $this->_user_id) {
					// clean cache if another user
					$_SESSION['UserAcl_cache'] = array();
				}
			}
		}
	}

	function _cache_clear() {
		if (!$this->_use_cache) return;

		$_SESSION['UserAcl_cache'] = array();
	}

	/**
	 * Read data from cache.
	 */
	function _cache_read($key) {
		if (!$this->_use_cache) return null;

		if (array_key_exists($key, $_SESSION['UserAcl_cache'])) {
			return $_SESSION['UserAcl_cache'][$key];
		}
		return null;
	}

	/**
	 * Save data in cache.
	 */
	function _cache_save($key, $value) {
		if (!$this->_use_cache) return;

		if ($key == 'foundTables') {
			$tblIds = array();
			foreach ($value as $kID => $vTableAcl) {
				$tblIds[] = $kID;
				$vTableAcl->save();
			}
			$value = $tblIds;
		}
		$_SESSION['UserAcl_cache'][$key] = $value;
	}

	public function getUrls() {
		$urls = $this->_cache_read('foundUrls');// TODO: old ['MENU_SELECT_PROCES_DATA']['MENU_COLUMN']
		if (empty($urls)) $urls = array();
		return $urls;
	}

	public function getTablesAcl() {
		$tbls = array();
		Lib::loadClass('TableAcl');
		$tblIds = $this->_cache_read('foundTables');
		foreach ($tblIds as $vTableID) {
			$tbls[$vTableID] = TableAcl::getInstance($vTableID);
		}
		return $tbls;
	}

	public function hasTableAcl($tableID) {
		$tbls = $this->_cache_read('foundTables');
		return (is_array($tbls) && in_array($tableID, $tbls));
	}

	public function getTableAcl($tableID) {
		Lib::loadClass('TableAcl');
		return TableAcl::getInstance($tableID);
	}

	public function getProcesInitList($tblId) {
		if ($tblId > 0) {
			$map = $this->_cache_read('foundMap');
			if (is_array($map) && array_key_exists($tblId, $map)) {
				return $map[$tblId];
			}
		}
		return null;
	}

	/**
	 * Check if perms are only for one proces.
	 * @returns int or false
	 */
	public function getPermsProcesId() {
		$procesID = $this->_cache_read('permsByProcesID');
		if ($procesID > 0) {
			return $procesID;
		}
		return false;
	}

	public function fetchAllPerms($force = false) {
		$this->_fetchPerms('All', $force);
	}

	public function fetchProcesPerms($procesID, $force = false) {
		$this->_fetchPerms($procesID, $force);
	}

	/**
	 * @param $type - 'All', $procesID
	 */
	private function _fetchPerms($type, $force = false) {
		$db = DB::getDB();

		Lib::loadClass('TableAcl');

		$foundTools = array();// TODO: rename to $foundTools
		$foundUrls = array();// TODO: old ['MENU_SELECT_PROCES_DATA']['MENU_COLUMN']
		$foundTables = array();// TODO: old $CRM_WSKAZNIK_PROCES_WSKAZNIK_TABELA_KONFIG, $TREE_CRM_WSKAZNIK_CONF, ...
		$foundMap = array();
		$procesID = 0;// if 0 - All, alse perms by procesID

		if ($force) {
			if (!$procesID) {
				$foundMap = $this->_cache_read('foundMap');
			}
			$this->_cache_clear();
		}

		$usedProcesListIds = array();
		if ($type == 'All') {
			$usedProcesListIds = $this->getUsedProcesIds();
		} else if (is_numeric($type) && $type > 0) {
			$procesID = (int)$type;
			$usedProcesListIds = $this->getUsedProcesIds($procesID);
		}
		if (empty($usedProcesListIds)) {
			return;
		}
		$sql = "select t1.`ID_PROCES`
				, t1.`ID` as ID_WSKAZNIK
				, t1.`ID_ZASOB`
				, replace(t2.`FORM_TREAT`, ',', '') as FORM_TREAT
				, t3.`DESC` as ZASOB_DESC
				, t3.`DESC_PL` as ZASOB_DESC_PL
				, t3.`OPIS` as ZASOB_OPIS 
				, t3.`SORT_PRIO` as z__SORT_PRIO
				, t3.`TYPE`
				, t4.`DESC` as PARENT_ZASOB_DESC
				, t4.`DESC_PL` as PARENT_ZASOB_DESC_PL
				, t4.`OPIS` as PARENT_ZASOB_OPIS
				, t4.`TYPE` as PARENT_TYPE
				, t4.`ID` as ZASOB_PARENT_ID
				, t5.`ID` as ID_BAZY_KONFIG
			from `CRM_WSKAZNIK` as t1
				left join `CRM_PRZYPADEK` as t2 on (t1.ID_PRZYPADEK=t2.ID)
				left join `CRM_LISTA_ZASOBOW` as t3 on (t3.ID=t1.ID_ZASOB)
				left join `CRM_LISTA_ZASOBOW` as t4 on (t4.ID=t3.PARENT_ID)
				left join `CRM_LISTA_ZASOBOW` as t5 on (t5.ID=t4.PARENT_ID)
			where
				(
					( t3.`TYPE`='KOMORKA' and t4.`TYPE`='TABELA' )
					or (t3.`TYPE`='URL')
		--			or (t3.`TYPE`='NARZEDZIE')
				)
				and t1.`A_STATUS` in('NORMAL', 'WAITING')
				and t1.`ID_PROCES` in(" . implode(",", $usedProcesListIds) . ")
		";
		$res = $db->query($sql);
		while ($r = $db->fetch($res)) {
			if ($r->TYPE == 'URL') {
				$foundUrls[$r->ID_ZASOB] = $r->ZASOB_OPIS;
			}
			else if ($r->TYPE == 'NARZEDZIE') {
				if (!array_key_exists($r->ID_ZASOB, $foundTools)) {
					$foundTools[$r->ID_ZASOB] .= $r->FORM_TREAT;
				}
				else {
					$foundTools[$r->ID_ZASOB] = $r->FORM_TREAT;
				}
			}
			else {
				if ($r->PARENT_TYPE == 'TABELA') {
					// t3 - KOMORKA, t4 - TABELA, t5 - DATABASE
					if (!array_key_exists($r->ZASOB_PARENT_ID, $foundTables)) {
						$foundTables[$r->ZASOB_PARENT_ID] = new TableAcl($r->ZASOB_PARENT_ID);
						$foundTables[$r->ZASOB_PARENT_ID]->setDB($r->ID_BAZY_KONFIG);
						$foundTables[$r->ZASOB_PARENT_ID]->setName($r->PARENT_ZASOB_DESC);
						$foundTables[$r->ZASOB_PARENT_ID]->setLabel($r->PARENT_ZASOB_DESC_PL);
						$foundTables[$r->ZASOB_PARENT_ID]->setOpis($r->PARENT_ZASOB_OPIS);
					}

					if (!$foundTables[$r->ZASOB_PARENT_ID]->hasField($r->ID_ZASOB)) {
						$foundTables[$r->ZASOB_PARENT_ID]->addField($r->ID_ZASOB, $r->ZASOB_DESC, $r->ZASOB_OPIS, $r->z__SORT_PRIO, $r->ZASOB_DESC_PL);
					}

					if (!empty($r->FORM_TREAT)) {
						$foundTables[$r->ZASOB_PARENT_ID]->setFieldPerms($r->ID_ZASOB, $r->FORM_TREAT);
					}

					if (!$procesID) {
						$foundMap[$r->ZASOB_PARENT_ID][$r->ID_PROCES] = true;
					}
				}
			}
		}

		// build $foundMap
		if (!$procesID) {
			$map = $this->getUsedProcesMap();
			foreach ($foundMap as $kTblId => $vMap) {
				foreach ($vMap as $kProcesId => $vProcesInitId) {
					foreach ($map as $kPInitId => $vStepIds) {
						if (in_array($kProcesId, $vStepIds)) {
							$foundMap[$kTblId][$kProcesId] = $kPInitId;
							break;
						}
					}
				}
			}
		}

		$this->_cache_save('foundUrls', $foundUrls);
		$this->_cache_save('foundTables', $foundTables);
		$this->_cache_save('permsByProcesID', $procesID);
		$this->_cache_save('foundMap', $foundMap);
	}

}
