Procházet zdrojové kódy

updated select in AclQueryBuilder, updated ViewObject

Piotr Labudda před 9 roky
rodič
revize
ba62b3cf55

+ 13 - 6
SE/se-lib/AclQueryBuilder.php

@@ -65,8 +65,11 @@ class AclQueryBuilder {
   public function select($propertyName) { // TODO: ogc:propertyName, *, xpath, @instances, etc...
     if (empty($propertyName)) return $this; // SKIP empty values, null's, etc.
     DBG::log($propertyName, 'array', "AclQueryBuilder->select");
-    if (is_array($propertyName) && !empty($propertyName['rawSelect'])) {
-      $this->select['__rawSelect__'] = $propertyName['rawSelect'];
+    if (is_array($propertyName)) {
+      foreach ($propertyName as $k => $v) {
+        if ('rawSelect' === $k) $this->select['__rawSelect__'] = $v;
+        else $this->select[] = $v;
+      }
       return $this;
     }
     if (!in_array($propertyName, $this->select)) $this->select[] = $propertyName; // TODO: split by property source
@@ -153,7 +156,8 @@ class AclQueryBuilder {
     if ('__rawSelect__' === $key) return $select;
     $sqlPk = 'ID';
     if ($this->from instanceof Core_AclBase) $sqlPk = $this->from->getSqlPrimaryKeyField();
-    if ('@instnces' === $select) {
+    if ('*' === $select) return '*';
+    if ('@instances' === $select) {
       if (!($this->from instanceof Core_AclBase)) throw new Exception("select @instances allowed only for Acl object");
       $instanceTable = ACL::getInstanceTable($this->from->getNamespace());
       return "
@@ -171,7 +175,11 @@ class AclQueryBuilder {
     } else {
       // TODO: only real table field
       // TODO: if geometry type then `AsWKT(t.`{$fieldName}`) as {$fieldName}`
-      return $this->parseSelectFieldValueToSql($select, $this->_fromPrefix);
+      try {
+        return $this->parseSelectFieldValueToSql($select, $this->_fromPrefix);
+      } catch (Exception $e) {
+        DBG::log($e);
+      }
     }
     return null;
   }
@@ -335,13 +343,12 @@ class AclQueryBuilder {
     // TODO: $this->_hasSelectRemoteFields = false;
     // TODO: $this->_hasQueryRemoteFields = false;
 
-    // TODO: select must contain primaryKey
     $sqlSelect = array_filter(
       array_map([$this, '_generateSelectMain'], $this->select, array_keys($this->select)),
       'is_string'
     );
     $sqlSelect = (!empty($sqlSelect))
-      ? implode("\n\t and ", $sqlSelect)
+      ? implode(",\n\t", $sqlSelect)
       : "{$this->_fromPrefix}.*"
     ;
 

+ 28 - 7
SE/se-lib/AclQueryFeatures.php

@@ -253,8 +253,11 @@ class AclQueryFeatures {
   public function getQuery() {
     if ($this->_query) return $this->_query;
     // $ds = $this->_acl->getDataSource(); // TODO: only for TableAcl // TODO: move _parseSqlWhere to this class
-    $filtrIsInstance = [];
+    $filtrIsInstance = []; // $filtrIsInstance = [ $this->_acl->getNamespace() ];
     $filtrIsNotInstance = [];
+    if (!empty($this->_params['f_is_instance'])) $filtrIsInstance = $this->_params['f_is_instance'];
+    if (!empty($this->_params['f_is_not_instance'])) $filtrIsNotInstance = $this->_params['f_is_not_instance'];
+
     $this->_query = ACL::query($this->_acl)
       ->isInstance($filtrIsInstance)
       ->isNotInstance($filtrIsNotInstance);
@@ -266,6 +269,10 @@ class AclQueryFeatures {
       if (is_int($k) && is_array($v)) {
         $this->_query->where($v); // TODO: check format [$fieldName, $comparisonSign, $value]
       } else if (is_int($k) && null === $v) { // skip NULL
+      } else if ('f_is_instance' === $k) { // parsed before
+      } else if ('f_is_not_instance' === $k) { // parsed before
+      } else if ('@instances' === $k) { // skip - select
+      } else if ('cols' === $k) { // skip - select
       } else if ('f_' === substr($k, 0, 2) && is_string($v) && strlen($k) > 3) {
         $fieldName = substr($k, 2);
         $fieldType = $this->_acl->getXsdFieldType($fieldName);
@@ -333,13 +340,27 @@ class AclQueryFeatures {
     $offset = V::get('limitstart', 0, $this->_params, 'int');
 
     DBG::log(['params' => $this->_params, 'sortBy' => $sortBy, 'limit' => $limit, 'offset' => $offset], 'array', '$this->_params');
+
+    // TODO: select from params: 'cols' => [ fieldName, ... ]
+    // TODO: select from params: '@instances' => 1
+    // TODO: if no fields set, then '*'
+    // TODO: select must contain primaryKey
+    $select = [];
+    $select = [
+      'rawSelect' => ($this->_acl instanceof TableAcl)
+        ? $this->_acl->getDataSource()->_getSqlCols()
+        : '*'
+    ];
+    if (!empty($this->_params['@instances'])) $select[] = '@instances';
+    if (!empty($this->_params['cols'])) {
+      foreach ($this->_params['cols'] as $fieldName) {
+        $select[] = $fieldName;
+      }
+    }
+    DBG::log($select, 'array', "\$select is(TableAcl)=(".($this->_acl instanceof TableAcl).")");
+
     return $this->getQuery()
-      ->select([
-        'rawSelect' => ($this->_acl instanceof TableAcl)
-          ? $this->_acl->getDataSource()->_getSqlCols()
-          : '*'
-      ])
-      ->select(!empty($this->_params['@instances']) ? '@instances' : null)
+      ->select($select)
       ->limit($limit)
       ->offset($offset)
       ->orderBy($sortBy)

+ 3 - 0
SE/se-lib/AntAclBase.php

@@ -79,6 +79,9 @@ class AntAclBase extends Core_AclBase {
   public function canReadObjectField($fieldName, $object) {
     return true; // TODO: return $this->getPerms($fieldName, $object)->canRead()
   }
+  public function canWriteObjectField($fieldName, $record) {
+    return false; // TODO: return $this->getPerms($fieldName, $object)->canWrite()
+  }
 
   public function getFields() {
     if (empty($this->_fields)) {

+ 13 - 5
SE/se-lib/Route/ViewObject.php

@@ -137,13 +137,16 @@ class Route_ViewObject extends Route_ViewTableAjax {
 						}
 					}
 				}
-				$items = $acl->getItems([
+				$queryFeatures = $acl->buildQuery([
 					// TODO: 'propertyName' => "*,@instance",
 					'f_is_instance' => $fIsInstance,
 					'f_is_not_instance' => $fIsNotInstance,
 					'@instances' => '1',
 					'limit' => 10
 				]);
+				// $total = $queryFeatures->getTotal();
+				$items = $queryFeatures->getItems();
+
 				$rootNamespace = $acl->getRootNamespace();
 				DBG::nicePrint($rootNamespace, '$rootNamespace');
 				$jsRenderFunName = 'render_dropdown_instances_' . substr(md5(time()), 0, 6);
@@ -741,9 +744,10 @@ class Route_ViewObject extends Route_ViewTableAjax {
 				$params[$k] = $v;
 			}
 		}
-		$total = $acl->getTotal($params);
+		$queryFeatures = $acl->buildQuery($params);
+		$total = $queryFeatures->getTotal();
 		// if ($total > $exportLimit) $params['limit'] = $exportLimit;
-		$items = $acl->getItems($params);
+		$items = $queryFeatures->getItems();
 
 		$format = V::get('format', 'html', $_GET);
 		if ('html' == $format) {
@@ -970,9 +974,13 @@ class Route_ViewObject extends Route_ViewTableAjax {
 			$jsonData->cols->{$col} = $columnConfig;
 		}
 		$jsonData->rows = array();
-		$jsonData->total = $acl->getTotal($params);
+		$queryFeatures = $acl->buildQuery($params);
+		$jsonData->total = $queryFeatures->getTotal();
 		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);
+		$listItems = $queryFeatures->getItems();
+		$primaryKeyField = $acl->getPrimaryKeyField();
+		$items = []; foreach ($listItems as $item) $items[ $item[$primaryKeyField] ] = $item;
+
 		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