Quellcode durchsuchen

updated Acl and TableAjax to view objects, fixed od viewtable_ajax

Piotr Labudda vor 9 Jahren
Ursprung
Commit
7e746be618

+ 16 - 1
SE/se-lib/Core/AclBase.php

@@ -33,6 +33,20 @@ class Core_AclBase {
     */
     throw new HttpException("Acl function " . __FUNCTION__ . " Not implemented", 501);
   }
+  public function getFieldLabel($fieldName) {
+    foreach ($this->getFields() as $field) {
+      if ($fieldName != $field['name']) continue;
+      return V::get('label', $fieldName, $field);
+    }
+    return $fieldName;
+	}
+  public function getFieldOpis($fieldName) {
+    foreach ($this->getFields() as $field) {
+      if ($fieldName != $field['name']) continue;
+      return V::get('opis', $fieldName, $field);
+    }
+    return $fieldName;
+	}
   public function getFieldListByIdZasob() { throw new HttpException("Acl function " . __FUNCTION__ . " Not implemented", 501); }// TODO: RMME - one field list function
   public function getRealFieldListByIdZasob() { throw new HttpException("Acl function " . __FUNCTION__ . " Not implemented", 501); }// TODO: RMME - one field list function
   public function getVirtualFieldListByIdZasob() { throw new HttpException("Acl function " . __FUNCTION__ . " Not implemented", 501); }// TODO: RMME - one field list function
