Browse Source

Schema process from file

Piotr Labudda 11 năm trước cách đây
mục cha
commit
6e6201de3a

+ 1 - 1
SE/VERSION

@@ -1 +1 @@
-3.9.10-2
+3.9.10-3

+ 1 - 0
SE/index.php

@@ -5,6 +5,7 @@ define('APP_PATH_ROOT', dirname(__FILE__));
 define('APP_PATH_LIB', APP_PATH_ROOT . '/se-lib');
 define('APP_PATH_WWW', APP_PATH_ROOT);
 define('APP_PATH_CONFIG', APP_PATH_ROOT . DS . 'config');
+define('APP_PATH_SCHEMA', APP_PATH_ROOT . DS . 'schema');
 
 //session_save_path("./tmp") ;
 session_start();

+ 25 - 17
SE/procesy/user.php

@@ -14,23 +14,31 @@ function task_USER() {
 
 	// Stanowiska powiazane z userem
 	$stanowiska = User::getGroups();
-	if (empty($stanowiska)) {
-		echo'<p class="red">'."Nie jestes przypisany do żadnego stanowiska - pilnie skontaktuj się z przełożonym!".'</p>';
-	} else {
-		echo '<div class="">';
-		echo '<p style="margin-bottom:0;">'."Stanowisko: ";
-			if (count($stanowiska) > 0) {
-				echo App::link("obowiązki", array('task'=>'CRM_WYSWIETL_OBOWIAZKI', 'z'=>array_keys($stanowiska)));
-			}
-		echo '</p>';
-		echo '<ul style="margin-top:0;">';
-		foreach ($stanowiska as $k_id => $v_zasob) {
-			echo '<li>' . "[" . App::link($k_id, array('task'=>'CRM_WYSWIETL_OBOWIAZKI', 'z'=>array($k_id))) . "] " . $v_zasob->DESC . '</li>';
-		}
-		echo '</ul>';
-		echo '</div>';// .box-blue
-	}
-
+	?>
+	<?php if (empty($stanowiska)) : ?>
+		<p class="red">Nie jestes przypisany do żadnego stanowiska - pilnie skontaktuj się z przełożonym!</p>
+		<?php if (User::hasAccess('user_add_group')) : ?>
+			<a class="btn btn-mini btn-primary" href="index.php?MENU_INIT=USER_ADD_GROUP&usrLogin=<?php echo User::getLogin(); ?>">przydziel stanowisko</a>
+		<?php endif; ?>
+	<?php else : ?>
+		<div class="">
+		<p style="margin-bottom:0;">Stanowisko:
+			<?php if (count($stanowiska) > 0) : ?>
+				<?php echo App::link("obowiązki", array('task'=>'CRM_WYSWIETL_OBOWIAZKI', 'z'=>array_keys($stanowiska))); ?>
+			<?php endif; ?>
+			<?php if (User::hasAccess('user_add_group')) : ?>
+				<a class="btn btn-mini btn-primary" href="index.php?MENU_INIT=USER_ADD_GROUP&usrLogin=<?php echo User::getLogin(); ?>">przydziel stanowisko</a>
+			<?php endif; ?>
+		</p>
+		<ul style="margin-top:0;">
+		<?php foreach ($stanowiska as $k_id => $v_zasob) : ?>
+			<li>[<?php echo App::link($k_id, array('task'=>'CRM_WYSWIETL_OBOWIAZKI', 'z'=>array($k_id))); ?>] <?php echo $v_zasob->DESC; ?></li>
+		<?php endforeach; ?>
+		</ul>
+		</div>
+	<?php endif; ?>
+
+	<?php
 	$db = DB::getDB();
 	Lib::loadClass('ProcesLogDao');
 	Lib::loadClass('ProcesLogSelectView');

+ 88 - 0
SE/schema/process/admin.user_add_group.ini.php

@@ -0,0 +1,88 @@
+;<?php
+;die();
+
+[CONFIG]
+type=PROCESS
+version=0.1
+date=2014-11-18
+
+[ACCESS]
+HAS_ACCESS[]=user_add_group
+
+[STEP:1]
+description='Procedura przyznawania uprawnień - przyporządkowywanie stanowiska pracownika do danego stanowiska ustalonego w Zasobach'
+
+[STEP:1:RESOURCE:1]
+uri=default_db/CRM_AUTH_PROFILE/ID
+type=TableField
+perms=RWXC
+
+[STEP:1:RESOURCE:2]
+uri=default_db/CRM_AUTH_PROFILE/REMOTE_TABLE
+type=TableField
+perms=RWXC
+
+[STEP:1:RESOURCE:3]
+uri=default_db/CRM_AUTH_PROFILE/REMOTE_ID
+type=TableField
+perms=RWXC
+
+[STEP:1:RESOURCE:4]
+uri=default_db/CRM_AUTH_PROFILE/A_STATUS
+type=TableField
+perms=RWXC
+
+[STEP:1:RESOURCE:5]
+uri=default_db/CRM_AUTH_PROFILE/ID_ZASOB
+type=TableField
+perms=RWXC
+
+[STEP:1:RESOURCE:6]
+uri=default_db/CRM_AUTH_PROFILE/SHOW_IN_PERIOD_MARK
+type=TableField
+perms=RWXC
+
+; RMME
+
+[RESOURCE:default_db:CRM_AUTH_PROFILE]
+type='TABLE'
+label='Przydział Uprawnień'
+description='Przydział uprawnień - Tabela do profilowania uprawnien dynamicznych do zasobow na podstawie tabeli ADMIN_USERS i CRM_LISTA_ZASOBOW take zawiera lokalizacje - moze byc unifikowana z tabela lokalizacji'
+
+[RESOURCE:default_db:CRM_AUTH_PROFILE:ID]
+perms=RWXC
+description='Unikalny klucz w tabeli'
+sort_prio=1
+label='Nr'
+
+[RESOURCE:default_db:CRM_AUTH_PROFILE:REMOTE_TABLE]
+perms=RWXC
+description='Odniesienie do tabeli , ktorej tyczy sie rekord, z reguly ADMIN_USERS'
+sort_prio=2
+label='Tabela'
+
+[RESOURCE:default_db:CRM_AUTH_PROFILE:REMOTE_ID]
+perms=RWXC
+description='Zdalny klucz w tabeli REMOTE_TABLE, ktorego tyczy sie wpis'
+sort_prio=3
+label='Nr pracownika'
+
+[RESOURCE:default_db:CRM_AUTH_PROFILE:A_STATUS]
+perms=RWXC
+description='Status rekordu wg notacji SE'
+sort_prio=4
+label='Status'
+
+[RESOURCE:default_db:CRM_AUTH_PROFILE:ID_ZASOB]
+perms=RWXC
+description=''
+sort_prio=5
+label='Nr zasobu'
+
+[RESOURCE:default_db:CRM_AUTH_PROFILE:SHOW_IN_PERIOD_MARK]
+perms=RWXC
+description='Czy dane powiązanie stanowiska ma być pokazywane na ocenie okresowej?'
+sort_prio=6
+label='ocen.okres.?'
+
+;?>

+ 1 - 1
SE/se-lib/Core/Config/INI.php

@@ -14,7 +14,7 @@ class Core_Config_INI {
 	/**
 	 * @return an associative array on success, and FALSE on failure.
 	 */
-	public function &getData() {
+	public function getData() {
 		if ($this->_data === null) {// @see __construct()
 			if (!file_exists($this->_config_file)) {
 				$this->_data = false;

+ 45 - 0
SE/se-lib/ProcesHelper.php

@@ -480,6 +480,51 @@ class ProcesHelper {
 		return $zasobObj;
 	}
 
+	public static function getZasobTableInfoByUri($uri) {
+		$zasobObj = null;
+		$db = DB::getDB();
+		$uriParts = explode('/', $uri);
+		if (count($uriParts) < 2) {
+			return null;
+		}
+		$tblName = array_pop($uriParts);
+		$dbName = array_pop($uriParts);
+		if ('default_db' == $dbName) {
+			$dbName = $db->getDatabaseName();
+		}
+		$sql = "select z.`ID`, z.`DESC`, z.`DESC_PL`, z.`OPIS`
+				, zp.`ID` as P__ID, zp.`DESC` as P__DESC, zp.`TYPE` as P__TYPE
+			from `CRM_LISTA_ZASOBOW` as z
+				left join `CRM_LISTA_ZASOBOW` as zp on(zp.`ID`=z.`PARENT_ID`)
+			where z.`DESC`='{$tblName}'
+				and z.`TYPE`='TABELA'
+				and zp.`DESC`='{$dbName}'
+		--		and zp.`TYPE` in('DATABASE_MYSQL','DATABASE')
+		";
+		if('1' == V::get('DBG_SQL', '', $_GET)){echo'<pre style="max-height:200px;overflow:auto;border:1px solid green;text-align:left;">sql (' . __CLASS__ . '::' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r($sql);echo'</pre>';}
+		$res = $db->query($sql);
+		if ($res) {
+			$zasobObj = $db->fetch($res);
+		}
+		return $zasobObj;
+	}
+
+	public static function getZasobTableFieldsInfo($id) {
+		$fldsInfo = array();
+		$db = DB::getDB();
+		$sql = "select z.`ID`, z.`DESC`, z.`DESC_PL`, z.`OPIS`, z.`SORT_PRIO`
+			from `CRM_LISTA_ZASOBOW` as z
+			where z.`TYPE`='KOMORKA'
+				and z.`PARENT_ID`={$id}
+		";
+		if('1' == V::get('DBG_SQL', '', $_GET)){echo'<pre style="max-height:200px;overflow:auto;border:1px solid green;text-align:left;">sql (' . __CLASS__ . '::' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r($sql);echo'</pre>';}
+		$res = $db->query($sql);
+		while ($r = $db->fetch($res)) {
+			$fldsInfo[$r->DESC] = $r;
+		}
+		return $fldsInfo;
+	}
+
 	public static function getZasobInfo($zasobID) {
 		$zasobObj = null;
 		$db = DB::getDB();

+ 29 - 28
SE/se-lib/ProcesLogDao.php

@@ -25,7 +25,7 @@
  * 
  * 
  * 
- * Obs³uga plików:
+ * Obsługa plików:
  *   Zasoby:
  * serwer (host)
  *   ZASOB_PLIKOW (path eg. /home/samba)
@@ -63,20 +63,21 @@ Lib::loadClass('ProcesLogModel');
 
 class ProcesLogDao extends BaseDao {
 
-	function __construct( $db ) {
+	function __construct($db) {
 		parent::__construct($db, 'CRM_PROCES_LOG');
 	}
 
-	function get_by_id( $id ) {
+	function get_by_id($id) {
 		$null = null;
 		$id = (int)$id;
 		if ($id <= 0) return $null;
+		$db = DB::getDB();
 		$sql = "select t.*
-			from `" . $this->_table . "` as t
-			where t.`ID`='" . $id . "'
+			from `{$this->_table}` as t
+			where t.`ID`='{$id}'
 		";
-		$res = DB::query($sql);
-		if ($h = DB::fetch_assoc($res)) {
+		$res = $db->query($sql);
+		if ($h = $db->fetch_assoc($res)) {
 			$model = new ProcesLogModel($this);
 			$model->setDataFromDB($h);
 			return $model;
@@ -84,18 +85,18 @@ class ProcesLogDao extends BaseDao {
 		return $null;
 	}
 
-	function get_hist( $id ) {
+	function get_hist($id) {
 	}
 
 	/**
 	 * @returns int
 	 */
-	function get_user_log_list_count( $user_id, $user_groups ) {
+	function get_user_log_list_count($user_id, $user_groups) {
 		$ret = 0;
 		$sql_where = $this->_get_user_log_list_query_where($user_id, $user_groups);
 		$sql = "select count(1) as cnt
-			from `" . $this->_table . "` as plog
-			where " . $sql_where . "
+			from `{$this->_table}` as plog
+			where {$sql_where}
 		";
 		$res = $this->_db->query($sql);
 		if ($r = $this->_db->fetch($res)) {
@@ -107,14 +108,14 @@ class ProcesLogDao extends BaseDao {
 	/**
 	 * @returns array of ProcesLogModel objects.
 	 */
-	function get_user_log_list( $user_id, $user_groups, $limitstart = 0 ) {
+	function get_user_log_list($user_id, $user_groups, $limitstart = 0) {
 		$ret = array();
 		$sql_offset = intval($limitstart);
 		$sql_where = $this->_get_user_log_list_query_where($user_id, $user_groups);
 		$sql = "select plog.*
-			from `" . $this->_table . "` as plog
-			where " . $sql_where . "
-			limit 20 offset " . $sql_offset . "
+			from `{$this->_table}` as plog
+			where {$sql_where}
+			limit 20 offset {$sql_offset}
 		";
 		$res = $this->_db->query($sql);
 		while ($r = $this->_db->fetch($res)) {
@@ -125,7 +126,7 @@ class ProcesLogDao extends BaseDao {
 		return $ret;
 	}
 
-	function _get_user_log_list_query_where( $user_id, $user_groups ) {
+	function _get_user_log_list_query_where($user_id, $user_groups) {
 		$sql_where = '';
 		$sql_where_groups_add = '';
 		if (!empty($user_groups)) {
@@ -135,8 +136,8 @@ class ProcesLogDao extends BaseDao {
 			}
 			$sql_where_groups_add .= " or (plog.`ID_USER`=0 and (" . implode(" or ", $sql_where_groups_and) . "))";
 		}
-		$sql_where = "( (plog.`ID_USER`>0 and plog.`ID_USER`='" . $user_id . "')
-				" . $sql_where_groups_add . " )
+		$sql_where = "( (plog.`ID_USER`>0 and plog.`ID_USER`='{$user_id}')
+				{$sql_where_groups_add} )
 		";
 		return $sql_where;
 	}
@@ -154,7 +155,7 @@ class ProcesLogDao extends BaseDao {
 		$log_model->set('TYPE', 'INIT');
 		$log_model->set('ID_PROCES_INIT', $proces_id);
 		$log_model->set('ID_STEP', $proces_id);
-		//$log_model->set('ID_STANOWISKA', '');// nieokrelony
+		//$log_model->set('ID_STANOWISKA', '');// nieokreślony
 		$log_model->set('ID_KEY', 0);
 		return $this->save($log_model);
 	}
@@ -170,14 +171,14 @@ class ProcesLogDao extends BaseDao {
 		}
 		switch ($model->get('TYPE')) {
 			case 'INIT':
-				$actions ['step']= "kontynuuj";
+				$actions['step'] = "kontynuuj";
 				break;
 			case 'STEP':
-				$actions ['step']= "kontynuuj";
-				$actions ['quit']= "zakoñcz";
+				$actions['step'] = "kontynuuj";
+				$actions['quit'] = "zakończ";
 				break;
 			case 'END':
-				$actions ['hist']= "hist";
+				$actions['hist'] = "hist";
 				break;
 		}
 
@@ -228,7 +229,7 @@ class ProcesLogDao extends BaseDao {
 		}
 		$sql = "select p.`ID`, p.`DESC`
 			from `CRM_PROCES` as p
-			where p.`PARENT_ID`='" . $cur_step_id . "'
+			where p.`PARENT_ID`='{$cur_step_id}'
 				and p.`A_STATUS` in ('WAITING', 'NORMAL')
 			order by p.`SORT_PRIO` asc, p.`ID` asc
 		";
@@ -260,12 +261,12 @@ class ProcesLogDao extends BaseDao {
 				left join `CRM_LISTA_ZASOBOW` as clz on (clz.`ID`=w.`ID_ZASOB`)
 				left join `CRM_PRZYPADEK` as cp on (cp.`ID`=w.`ID_PRZYPADEK`)
 			where
-				w.`ID_PROCES`='".$proces_id."'
+				w.`ID_PROCES`='{$proces_id}'
 				and w.`A_STATUS` in('WAITING','NORMAL','MONITOR')
 			order by w.`SORT_PRIO` asc, w.`ID` asc
 		";
-		$res = $this->_db->query( $sql );
-		while ($r = $this->_db->fetch( $res )) {
+		$res = $this->_db->query($sql);
+		while ($r = $this->_db->fetch($res)) {
 			$ret[$r->CW_ID] = $r;
 		}
 		return $ret;
@@ -284,7 +285,7 @@ class ProcesLogDao extends BaseDao {
 	function get_sql_types($sql_table) {
 		$db = DB::getDB();
 		$types = array();
-		$sql = "show fields from `" . $sql_table . "`;";
+		$sql = "show fields from `{$sql_table}`;";
 		$res = $db->query($sql);
 		while ($r = $db->fetch($res)) {
 			$field = $r->Field;

+ 1 - 1
SE/se-lib/ProcesMenu.php

@@ -117,7 +117,7 @@ class ProcesMenu {
 							if ($max_update_date) {
 								$max_update_date = substr($max_update_date, 0, 10);
 								$test_end = substr($last_test->TEST_END, 0, 10);
-								echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;">'."P_INIT({$k_proces_id}) max_update_date({$max_update_date}) TEST_END({$last_test->TEST_END}) not actual(" . ($max_update_date > $last_test->TEST_END) . ")".' (' . __CLASS__ . '::' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r($last_test);echo'</pre>';
+								if('1' == V::get('DBG_PM', '', $_GET)){echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;">'."P_INIT({$k_proces_id}) max_update_date({$max_update_date}) TEST_END({$last_test->TEST_END}) not actual(" . ($max_update_date > $last_test->TEST_END) . ")".' (' . __CLASS__ . '::' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r($last_test);echo'</pre>';}
 								if ($max_update_date > $test_end) {
 									$testy_arr[$last_test->test_ind]->unactual = $max_update_date;
 									$testy_arr[$last_test->test_ind]->unactualId = $last_test->ID;

+ 88 - 0
SE/se-lib/SchemaReader.php

@@ -0,0 +1,88 @@
+<?php
+
+Lib::loadClass('Core_Config_INI');
+Lib::loadClass('SchemaReaderProcess');
+
+class SchemaReader {
+
+	private $_schemaPathProcess;
+	private $_configIniSuffix;
+	private $_configs = null;
+
+	public function __construct() {
+		$this->_schemaPathProcess = APP_PATH_SCHEMA . DS . 'process';
+		$this->_configIniSuffix = '.ini.php';
+	}
+
+	public function getAll() {
+		if (!is_array($this->_configs)) {
+			$this->_configs = array();
+			$fileGlob = "{$this->_schemaPathProcess}/*{$this->_configIniSuffix}";
+			$files = glob($fileGlob);
+			foreach ($files as $file) {
+				$this->_parseIniFile($file);
+			}
+		}
+	}
+
+	private function _parseIniFile($file) {
+		$fileName = basename($file, $this->_configIniSuffix);
+		$config = new Core_Config_INI($file);
+		$configData = $config->getData();
+		$type = $config->get('type', 'CONFIG');
+		if (!$type) {
+			return;
+		}
+		$className = "SchemaReader" . ucfirst(strtolower($type));
+		if (!class_exists($className)) {
+			return;
+		}
+		$reader = new $className();
+		if (!$reader->parseIniConfig($config)) {
+			return;
+		}
+		$this->_configs[$fileName] = $reader;
+	}
+
+	public function hasProcessConfigs() {
+		return !empty($this->_configs);
+	}
+
+	public function getProcessConfigs() {
+		return $this->_configs;
+	}
+
+	public function findTblInfoByUri($uri) {
+		
+	}
+
+	public static function buildProcessStepFromIni($stepNr, $configData) {
+		$className = "SchemaReaderProcessStep";
+		if (!Lib::loadClass($className)) {
+			return null;
+		}
+		$step = new $className($stepNr);
+		if (!$step->parseIniConfig($configData)) {
+			return null;
+		}
+		return $step;
+	}
+
+	public static function buildFromIni($resourceUri, $configData) {
+		$resourceType = V::get('type', '', $configData);
+		if (!$resourceType) {
+			echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;"> (' . __CLASS__ . '::' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r("!resourceType");echo'</pre>';
+			return null;
+		}
+		$className = "SchemaReaderResource{$resourceType}";
+		if (!Lib::loadClass($className)) {
+			return null;
+		}
+		$resource = new $className($resourceUri);
+		if (!$resource->parseIniConfig($configData)) {
+			return null;
+		}
+		return $resource;
+	}
+
+}

+ 113 - 0
SE/se-lib/SchemaReaderProcess.php

@@ -0,0 +1,113 @@
+<?php
+
+Lib::loadClass('User');
+Lib::loadClass('SchemaReader');
+
+class SchemaReaderProcess {
+
+	private $_version;
+	private $_date;
+	private $_access = array();
+	private $_accessGroups = array();
+	private $_steps = array();
+	private $_resourcesTable = array();
+	private $_resources = array();
+
+	public function __construct() {
+	}
+
+	public function parseIniConfig($config) {
+		$configData = $config->getData();
+
+		$this->_version = $config->get('version', 'CONFIG');
+		$this->_date = $config->get('date', 'CONFIG');
+
+		if('1' == V::get('DBG_SCH', '', $_GET)){echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;">$configData (' . __CLASS__ . '::' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r($configData);echo'</pre>';}
+		$configSections = array_keys($configData);
+		if (in_array('ACCESS', $configSections)) {
+			if (array_key_exists('HAS_ACCESS', $configData['ACCESS'])) {
+				$this->_access = $configData['ACCESS']['HAS_ACCESS'];
+				if (!is_array($this->_access)) $this->_access = array($this->_access);
+			}
+			if (array_key_exists('GROUPS', $configData['ACCESS'])) {
+				$this->_accessGroups = $configData['ACCESS']['GROUPS'];
+				if (!is_array($this->_accessGroups)) $this->_accessGroups = array($this->_accessGroups);
+			}
+		}
+
+		$this->_steps = array();
+		foreach ($configSections as $section) {
+			if ('STEP' == substr($section, 0, 4)) {
+				$sectionParts = explode(':', $section);
+				$sectionPartsCnt = count($sectionParts);
+				if ($sectionPartsCnt == 2) {// eg. [STEP:1]
+					$stepNr = $sectionParts[1];
+					$step = SchemaReader::buildProcessStepFromIni($stepNr, $configData[$section]);
+					if ($step) {
+						$this->_steps[$stepNr] = $step;
+					}
+				}
+			}
+		}
+		if('1' == V::get('DBG_SCH', '', $_GET)){echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;">$this->_steps:1 (' . __CLASS__ . '::' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r($this->_steps);echo'</pre>';}
+
+		foreach ($configSections as $section) {
+			if ('STEP' == substr($section, 0, 4)) {
+				$sectionParts = explode(':', $section);
+				$sectionPartsCnt = count($sectionParts);
+				if ($sectionPartsCnt > 3) {// eg. [STEP:1:RESOURCE:1]
+					$stepNr = $sectionParts[1];
+					$resourceUri = V::get('uri', '', $configData[$section]);
+					if (!$resourceUri) continue;
+					$resource = SchemaReader::buildFromIni($resourceUri, $configData[$section]);
+					if ($resource && array_key_exists($stepNr, $this->_steps)) {
+						$this->_steps[$stepNr]->addResource($resource);
+					}
+				}
+			}
+		}
+		if('1' == V::get('DBG_SCH', '', $_GET)){echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;">$this->_steps:2 (' . __CLASS__ . '::' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r($this->_steps);echo'</pre>';}
+
+		$this->_resourcesTable = array();
+		foreach ($this->_steps as $step) {
+			$stepTbls = $step->getTables();
+			foreach ($stepTbls as $tblUri => $tbl) {
+				if (array_key_exists($tblUri, $this->_resourcesTable)) {
+					$this->_resourcesTable[$tblUri]->mergeFields($tbl);
+				} else {
+					$this->_resourcesTable[$tblUri] = $tbl;
+				}
+			}
+		}
+		if('1' == V::get('DBG_SCH', '', $_GET)){echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;">this->_resourcesTable (' . __CLASS__ . '::' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r($this->_resourcesTable);echo'</pre>';}
+
+		return true;
+	}
+
+	public function hasTables() {
+		return !empty($this->_resourcesTable);
+	}
+
+	public function getTables() {
+		return $this->_resourcesTable;
+	}
+
+	public function hasAccess() {
+		if (!empty($this->_access)) {
+			foreach ($this->_access as $accessName) {
+				if (User::hasAccess($accessName)) {
+					return true;
+				}
+			}
+		}
+		if (!empty($this->_accessGroups)) {
+			foreach ($this->_accessGroups as $accessGroup) {
+				if (User::hasGroup($accessGroup)) {
+					return true;
+				}
+			}
+		}
+		return false;
+	}
+
+}

+ 54 - 0
SE/se-lib/SchemaReaderProcessStep.php

@@ -0,0 +1,54 @@
+<?php
+
+Lib::loadClass('SchemaReader');
+Lib::loadClass('SchemaReaderResourceTableField');
+
+class SchemaReaderProcessStep {
+
+	private $_nr;
+	private $_resourcesRefTable = array();
+	private $_resources = array();
+
+	public function __construct($stepNr) {
+		$this->_nr = $stepNr;
+	}
+
+	public function parseIniConfig($configData) {
+		$this->_description = V::get('description', '', $configData);
+		return true;
+	}
+
+	public function addResource($resource) {
+		if ($resource instanceof SchemaReaderResourceTableField) {
+			$this->_resourcesRefTable[$resource->getTableUri()] = true;
+		}
+		$resourceUri = $resource->getUri();
+		if (array_key_exists($resourceUri, $this->_resources)) {
+			$this->_resources[$resourceUri]->addPerms($resource->getPerms());
+		} else {
+			$this->_resources[$resourceUri] = $resource;
+		}
+	}
+
+	public function hasTables() {
+		return !empty($this->_resourcesFields);
+	}
+
+	public function getTables() {
+		$tbls = array();
+		foreach ($this->_resourcesRefTable as $tblUri => $vBool) {
+			$configData = array('type'=>'Table');
+			$tbl = SchemaReader::buildFromIni($tblUri, $configData);
+			foreach ($this->_resources as $resource) {
+				if ($resource instanceof SchemaReaderResourceTableField) {
+					if ($tbl->getUri() == $resource->getTableUri()) {
+						$tbl->addField($resource);
+					}
+				}
+			}
+			$tbls[$tblUri] = $tbl;
+		}
+		return $tbls;
+	}
+
+}

+ 21 - 0
SE/se-lib/SchemaReaderResource.php

@@ -0,0 +1,21 @@
+<?php
+
+class SchemaReaderResource {
+
+	protected $_uri;
+
+	public function __construct($uri) {
+		$this->_uri = $uri;
+		$this->_uri = str_replace(':', '/', $this->_uri);
+	}
+
+	public function parseIniConfig($configData) {
+	}
+
+	public function getUri() { return $this->_uri; }
+	public function getName() {
+		$uriParts = explode('/', $this->_uri);
+		return array_pop($uriParts);
+	}
+
+}

+ 55 - 0
SE/se-lib/SchemaReaderResourceTable.php

@@ -0,0 +1,55 @@
+<?php
+
+Lib::loadClass('SchemaReaderResource');
+Lib::loadClass('SchemaReaderResourceTableField');
+
+class SchemaReaderResourceTable extends SchemaReaderResource {
+
+	protected $_uri;
+	private $_name;
+	private $_label;
+	private $_description;
+	private $_fields = array();
+
+	public function __construct($uri) {
+		parent::__construct($uri);
+	}
+
+	public function parseIniConfig($configData) {
+		$this->_label = V::get('label', '', $configData);
+		$this->_description = V::get('description', '', $configData);
+		return true;
+	}
+
+	public function parseIniSubConfig($path, $configData) {
+		$uri = $this->_uri . '/' . str_replace(':', '/', $path);
+		$reader = new SchemaReaderResourceTableField($uri);
+		if (!$reader->parseIniConfig($configData)) {
+			if('1' == V::get('DBG_SCH', '', $_GET)){echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;"> (' . __CLASS__ . '::' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r("!parseIniConfig()");echo'</pre>';}
+			continue;
+		}
+		$this->addField($resource);
+		return true;
+	}
+
+	public function addField($resource) {
+		$uri = $resource->getUri();
+		if (array_key_exists($uri, $this->_fields)) {
+			$this->_fields[$uri]->addPerms($resource->getPerms());
+		} else {
+			$this->_fields[$uri] = $resource;
+		}
+	}
+
+	public function mergeFields($tbl) {
+		foreach ($tbl->getFields() as $field) {
+			$this->addField($field);
+		}
+	}
+
+	public function getUri() { return $this->_uri; }
+	public function getLabel() { return $this->_label; }
+	public function getDescription() { return $this->_description; }
+	public function getFields() { return $this->_fields; }
+
+}

+ 48 - 0
SE/se-lib/SchemaReaderResourceTableField.php

@@ -0,0 +1,48 @@
+<?php
+
+Lib::loadClass('SchemaReaderResource');
+
+class SchemaReaderResourceTableField extends SchemaReaderResource {
+
+	protected $_uri;
+	private $_label;
+	private $_description;
+	private $_perms;
+	private $_sort_prio;
+
+	public function __construct($uri) {
+		parent::__construct($uri);
+	}
+
+	public function parseIniConfig($configData) {
+		$this->_label = V::get('label', '', $configData);
+		$this->_description = V::get('description', '', $configData);
+		$this->_perms = V::get('perms', '', $configData);
+		$this->_sort_prio = V::get('sort_prio', 0, $configData, 'int');
+		return true;
+	}
+
+	public function addPerms($perms) {
+		$perms .= $this->_perms;
+		$perms = str_split($perms);
+		$perms = array_unique($perms);
+		$perms = implode('', $perms);
+		$this->_perms = $perms;
+	}
+
+	public function getTableName() {
+		$uriParts = explode('/', $this->_uri);
+		array_pop($uriParts);
+		return array_pop($uriParts);
+	}
+	public function getTableUri() {
+		$uriParts = explode('/', $this->_uri);
+		array_pop($uriParts);
+		return implode('/', $uriParts);
+	}
+	public function getLabel() { return $this->_label; }
+	public function getDescription() { return $this->_description; }
+	public function getPerms() { return $this->_perms; }
+	public function getSortPrio() { return $this->_sort_prio; }
+
+}

+ 10 - 0
SE/se-lib/User.php

@@ -147,6 +147,7 @@ class User {
 		if (!$_acl) {
 			Lib::loadClass('UserAcl');
 			$_acl = new UserAcl(self::getID(), $use_cache = true);
+			$_acl->fetchGroups();
 		}
 		return $_acl;
 	}
@@ -604,12 +605,21 @@ class User {
 				if (User::get('ADM_ADMIN_LEVEL') < 3) return true;
 				break;
 			}
+			case 'user_add_group': {
+				if (User::get('ADM_ADMIN_LEVEL') < 1) return true;
+				break;
+			}
 			default:
 				
 		}
 		return false;
 	}
 
+	public static function hasGroup($groupName) {
+		// TODO: find group by name @see self::getGroups() @used in SchemaReaderProcess
+		return false;
+	}
+
 	public static function getAnonymousAccount() {
 		$db = DB::getDB();
 		if (!$db) die("Error DB connection!");

+ 62 - 21
SE/se-lib/UserAcl.php

@@ -1,5 +1,10 @@
 <?php
 
+Lib::loadClass('DB');
+Lib::loadClass('UsersHelper');
+Lib::loadClass('ProcesHelper');
+Lib::loadClass('TableAcl');
+Lib::loadClass('SchemaReader');
 
 class UserAcl {
 
@@ -34,7 +39,6 @@ class UserAcl {
 		}
 		$this->_groups = array();
 
-		Lib::loadClass('UsersHelper');
 		$this->_groups = UsersHelper::get_group_by_user($this->_user_id);
 
 		$this->_cache_save('_groups', $this->_groups);
@@ -46,7 +50,6 @@ class UserAcl {
 		if (!empty($this->_proces_ids)) {
 			return $this->_proces_ids;
 		}
-		Lib::loadClass('DB');
 		$db = DB::getDB();
 		$groups = $this->fetchGroups();
 		if (empty($groups)) {
@@ -73,7 +76,6 @@ class UserAcl {
 			return $this->_proces_tree_flat;
 		}
 
-		Lib::loadClass('DB');
 		$db = DB::getDB();
 		$sql = "select p.`ID`, p.`PARENT_ID`
 				from `CRM_PROCES` as p
@@ -164,7 +166,6 @@ class UserAcl {
 
 		$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);
@@ -207,7 +208,6 @@ echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:
 			return false;
 		}
 
-		Lib::loadClass('DB');
 		$db = DB::getDB();
 
 		//$TREE_CRM_WSKAZNIK = array();
@@ -300,7 +300,6 @@ echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:
 
 	echo '<p>{User id: '.$this->_user_id.'}</p>';
 
-		Lib::loadClass('DB');
 		$db = DB::getDB();
 
 		$ID_ZASOBOW_USERA = array();
@@ -705,7 +704,6 @@ echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:
 
 	public function getTablesAcl() {
 		$tbls = array();
-		Lib::loadClass('TableAcl');
 		$tblIds = $this->_cache_read('foundTables');
 		foreach ($tblIds as $vTableID) {
 			$tbls[$vTableID] = TableAcl::getInstance($vTableID);
@@ -719,7 +717,6 @@ echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:
 	}
 
 	public function getTableAcl($tableID) {
-		Lib::loadClass('TableAcl');
 		return TableAcl::getInstance($tableID);
 	}
 
@@ -759,11 +756,9 @@ echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:
 	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, ...
+		$foundTbls = array();// TODO: old $CRM_WSKAZNIK_PROCES_WSKAZNIK_TABELA_KONFIG, $TREE_CRM_WSKAZNIK_CONF, ...
 		$foundMap = array();
 		$procesID = 0;// if 0 - All, alse perms by procesID
 
@@ -775,7 +770,9 @@ echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:
 		}
 
 		$usedProcesListIds = array();
+		$schemaReader = new SchemaReader();
 		if ($type == 'All') {
+			$schemaReader->getAll();
 			$usedProcesListIds = $this->getUsedProcesIds();
 		} else if (is_numeric($type) && $type > 0) {
 			$procesID = (int)$type;
@@ -784,6 +781,49 @@ echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:
 		if (empty($usedProcesListIds)) {
 			return;
 		}
+
+		{// fetch from schema files
+		if ($schemaReader->hasProcessConfigs()) {
+			foreach ($schemaReader->getProcessConfigs() as $process) {
+				if('1' == V::get('DBG_SCH', '', $_GET)){echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;">process (' . __CLASS__ . '::' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r($process);echo'</pre>';}
+				if ($process->hasAccess()) {
+					$tables = $process->getTables();
+					if('1' == V::get('DBG_SCH', '', $_GET)){echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;">$tables (' . __CLASS__ . '::' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r($tables);echo'</pre>';}
+					foreach ($tables as $table) {
+						$tblUri = $table->getUri();
+						$zasobTblInfo = ProcesHelper::getZasobTableInfoByUri($tblUri);
+						if('1' == V::get('DBG_SCH', '', $_GET)){echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;">table('.$table->getLabel().') $zasobTblInfo (' . __CLASS__ . '::' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r($zasobTblInfo);echo'</pre>';}
+						if ($zasobTblInfo) {
+
+							if (!array_key_exists($zasobTblInfo->ID, $foundTbls)) {
+								$tblAcl = new TableAcl($zasobTblInfo->ID);
+								$tblAcl->setDB($zasobTblInfo->P__ID);
+								$tblAcl->setName($table->getName());
+								$tblAcl->setLabel($table->getLabel());
+								$tblAcl->setOpis($table->getDescription());
+								$foundTbls[$zasobTblInfo->ID] = $tblAcl;
+							}
+
+							$fldsInfo = ProcesHelper::getZasobTableFieldsInfo($zasobTblInfo->ID);
+							foreach ($table->getFields() as $field) {
+								$fldInfo = V::get($field->getName(), null, $fldsInfo);
+								if ($fldInfo) {
+									if (!$foundTbls[$zasobTblInfo->ID]->hasField($r->ID_ZASOB)) {
+										$foundTbls[$zasobTblInfo->ID]->addField($fldInfo->ID, $fldInfo->DESC, $fldInfo->OPIS, $fldInfo->SORT_PRIO, $fldInfo->DESC_PL);
+									}
+
+									$foundTbls[$zasobTblInfo->ID]->setFieldPerms($fldInfo->ID, $field->getPerms());
+								}
+							}
+						}
+					}
+				}
+			}
+		}
+		if('1' == V::get('DBG_SCH', '', $_GET)){echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;">$foundTbls (' . __CLASS__ . '::' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r($foundTbls);echo'</pre>';}
+		}// fetch from schema files
+
+		{// fetch from DB
 		$sql = "select t1.`ID_PROCES`
 				, t1.`ID` as ID_WSKAZNIK
 				, t1.`ID_ZASOB`
@@ -829,20 +869,20 @@ echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:
 			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 (!array_key_exists($r->ZASOB_PARENT_ID, $foundTbls)) {
+						$foundTbls[$r->ZASOB_PARENT_ID] = new TableAcl($r->ZASOB_PARENT_ID);
+						$foundTbls[$r->ZASOB_PARENT_ID]->setDB($r->ID_BAZY_KONFIG);
+						$foundTbls[$r->ZASOB_PARENT_ID]->setName($r->PARENT_ZASOB_DESC);
+						$foundTbls[$r->ZASOB_PARENT_ID]->setLabel($r->PARENT_ZASOB_DESC_PL);
+						$foundTbls[$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 (!$foundTbls[$r->ZASOB_PARENT_ID]->hasField($r->ID_ZASOB)) {
+						$foundTbls[$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);
+						$foundTbls[$r->ZASOB_PARENT_ID]->setFieldPerms($r->ID_ZASOB, $r->FORM_TREAT);
 					}
 
 					if (!$procesID) {
@@ -851,6 +891,7 @@ echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:
 				}
 			}
 		}
+		}// fetch from DB
 
 		// build $foundMap
 		if (!$procesID) {
@@ -868,7 +909,7 @@ echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:
 		}
 
 		$this->_cache_save('foundUrls', $foundUrls);
-		$this->_cache_save('foundTables', $foundTables);
+		$this->_cache_save('foundTables', $foundTbls);
 		$this->_cache_save('permsByProcesID', $procesID);
 		$this->_cache_save('foundMap', $foundMap);
 	}

+ 1 - 1
SE/se-lib/UserStorageBase.php

@@ -63,7 +63,7 @@ class UserStorageBase {
 	 *    ['com.apple.access_chat'] = 'com.apple.access_chat';
 	 */
 	public function getUserGroups($usrLogin) {}
-	public function createGroup($group) {}
+	public function createGroup(ObjectGroup $group) {}
 	public function addUserGroup($usrLogin, $group) {}
 	public function removeUserGroup($usrLogin, $group) {}
 	public function updateGroup($group, $updateData) {}

+ 1 - 1
SE/se-lib/UserStorageDB.php

@@ -162,7 +162,7 @@ class UserStorageDB extends UserStorageBase {
 		return $groups;
 	}
 
-	public function getParentGroups(ObjectGroupDB $group) {
+	public function getParentGroups(ObjectGroup $group) {
 		return $this->fetchParentGroups($group->primaryKey);
 	}
 

+ 1 - 1
SE/se-lib/UserStorageMacOSX.php

@@ -80,7 +80,7 @@ class UserStorageMacOSX extends UserStorageBase {
 		return $group;
 	}
 
-	public function getParentGroups(ObjectGroupLdap $group) {
+	public function getParentGroups(ObjectGroup $group) {
 		Lib::loadClass('UsersLdapHelper');
 		$parentGroups = array();
 		$parentGroupsLdap = UsersLdapHelper::getParentGroupsByAppleUID($group->getLdapUID());

+ 0 - 1
SE/superedit-USER_ADD_GROUP.php

@@ -190,7 +190,6 @@ function USER_ADD_GROUP() {
 	//echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;">zasobObj (F.' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r($zasobObj);echo'</pre>';
 
 	$userAcl = User::getAcl();
-	$userAcl->fetchGroups();
 	//echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;display:none;">$userAcl (F.' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r($userAcl);echo'</pre>';
 
 	if (!$userAcl->hasTableAcl($zasobObj->ID)) {