Prechádzať zdrojové kódy

added filter f_@selected: 'YES' | 'NO'

Piotr Labudda 8 rokov pred
rodič
commit
6b86b1cae2

+ 30 - 16
SE/se-lib/AclQueryBuilder.php

@@ -27,6 +27,7 @@ class AclQueryBuilder {
 	public $_fromPrefix;
 	public $_joinPrefix;
 	public $_joinParams;
+	public $_joinType;
 	public $isInstances;
 	public $isNotInstances;
 	public $_hasSelectRemoteFields;
@@ -43,6 +44,7 @@ class AclQueryBuilder {
 		$this->_fromPrefix = 't'; // prefix for this->from - default 't'
 		$this->_joinPrefix = []; // prefix => from (Acl | tableName)
 		$this->_joinParams = []; // prefx => params
+		$this->_joinType = []; // prefix => ( 'join' | 'left join' )
 		$this->isInstances = [];
 		$this->isNotInstances = [];
 
@@ -99,28 +101,31 @@ class AclQueryBuilder {
 	}
 	public function _generateWhereMain($where) { // @returns string
 		if (is_string($where)) return $where; // whereRaw
-		list($fieldName, $comparisonSign, $value) = $where;
+		list($prefixedFieldName, $comparisonSign, $value) = $where;
 		// $sqlFieldName = $fieldName; // TODO: getSqlFieldName // TODO: get sql field name with table prefix from join list to replace "{$this->_fromPrefix}.{$sqlFieldName}" below
+		$prefixedFieldName = (false === strpos($prefixedFieldName, '.')) ? "{$this->_fromPrefix}.{$prefixedFieldName}" : $prefixedFieldName;
+		list($prefix, $fieldName) = explode('.', $prefixedFieldName);
+		$sqlPrefix = $this->getPDO()->identifierQuote($prefix);
 		$sqlFieldName = $this->getPDO()->identifierQuote($fieldName);
 		switch ($comparisonSign) {
-			case 'is not null': return "{$this->_fromPrefix}.{$sqlFieldName} is not null";
-			case 'is null': return "{$this->_fromPrefix}.{$sqlFieldName} is null";
-			case 'Intersects': return "Intersects(GeomFromText('{$value}'), {$this->_fromPrefix}.{$sqlFieldName})=1";
-			case 'GeometryType': return "GeometryType({$this->_fromPrefix}.{$sqlFieldName})='{$value}'";
+			case 'is not null': return "{$sqlPrefix}.{$sqlFieldName} is not null";
+			case 'is null': return "{$sqlPrefix}.{$sqlFieldName} is null";
+			case 'Intersects': return "Intersects(GeomFromText('{$value}'), {$sqlPrefix}.{$sqlFieldName})=1";
+			case 'GeometryType': return "GeometryType({$sqlPrefix}.{$sqlFieldName})='{$value}'";
 			case 'or': return $this->_generateWhereBlock($where);
 			case 'and': return $this->_generateWhereBlock($where);
 			case 'UNIX_TIMESTAMP_LESS_THAN_NOW': return "
-				COALESCE(UNIX_TIMESTAMP({$this->_fromPrefix}.{$sqlFieldName}), 0) < UNIX_TIMESTAMP()
-				and {$this->_fromPrefix}.{$sqlFieldName} != ''
-				and {$this->_fromPrefix}.{$sqlFieldName} != '0000-00-00 00:00:00'
+				COALESCE(UNIX_TIMESTAMP({$sqlPrefix}.{$sqlFieldName}), 0) < UNIX_TIMESTAMP()
+				and {$sqlPrefix}.{$sqlFieldName} != ''
+				and {$sqlPrefix}.{$sqlFieldName} != '0000-00-00 00:00:00'
 			";
 			case 'UNIX_TIMESTAMP_NOW_3600': return "
-				COALESCE(UNIX_TIMESTAMP({$this->_fromPrefix}.{$sqlFieldName}), 0) < UNIX_TIMESTAMP()+3600
-				and COALESCE(UNIX_TIMESTAMP({$this->_fromPrefix}.{$sqlFieldName}), 0) > UNIX_TIMESTAMP()-3600
+				COALESCE(UNIX_TIMESTAMP({$sqlPrefix}.{$sqlFieldName}), 0) < UNIX_TIMESTAMP()+3600
+				and COALESCE(UNIX_TIMESTAMP({$sqlPrefix}.{$sqlFieldName}), 0) > UNIX_TIMESTAMP()-3600
 			";
-			case 'UNIX_TIMESTAMP_GREATER_THAN': return " COALESCE(UNIX_TIMESTAMP({$this->_fromPrefix}.{$sqlFieldName}), 0) > '{$value}' ";
-			case 'UNIX_TIMESTAMP_LESS_THAN':		return " COALESCE(UNIX_TIMESTAMP({$this->_fromPrefix}.{$sqlFieldName}), 0) < '{$value}' ";
-			default: return "{$this->_fromPrefix}.{$sqlFieldName} {$comparisonSign} " . $this->getPDO()->quote($value);
+			case 'UNIX_TIMESTAMP_GREATER_THAN': return " COALESCE(UNIX_TIMESTAMP({$sqlPrefix}.{$sqlFieldName}), 0) > '{$value}' ";
+			case 'UNIX_TIMESTAMP_LESS_THAN':		return " COALESCE(UNIX_TIMESTAMP({$sqlPrefix}.{$sqlFieldName}), 0) < '{$value}' ";
+			default: return "{$sqlPrefix}.{$sqlFieldName} {$comparisonSign} " . $this->getPDO()->quote($value);
 		}
 		return null;
 	}
@@ -191,10 +196,19 @@ class AclQueryBuilder {
 		return null;
 	}
 
-	public function join($join, $prefix, $params) {
+	public function join($remoteTableName, $prefix, $params) {
+		if (array_key_exists($prefix, $this->_joinPrefix)) throw new Exception("Prefix already used!");
+		$this->_joinPrefix[$prefix] = $remoteTableName;
+		$this->_joinParams[$prefix] = $params;
+		$this->_joinType[$prefix] = 'join';
+		return $this;
+	}
+
+	public function leftJoin($remoteTableName, $prefix, $params) {
 		if (array_key_exists($prefix, $this->_joinPrefix)) throw new Exception("Prefix already used!");
-		$this->_joinPrefix[$prefix] = $join;
+		$this->_joinPrefix[$prefix] = $remoteTableName;
 		$this->_joinParams[$prefix] = $params;
+		$this->_joinType[$prefix] = 'left join';
 		return $this;
 	}
 
@@ -336,7 +350,7 @@ class AclQueryBuilder {
 
 		foreach ($this->_joinPrefix as $prefix => $join) {
 			$joinName = $this->_getTableName($join);
-			$sqlJoin[] = " join `{$joinName}` {$prefix} on(" . $this->_parseJoinParams($this->_joinParams[$prefix]) . ") ";
+			$sqlJoin[] = " {$this->_joinType[$prefix]} `{$joinName}` {$prefix} on(" . $this->_parseJoinParams($this->_joinParams[$prefix]) . ") ";
 		}
 
 		$sqlJoin = (!empty($sqlJoin)) ? implode("\n\t", $sqlJoin) : "";

+ 12 - 0
SE/se-lib/AclQueryFeatures.php

@@ -319,6 +319,18 @@ class AclQueryFeatures {
 			} else if ('f_is_not_instance' === $k) { // parsed before
 			} else if ('@instances' === $k) { // skip - select
 			} else if ('cols' === $k) { // skip - select
+			} else if ('f_@selected' === $k) { // skip - f_@selected
+				Lib::loadClass('FeatureAttrSelected');
+				$userSelectedTableName = FeatureAttrSelected::getAttributeTableName($typeName = $this->_acl->getNamespace(), $idUser = User::getID());
+				$pkFieldName = $this->_acl->getPrimaryKeyField();
+				if ('YES' === $v) {
+					$this->_query->join($userSelectedTableName, 't_selected', [ 'rawJoin' => "t.{$pkFieldName} = t_selected.primaryKey" ]);
+				} else if ('NO' === $v) {
+					$this->_query->leftJoin($userSelectedTableName, 't_selected', [ 'rawJoin' => "t.{$pkFieldName} = t_selected.primaryKey" ]);
+					$this->_query->where(['t_selected.primaryKey', 'is null']);
+				} else {
+					throw new Exception("Not implemented @selected filter value '{$v}'");
+				}
 			} else if ('f_' === substr($k, 0, 2) && is_string($v) && strlen($k) > 3) {
 				$fieldName = substr($k, 2);
 				$fieldType = $this->_acl->getXsdFieldType($fieldName);

+ 1 - 0
SE/se-lib/FeatureAttrSelected.php

@@ -76,6 +76,7 @@ class FeatureAttrSelected {
 		");
 	}
 
+	// @example FeatureAttrSelected::getAttributeTableName($typeName, $idUser);
 	static function getAttributeTableName($typeName, $idUser) {
 		static $_created = [];
 		$key = "{$typeName}-{$idUser}";