@@ -63,7 +77,8 @@ class Core_AclBase {
 
   public function getRawLabel($posLimit = 20) { return substr($this->getName(), 0, $posLimit); }
 
-  public function getItems($params = array()) { throw new HttpException("Acl function " . __FUNCTION__ . " Not implemented", 501); }
+  public function getItems($params = array()) { throw new HttpException("Acl function " . __FUNCTION__ . " Not implemented", 501); }// TODO: use ParseOgcQuery
+  public function getTotal($params = array()) { throw new HttpException("Acl function " . __FUNCTION__ . " Not implemented", 501); }// TODO: use ParseOgcQuery
   public function addItem($todoItem) { throw new HttpException("Acl function " . __FUNCTION__ . " Not implemented", 501); }
   public function updateItem($itemPatch) { throw new HttpException("Acl function " . __FUNCTION__ . " Not implemented", 501); }
   public function getGeomFieldType($fieldName) { throw new HttpException("Acl function " . __FUNCTION__ . " Not implemented", 501); }

+ 174 - 0
SE/se-lib/ParseOgcQuery.php

@@ -0,0 +1,174 @@
+<?php
+
+Lib::loadClass('SqlQueryWhereBuilder');
+Lib::loadClass('Api_WfsException');
+
+/*
+<wfs:Query>
+	<ogc:PropertyName>id</ogc:PropertyName>
+	<ogc:PropertyName>name</ogc:PropertyName>
+	...
+	<ogc:Filter> ... <!-- maxOccurs="1" @see ParseOgcFilter -->
+	[ <wfs:handle> ... <!-- type="xsd:string" use="optional --> ]
+	<wfs:typeName> ... <!-- type="xsd:QName" use="required" -->
+	[ <wfs:featureVersion ... <!-- type="xsd:string" use="optional" --> ]
+</wfs:Query>
+ *
+ * @usage:
+		$parser = new ParseOgcFilter();
+		$parser->loadOgcFilter($ogcFilter);
+		$queryWhereBuilder = $parser->convertToSqlQueryWhereBuilder();
+		$query = $queryWhereBuilder->getQueryWhere('t');
+ *
+ */
+class ParseOgcQuery {
+
+	public $_ogcFilter = '';
+
+	public function __construct() {
+	}
+
+	public function loadOgcFilter($ogcFilter) {
+		// validate?
+		$this->_ogcFilter = $ogcFilter;
+	}
+
+	public function convertToSqlQueryWhereBuilder() {
+		$ogcFilterXmlString = '<?xml version="1.0" encoding="UTF-8"?>' . "\n";
+		$ogcFilterXmlString .= <<<OGC_FILTER_XML_FILE
+<filter xmlns="https://biuro.biall-net.pl/SE/version-git/schema/filter.xsd"
+        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+        xmlns:ogc="http://www.opengis.net/ogc">
+	{$this->_ogcFilter}
+</filter>
+OGC_FILTER_XML_FILE;
+		$convertedGuiXml = $this->_convertOgcFilterToCmdList($ogcFilterXmlString);
+
+		DBG::_('DBG_DS_OGC', '>1', "convertedGuiXml(".strlen($convertedGuiXml).")", $convertedGuiXml, __CLASS__, __FUNCTION__, __LINE__);
+
+		$tags = array();
+		$parserXml = xml_parser_create();
+		xml_parser_set_option($parserXml, XML_OPTION_CASE_FOLDING, 0);
+		xml_parser_set_option($parserXml, XML_OPTION_SKIP_WHITE, 1);
+		if (0 == xml_parse_into_struct($parserXml, $convertedGuiXml, $tags)) {
+			throw new Exception("Parse Request xml error #" . __LINE__ . ": parse converted transaction failed");
+		}
+		xml_parser_free($parserXml);
+		if (empty($tags)) {
+			throw new Exception("Parse Request xml error #" . __LINE__ . ": parse converted transaction returns empty structure");
+		}
+
+		$queryWhereBuilder = new SqlQueryWhereBuilder();
+		foreach ($tags as $tag) {
+			switch ($tag['tag']) {
+				case 'filter': {// root tag
+				}
+					break;
+				case 'sql_filter_comparisonFieldToValue': {
+					$fieldName = V::get('fieldName', '', $tag['attributes']);
+					$fieldFunction = V::get('fieldFunction', null, $tag['attributes']);
+					$comparisonSign = V::get('comparisonSign', '', $tag['attributes']);
+					$value = V::get('value', '', $tag['attributes']);
+					DBG::_('DBG_DS_OGC', '>3', "sql_filter_comparisonFieldToValue comparisonSign", $comparisonSign, __CLASS__, __FUNCTION__, __LINE__);
+					if ('like' == $comparisonSign) {
+						$wildCard = V::get('wildCard', '', $tag['attributes']);
+						$singleChar = V::get('singleChar', '', $tag['attributes']);
+						$escapeChar = V::get('escapeChar', '', $tag['attributes']);
+						// wildCard="*" singleChar="#" escapeChar="!" => sql: % _ \
+						// '*ORMA!*' => '%ORMA\*'
+						// TODO: first replace every escapeChar
+						$valLength = strlen($value);
+						$valCharsAllowReplace = array(); for ($i = 0; $i < $valLength; $i++) $valCharsAllowReplace[] = true;
+						{// escapeChar
+							$lastOffset = 0;
+							while (false !== ($pos = strpos($value, $escapeChar, $lastOffset))) {
+								DBG::_('DBG_DS_OGC', '>3', "sql_filter_comparisonFieldToValue like value({$value}) escapeChar({$escapeChar}) pos({$pos}) lastOffset({$lastOffset})", null, __CLASS__, __FUNCTION__, __LINE__);
+								$value[$pos] = '\\';
+								$valCharsAllowReplace[$pos] = false;
+								if ($pos + 1 < $valLength) $valCharsAllowReplace[$pos + 1] = false;
+								$lastOffset = $pos + 1;
+							}
+						}
+						{// singleChar
+							$lastOffset = 0;
+							while (false !== ($pos = strpos($value, $singleChar, $lastOffset))) {
+								DBG::_('DBG_DS_OGC', '>3', "sql_filter_comparisonFieldToValue like value({$value}) singleChar({$singleChar}) pos({$pos}) lastOffset({$lastOffset})", null, __CLASS__, __FUNCTION__, __LINE__);
+								if ($valCharsAllowReplace[$pos]) {
+									$value[$pos] = '_';
+									$valCharsAllowReplace[$pos] = false;
+								}
+								$lastOffset = $pos + 1;
+							}
+						}
+						{// wildCard
+							$lastOffset = 0;
+							while (false !== ($pos = strpos($value, $wildCard, $lastOffset))) {
+								DBG::_('DBG_DS_OGC', '>3', "sql_filter_comparisonFieldToValue like value({$value}) wildCard({$wildCard}) pos({$pos}) lastOffset({$lastOffset})", null, __CLASS__, __FUNCTION__, __LINE__);
+								if ($valCharsAllowReplace[$pos]) {
+									$value[$pos] = '%';
+									$valCharsAllowReplace[$pos] = false;
+								}
+								$lastOffset = $pos + 1;
+							}
+						}
+					}
+					DBG::_('DBG_DS_OGC', '>3', "sql_filter_comparisonFieldToValue value({$value})", null, __CLASS__, __FUNCTION__, __LINE__);
+					if ($fieldFunction) {
+						$queryWhereBuilder->addComparisonFieldFunToValue($fieldFunction, $fieldName, $comparisonSign, $value);
+					} else {
+						$queryWhereBuilder->addComparisonFieldToValue($fieldName, $comparisonSign, $value);
+					}
+				}
+					break;
+				case 'sql_filter_comparisonFieldIsNull': {
+					$fieldName = V::get('fieldName', '', $tag['attributes']);
+					$queryWhereBuilder->sql_filter_comparisonFieldIsNull($fieldName);
+				}
+					break;
+				case 'sql_filter_openBlock': {
+					$blockType = V::get('type', '', $tag['attributes']);
+					DBG::_('DBG_DS_OGC', '>2', "sql_filter_openBlock block Type {$blockType} attrs", json_encode($tag), __CLASS__, __FUNCTION__, __LINE__);
+					$queryWhereBuilder->openBlock($blockType);
+				}
+					break;
+				case 'sql_filter_closeBlock': {
+					$blockType = V::get('type', '', $tag['attributes']);
+					$queryWhereBuilder->closeBlock($blockType);
+				}
+					break;
+				case 'not_implemented_tag': {
+					$tagName = V::get('name', '', $tag['attributes']);
+					DBG::_('DBG_DS_OGC', '>1', "Not Implemented tag '{$tagName}'", $queryWhereBuilder, __CLASS__, __FUNCTION__, __LINE__);
+					throw new Api_WfsException("Not Implemented tag '{$tagName}'", 501, null, 'NotImplementedOgcTag', 'request');
+				}
+					break;
+				default: {
+					DBG::_('DBG_DS_OGC', '>1', "TODO: tag {$tag['tag']}", $queryWhereBuilder, __CLASS__, __FUNCTION__, __LINE__);
+					throw new HttpException("TODO: tag {$tag['tag']}", 501);
+				}
+			}
+		}
+
+		$queryWhereBuilder->parseQueryWhere();
+		DBG::_('DBG_DS_OGC', '>1', "queryWhereBuilder", $queryWhereBuilder, __CLASS__, __FUNCTION__, __LINE__);
+		return $queryWhereBuilder;
+	}
+
+	public function _convertOgcFilterToCmdList($ogcFilterXmlString) {
+		$convertOgcFilterXslString = @file_get_contents(APP_PATH_SCHEMA . DS . 'wfs' . DS . 'convertOgcFilterToXmlTaskList.xsl');
+		if (false === $convertOgcFilterXslString) throw new HttpException("Cannot find file 'convertOgcFilter...'", 404);
+		if (empty($convertOgcFilterXslString)) throw new HttpException("Empty file 'convertOgcFilter...'", 404);
+
+		$requestXml = new DOMDocument();
+		$isFileCorrect = @$requestXml->loadXml($ogcFilterXmlString);
+		if (false === $isFileCorrect) throw new HttpException("Parse error for ogc filter", 400);
+		$convertOgcFilterXsl = new DOMDocument();
+		$isFileCorrect = @$convertOgcFilterXsl->loadXml($convertOgcFilterXslString);
+		if (false === $isFileCorrect) throw new HttpException("Parse error for file 'convertOgcFilter...'", 500);
+		$proc = new XSLTProcessor();
+		$isImported = $proc->importStylesheet($convertOgcFilterXsl);
+		if (false === $isImported) throw new HttpException("XSLT Parse error for import 'convertOgcFilter...'", 500);
+		return $proc->transformToXML($requestXml);
+	}
+
+}

+ 1 - 0
SE/se-lib/Schema/AccessGroupStorageAcl.php

@@ -14,6 +14,7 @@ class Schema_AccessGroupStorageAcl extends Core_AclBase {// Read only class
   public function getName() { return 'AccessGroup'; }
   public function getRootTableName() { return 'CRM_LISTA_ZASOBOW'; }
   public function getFieldListByIdZasob() { return $this->getRealFieldListByIdZasob(); }
+  public function getVisibleFieldListByIdZasob() { return $this->getRealFieldListByIdZasob(); }
   public function getVirtualFieldListByIdZasob() { return array(); }
   public function getRealFieldListByIdZasob($force = false) {
     $cols[100000] = 'id';// CRM_LISTA_ZASOBOW.ID

+ 1 - 0
SE/se-lib/Schema/AccessOwnerStorageAcl.php

@@ -12,6 +12,7 @@ class Schema_AccessOwnerStorageAcl extends Core_AclBase {
   public function getName() { return 'AccessOwner'; }
   public function getRootTableName() { return 'ADMIN_USERS'; }// TODO: turn off - use getName for generating ref's
   public function getFieldListByIdZasob() { return $this->getRealFieldListByIdZasob(); }
+  public function getVisibleFieldListByIdZasob() { return $this->getRealFieldListByIdZasob(); }
   public function getVirtualFieldListByIdZasob() { return array(); }
   public function getRealFieldListByIdZasob($force = false) {
     $cols[100000] = 'id';// ADMIN_USERS.ID

+ 55 - 4
SE/se-lib/Schema/FileStorageAcl.php

@@ -13,6 +13,7 @@ class Schema_FileStorageAcl extends Core_AclBase {
   public function getName() { return 'File'; }
   public function getRootTableName() { return 'CRM_FILES'; }
   public function getFieldListByIdZasob() { return $this->getRealFieldListByIdZasob(); }
+  public function getVisibleFieldListByIdZasob() { return $this->getRealFieldListByIdZasob(); }
   public function getVirtualFieldListByIdZasob() { return array(); }
   public function getRealFieldListByIdZasob() {
     $cols = array();// FileStorage::getFileById()
@@ -27,6 +28,15 @@ class Schema_FileStorageAcl extends Core_AclBase {
     // $cols[] = 'exists';
     return $cols;
   }
+  public function getFields() {// @returns array - $this->_fields
+    $fields[1] = ['name'=>'id', 'perms'=>'R', 'opis'=>'', 'label'=>'', 'sort_prio'=>999];
+    $fields[2] = ['name'=>'name', 'perms'=>'R', 'opis'=>'', 'label'=>'', 'sort_prio'=>999];
+    $fields[3] = ['name'=>'size', 'perms'=>'R', 'opis'=>'', 'label'=>'', 'sort_prio'=>999];
+    $fields[4] = ['name'=>'mimeType', 'perms'=>'R', 'opis'=>'', 'label'=>'', 'sort_prio'=>999];
+    $fields[5] = ['name'=>'version', 'perms'=>'R', 'opis'=>'', 'label'=>'', 'sort_prio'=>999];
+    $fields[6] = ['name'=>'content', 'perms'=>'R', 'opis'=>'', 'label'=>'', 'sort_prio'=>999];
+    return $fields;
+  }
   public function getFieldIdByName($fieldName) {
     $fields = $this->getRealFieldListByIdZasob();
 		if (empty($fieldName)) return null;
@@ -50,9 +60,10 @@ class Schema_FileStorageAcl extends Core_AclBase {
     return false;
   }
 	public function isEnumerationField($fieldName) { return false; }
-  public function getFieldType($colName) {
-    switch ($colName) {
-      case 'id': return array(); break;
+  public function getFieldType($fieldName) {
+    switch ($fieldName) {
+      case 'id': return ['name'=>'id', 'type'=>'int']; break;
+      case 'name': return ['name'=>'name', 'type'=>'string']; break;
     }
     return null;
 	}
@@ -90,7 +101,47 @@ class Schema_FileStorageAcl extends Core_AclBase {
     return $this->canWriteField($fieldName);
   }
 
-  public function getItems($params = array()) {
+  public function getTotal($params = array()) {// TODO: use ParseOgcQuery
+    $sqlLimit = V::get('limit', 10000, $params);
+    $sqlOffset = V::get('limitstart', 0, $params);
+    // TODO: parse params:
+    //   [sortBy] => ID D,test_date A
+    //   [cols] => Array( [0] => ID
+    //                    [1] => test_date
+    //                    [2] => A_STATUS )
+    //   [ogc:Filter] => "<ogc:Filter><ogc:PropertyIsEqualTo><ogc:PropertyName>id</ogc:PropertyName><ogc:Literal>35</ogc:Literal></ogc:Filter>"
+    $sqlWhereAddOgcFilter = '';
+    $ogcFilter = V::get('ogc:Filter', '', $params);
+    if (!empty($ogcFilter)) {
+      Lib::loadClass('ParseOgcFilter');
+      $parser = new ParseOgcFilter();
+      $parser->loadOgcFilter($ogcFilter);
+      $queryWhereBuilder = $parser->convertToSqlQueryWhereBuilder();
+      $usedFields = $queryWhereBuilder->getUsedFields();
+      foreach ($usedFields as $fieldName) {
+        if (!$this->getFieldIdByName($fieldName)) throw new Exception("Not allowed PropertyName '{$fieldName}'");
+      }
+      $sqlWhereAddOgcFilter = $queryWhereBuilder->getQueryWhere('t');
+      if (!empty($sqlWhereAddOgcFilter)) $sqlWhereAddOgcFilter = " and {$sqlWhereAddOgcFilter}";
+      DBG::_('DBG_DS', '>1', "ogc:Filter parser", $parser, __CLASS__, __FUNCTION__, __LINE__);
+      DBG::_('DBG_DS', '>1', "ogc:Filter queryWhereBuilder", $queryWhereBuilder, __CLASS__, __FUNCTION__, __LINE__);
+      DBG::_('DBG_DS', '>1', "ogc:Filter usedFields", $usedFields, __CLASS__, __FUNCTION__, __LINE__);
+      DBG::_('DBG_DS', '>1', "ogc:Filter sqlWhereAddOgcFilter", $sqlWhereAddOgcFilter, __CLASS__, __FUNCTION__, __LINE__);
+    }
+    $sqlTblName = FileStorage::getTableName();
+    $sqlUserLogin = User::getLogin();
+    $sqlWhere = "1=1";
+    // $sqlWhere .= " and t.`A_RECORD_CREATE_AUTHOR` = '{$sqlUserLogin}' ";// TODO: Acl to read file
+    $sqlWhere .= $sqlWhereAddOgcFilter;
+    if ($pk = V::get('primaryKey', 0, $params, 'int')) $sqlWhere .= " and t.`ID` = {$pk} ";
+    return DB::getPDO()->fetchValue("
+    	select count(1) as total
+    	from `{$sqlTblName}` t
+      where {$sqlWhere}
+    ");
+  }
+
+  public function getItems($params = array()) {// TODO: use ParseOgcQuery
     $sqlLimit = V::get('limit', 10000, $params);
     $sqlOffset = V::get('limitstart', 0, $params);
     // TODO: parse params:

+ 1 - 0
SE/se-lib/Schema/KorespondencjaStorageAcl.php

@@ -16,6 +16,7 @@ class Schema_KorespondencjaStorageAcl extends Core_AclBase {
   public function getName() { return 'Korespondencja'; }
   public function getRootTableName() { return 'IN7_DZIENNIK_KORESP'; }
   public function getFieldListByIdZasob() { return $this->getRealFieldListByIdZasob(); }
+  public function getVisibleFieldListByIdZasob() { return $this->getRealFieldListByIdZasob(); }
   public function getVirtualFieldListByIdZasob() { return array(); }
   public function getRealFieldListByIdZasob($force = false) {
     $cols = $this->parentAcl->getRealFieldListByIdZasob();

+ 11 - 2
SE/se-lib/Schema/TestPermsStorageAcl.php

@@ -16,6 +16,7 @@ class Schema_TestPermsStorageAcl extends Core_AclBase {
   public function getName() { return 'TestPerms'; }
   public function getRootTableName() { return 'TEST_PREMS'; }
   public function getFieldListByIdZasob() { return $this->getRealFieldListByIdZasob(); }
+  public function getVisibleFieldListByIdZasob() { return $this->getRealFieldListByIdZasob(); }
   public function getVirtualFieldListByIdZasob() { return array(); }
   public function getRealFieldListByIdZasob($force = false) {
     $cols = $this->parentAcl->getRealFieldListByIdZasob();
@@ -37,7 +38,10 @@ class Schema_TestPermsStorageAcl extends Core_AclBase {
     $fields[100004] = ['name'=>'AccessOwner', 'perms'=>'RWXC', 'opis'=>'Osoba odpowiedzialna', 'sort_prio'=>999, 'label'=>'Osoba odp.'];
     return $fields;
   }
-  public function getFieldType($colName) {
+  public function getFieldType($fieldName) {
+    foreach ($this->getFields() as $field) {
+      if ($fieldName == $field['name']) return $field;
+    }
     return null;
 	}
 
@@ -78,7 +82,12 @@ class Schema_TestPermsStorageAcl extends Core_AclBase {
     return $this->parentAcl->canWriteObjectField($fieldName, $record);
   }
 
-  public function getItems($params = array()) {
+  public function getTotal($params = array()) {// TODO: use ParseOgcQuery
+    $DBG = V::get('DBG_DS', 0, $_GET, 'int');
+    if($DBG>2){echo 'C.'.get_class($this).' L.' . __LINE__ . " getTotal \$params:";print_r($params);echo "\n";}
+    return $this->parentAcl->getTotal($params);
+  }
+  public function getItems($params = array()) {// TODO: use ParseOgcQuery
     $DBG = V::get('DBG_DS', 0, $_GET, 'int');
     if($DBG>2){echo 'C.'.get_class($this).' L.' . __LINE__ . " getItems \$params:";print_r($params);echo "\n";}
     $items = array();

+ 14 - 12
SE/se-lib/TableAcl.php

@@ -226,11 +226,11 @@ class TableAcl extends Core_AclBase {
 	 *
 	 */
 	public function canWriteRecord($record) {
-
+		$record = (array)$record;
 		$dbgArr = array();
-		$dbgArr['record_owner'] = (isset($record->L_APPOITMENT_USER))? $record->L_APPOITMENT_USER : '';
-		$dbgArr['record_write'] = (isset($record->A_ADM_COMPANY))? $record->A_ADM_COMPANY : '';
-		$dbgArr['record_read'] = (isset($record->A_CLASSIFIED))? $record->A_CLASSIFIED : '';
+		$dbgArr['record_owner'] = (isset($record['L_APPOITMENT_USER']))? $record['L_APPOITMENT_USER'] : '';
+		$dbgArr['record_write'] = (isset($record['A_ADM_COMPANY']))? $record['A_ADM_COMPANY'] : '';
+		$dbgArr['record_read'] = (isset($record['A_CLASSIFIED']))? $record['A_CLASSIFIED'] : '';
 		$dbgArr['user_groups'] = User::getLdapGroupsNames();
 		if(V::get('DBG_ACL', '', $_REQUEST) > 2){echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;">dbgArr (' . __CLASS__ . '::' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r($dbgArr);echo'</pre>';}
 
@@ -253,12 +253,13 @@ class TableAcl extends Core_AclBase {
 	}
 
 	public function canReadRecord($record) {
+		$record = (array)$record;
 		$dbgArr = array();
-		$dbgArr['record_owner'] = (isset($record->L_APPOITMENT_USER))? $record->L_APPOITMENT_USER : '';
-		$dbgArr['record_write'] = (isset($record->A_ADM_COMPANY))? $record->A_ADM_COMPANY : '';
-		$dbgArr['record_read'] = (isset($record->A_CLASSIFIED))? $record->A_CLASSIFIED : '';
+		$dbgArr['record_owner'] = (isset($record['L_APPOITMENT_USER']))? $record['L_APPOITMENT_USER'] : '';
+		$dbgArr['record_write'] = (isset($record['A_ADM_COMPANY']))? $record['A_ADM_COMPANY'] : '';
+		$dbgArr['record_read'] = (isset($record['A_CLASSIFIED']))? $record['A_CLASSIFIED'] : '';
 		$dbgArr['user_groups'] = User::getLdapGroupsNames();
-		if(V::get('DBG_ACL', '', $_REQUEST) > 2){echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;">record('.$record->ID.') (' . __CLASS__ . '::' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r($dbgArr);echo'</pre>';}
+		if(V::get('DBG_ACL', '', $_REQUEST) > 2){echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;">record('.$record['ID'].') (' . __CLASS__ . '::' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r($dbgArr);echo'</pre>';}
 
 		if ($dbgArr['record_owner'] && $dbgArr['record_owner'] == User::getLogin()) {
 			if(V::get('DBG_ACL', '', $_REQUEST) > 2){echo '<p>true - is record owner</p>';}
@@ -1007,7 +1008,7 @@ class TableAcl extends Core_AclBase {
 			$this->_types = array();// clear _types @see $this->isInitialized
 			$userAcl = User::getAcl();
 			$fieldsConfig = $userAcl->getPermsForTable($this->_zasobID);
-			DBG::_('DBG_SCH', '1', "INIT::\$fieldsConfig({$this->_zasobID}) fields(".count($this->_fields).")", $fieldsConfig, __CLASS__, __FUNCTION__, __LINE__ );
+			DBG::_('DBG_SCH', '>1', "INIT::\$fieldsConfig({$this->_zasobID}) fields(".count($this->_fields).")", $fieldsConfig, __CLASS__, __FUNCTION__, __LINE__ );
 			$this->initFieldsFromConfig($fieldsConfig);
 			//DBG::_('DBG_SCH', '1', "INIT::\$fieldsConfig({$this->_zasobID}) fields(".count($this->_fields).")", $this, __CLASS__, __FUNCTION__, __LINE__ );
 		}
@@ -1213,7 +1214,8 @@ class TableAcl extends Core_AclBase {
 		return false;
 	}
 
-	public function getVisibleFieldList() {
+	public function getVisibleFieldList() { return $this->getVisibleFieldListByIdZasob(); }
+	public function getVisibleFieldListByIdZasob() {
 		$cols = array();
 		$id = 0;
 		foreach ($this->_fields as $kFieldID => $vField) {
@@ -1411,12 +1413,12 @@ class TableAcl extends Core_AclBase {
 		return $ds->getItem($id);
 	}
 
-	public function getItems($params = array()) {
+	public function getItems($params = array()) {// TODO: use ParseOgcQuery
 		$ds = $this->getDataSource();
 		return $ds->getItems($params);
 	}
 
-	public function getTotal($params) {
+	public function getTotal($params = array()) {// TODO: use ParseOgcQuery
 		$ds = $this->getDataSource();
 		return $ds->getTotal($params);
 	}

+ 18 - 21
SE/se-lib/TableAjax.php

@@ -1826,7 +1826,7 @@ var p5UI_TableAjax_generateFunctionNode = function(funObj, rowPK, props) {
 					currentNode = $(_uiNodeCont).next('.foot').find('.' + nodeClass),
 					node;
 			if (priv.options.debug) console.log('Render: ', nodeClass);
-			if (priv.options.exportFields.length) {
+			if (priv.options.exportFields && priv.options.exportFields.length) {
 				node = $('<div class="btn-group dropup pagesize ' + nodeClass + '"></div>');
 				var btn = $('<button class="btn btn-sm dropdown-toggle" data-toggle="dropdown" href="#">Export&nbsp;</button>').appendTo(node);
 				var span = $('<span class="caret"></span>').appendTo(btn);
@@ -5085,7 +5085,7 @@ jQuery(document).ready(function(){
 		$connTbls = array();
 		return $connTbls;// TODO: OFF - hardlinki tworzone w bash_sync_perms.php
 
-		$fields = $this->_acl->getVisibleFieldList();
+		$fields = $this->_acl->getVirtualFieldListByIdZasob();
 		if (!empty($fields)) {
 			foreach ($fields as $vColID => $vCol) {
 				$typeSpecial = Typespecial::getInstance($vColID);
@@ -5106,7 +5106,7 @@ jQuery(document).ready(function(){
 	private function getConnectedTblTypespecials($connTblID) {
 		$connTblTypespecials = array();
 
-		$fields = $this->_acl->getVisibleFieldList();
+		$fields = $this->_acl->getVirtualFieldListByIdZasob();
 		if (!empty($fields)) {
 			foreach ($fields as $vColID => $vCol) {
 				$typeSpecial = Typespecial::getInstance($vColID);
@@ -5798,7 +5798,7 @@ jQuery(document).ready(function(){
 			if($DBG){echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;">vCols (' . __CLASS__ . '::' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r($vCols);echo'</pre>';}
 		}
 
-		$visibleCols = $acl->getVisibleFieldList();
+		$visibleCols = $acl->getVisibleFieldListByIdZasob();
 		if($DBG){echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;">visibleCols (F.' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r($visibleCols);echo'</pre>';}
 
 		$jsonData = new stdClass();
@@ -5821,7 +5821,7 @@ jQuery(document).ready(function(){
 			else if ($acl->isGeomField($col)) {
 				$columnConfig->type = 'geom';
 			}
-			if ('' !== ($label = $this->_acl->getFieldLabel($col))) {
+			if ('' !== ($label = $acl->getFieldLabel($col))) {
 				$columnConfig->friendly = $label;
 			}
 			$colType = $acl->getFieldType($col);
@@ -5873,7 +5873,7 @@ jQuery(document).ready(function(){
 			}
 
 			// @see ajaxHiddenColsSave
-			if (UserProfile::isHiddenColumn($this->_zasobID, $fieldID)) {
+			if (UserProfile::isHiddenColumn($acl->getID(), $fieldID)) {
 				$columnConfig->hidden = true;
 			}
 
@@ -5885,14 +5885,13 @@ jQuery(document).ready(function(){
 		$jsonData->total = $acl->getTotal($params);
 		if($DBG){echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;">get_total (F.' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r($jsonData->total);echo'</pre>';}
 		$items = $acl->getItems($params);
+		foreach ($items as $idx => $item) $items[$idx] = (array)$item;
 		if($DBG){echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;">items (F.' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r($items);echo'</pre>';}
 		// TODO: add virtual data by Typespecial
 		if (!empty($vCols) && !empty($items)) {
 			foreach ($vCols as $vColID => $vCol) {
 				$colType = $acl->getFieldTypeById($vColID);
-				if ($colType) {
-					continue;// pomin Typespecial dla realnych komorek w bazie danych
-				}
+				if ($colType) continue;// pomin Typespecial dla realnych komorek w bazie danych
 
 				$typeSpecial = Typespecial::getInstance($vColID, $vCol);
 				if ($typeSpecial) {
@@ -5907,31 +5906,29 @@ jQuery(document).ready(function(){
 						if (!empty($specialValues)) foreach ($specialValues as $kItemID => $vValues) {
 							$tsValue = implode('<br>', $vValues);
 							if($DBG){echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;">Item['.$kItemID.'].'.$vCol.' specialValues (' . __CLASS__ . '::' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r($items[$kItemID]);echo'</pre>';}
-							if (!empty($items[$kItemID]->{$vCol}) && !empty($tsValue)) {
-								$items[$kItemID]->{$vCol} .= ": {$tsValue}";
+							if (!empty($items[$kItemID][$vCol]) && !empty($tsValue)) {
+								$items[$kItemID][$vCol] .= ": {$tsValue}";
 							} else {
-								$items[$kItemID]->{$vCol} = $tsValue;
+								$items[$kItemID][$vCol] = $tsValue;
 							}
 						}
 					}
 				}
 			}
 		}
-		foreach ($items as $vItem) {
+		foreach ($items as $item) {
 			// TODO: hide items without 'R'
-			foreach ($visibleCols as $kID => $vCol) {
+			foreach ($visibleCols as $fieldName) {
 				// TODO: ID default 'R'
-				if (!$acl->isAllowed($kID, 'R', $vItem)) {
-					$vItem->{$vCol} = '*****';
-				}
+				if (!$acl->canReadObjectField($fieldName, $item)) $item[$fieldName] = '*****';
 
 				// null => empty string
-				if (!isset($vItem->{$vCol}) || (!$vItem->{$vCol} && $vItem->{$vCol} !== '0')) {
-					if($DBG){echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;">isEmptyString['.$vCol.'] (F.' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r($vItem->{$vCol});echo'</pre>';}
-					$vItem->{$vCol} = '';
+				if (!isset($item[$fieldName]) || (!$item[$fieldName] && $item[$fieldName] !== '0')) {
+					if($DBG){echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;">isEmptyString['.$fieldName.'] (F.' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r($item[$fieldName]);echo'</pre>';}
+					$item[$fieldName] = '';
 				}
 			}
-			$jsonData->rows[] = $vItem;
+			$jsonData->rows[] = $item;
 		}
 		return $jsonData;
 	}

+ 7 - 4
SE/superedit-VIEWTABLE_AJAX.php

@@ -1,6 +1,7 @@
 <?php
 
 Lib::loadClass('ProcesHelper');
+Lib::loadClass('Request');
 
 function VIEWTABLE_AJAX($params = array()) {
 	try {
@@ -19,11 +20,11 @@ function VIEWTABLE_AJAX($params = array()) {
 
 		if (!$userAcl->hasTableAcl($zasobObj->ID)) throw new Exception("Brak uprawnień do tabeli ID={$zasobObj->ID}");
 
-		$tblAcl = $userAcl->getTableAcl($zasobObj->ID);
-		//echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;">tblAcl (F.' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r($tblAcl);echo'</pre>';
+		$acl = $userAcl->getTableAcl($zasobObj->ID);
+		//echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;">tblAcl (F.' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r($acl);echo'</pre>';
 
 		$forceTblAclInit = ('1' == V::get('_force', '', $_GET));
-		$tblAcl->init($forceTblAclInit);
+		$acl->init($forceTblAclInit);
 
 		Lib::loadClass('TableAjax');
 
@@ -44,7 +45,9 @@ function VIEWTABLE_AJAX($params = array()) {
 			}
 		}
 
-		$tbl = new TableAjax($tblAcl);
+		$tbl = new TableAjax($acl);
+		$syncUrl = Request::getPathUri() . 'index.php?_route=ViewTableAjax&namespace=' . $acl->getNamespace();
+		$tbl->setSyncUrl($syncUrl);
 		$tblLabel = array();
 		if (!empty($zasobObj->DESC_PL)) $tblLabel []= $zasobObj->DESC_PL;
 		if (!empty($zasobObj->OPIS))    $tblLabel []= $zasobObj->OPIS;