mirror of
https://github.com/espocrm/espocrm.git
synced 2026-07-01 08:26:04 +00:00
noneOf filter
This commit is contained in:
@@ -742,7 +742,7 @@ class Base
|
||||
$attribute = $w['attribute'];
|
||||
}
|
||||
if ($attribute) {
|
||||
if (isset($w['type']) && in_array($w['type'], ['isLinked', 'isNotLinked', 'linkedWith', 'isUserFromTeams'])) {
|
||||
if (isset($w['type']) && in_array($w['type'], ['isLinked', 'isNotLinked', 'linkedWith', 'notLinkedWith', 'isUserFromTeams'])) {
|
||||
if (in_array($attribute, $this->getAcl()->getScopeForbiddenFieldList($this->getEntityType()))) {
|
||||
throw new Forbidden();
|
||||
}
|
||||
@@ -958,6 +958,10 @@ class Base
|
||||
$attribute = $item['attribute'];
|
||||
}
|
||||
|
||||
if (!is_null($attribute) && !is_string($attribute)) {
|
||||
throw new Error('Bad attribute in where statement');
|
||||
}
|
||||
|
||||
if (!empty($attribute) && !empty($item['type'])) {
|
||||
$methodName = 'getWherePart' . ucfirst($attribute) . ucfirst($item['type']);
|
||||
if (method_exists($this, $methodName)) {
|
||||
@@ -1159,14 +1163,14 @@ class Base
|
||||
break;
|
||||
case 'isNotLinked':
|
||||
if (!$result) break;
|
||||
$alias = $attribute . 'IsNotLinkedFilter';
|
||||
$alias = $attribute . 'IsNotLinkedFilter' . strval(rand(10000, 99999));;
|
||||
$part[$alias . '.id'] = null;
|
||||
$this->setDistinct(true, $result);
|
||||
$this->addLeftJoin([$attribute, $alias], $result);
|
||||
break;
|
||||
case 'isLinked':
|
||||
if (!$result) break;
|
||||
$alias = $attribute . 'IsLinkedFilter';
|
||||
$alias = $attribute . 'IsLinkedFilter' . strval(rand(10000, 99999));;
|
||||
$part[$alias . '.id!='] = null;
|
||||
$this->setDistinct(true, $result);
|
||||
$this->addLeftJoin([$attribute, $alias], $result);
|
||||
@@ -1176,35 +1180,75 @@ class Base
|
||||
$link = $attribute;
|
||||
if (!$seed->hasRelation($link)) break;
|
||||
|
||||
$alias = $link . 'Filter' . strval(rand(10000, 99999));
|
||||
|
||||
$value = $item['value'];
|
||||
|
||||
if (is_null($value)) break;
|
||||
|
||||
$relationType = $seed->getRelationType($link);
|
||||
|
||||
if ($relationType == 'manyMany') {
|
||||
$this->addLeftJoin([$link, $alias], $result);
|
||||
$midKeys = $seed->getRelationParam($link, 'midKeys');
|
||||
|
||||
if (!empty($midKeys)) {
|
||||
$key = $midKeys[1];
|
||||
$part[$alias . 'Middle.' . $key] = $value;
|
||||
}
|
||||
} else if ($relationType == 'hasMany') {
|
||||
$this->addLeftJoin([$link, $alias], $result);
|
||||
|
||||
$part[$alias . '.id'] = $value;
|
||||
} else if ($relationType == 'belongsTo') {
|
||||
$key = $seed->getRelationParam($link, 'key');
|
||||
if (!empty($key)) {
|
||||
$part[$key] = $value;
|
||||
}
|
||||
} else if ($relationType == 'hasOne') {
|
||||
$this->addLeftJoin([$link, $alias], $result);
|
||||
$part[$alias . '.id'] = $value;
|
||||
} else {
|
||||
break;;
|
||||
}
|
||||
$this->setDistinct(true, $result);
|
||||
break;
|
||||
case 'notLinkedWith':
|
||||
$seed = $this->getSeed();
|
||||
$link = $attribute;
|
||||
if (!$seed->hasRelation($link)) break;
|
||||
|
||||
$value = $item['value'];
|
||||
|
||||
if (is_null($value)) break;
|
||||
|
||||
$relationType = $seed->getRelationType($link);
|
||||
|
||||
$alias = $link . 'NotLinkedFilter' . strval(rand(10000, 99999));
|
||||
|
||||
if ($relationType == 'manyMany') {
|
||||
$this->addLeftJoin([$link, $link . 'Filter'], $result);
|
||||
$this->addLeftJoin([$link, $alias], $result);
|
||||
$midKeys = $seed->getRelationParam($link, 'midKeys');
|
||||
|
||||
if (!empty($midKeys)) {
|
||||
$key = $midKeys[1];
|
||||
$part[$link . 'Filter' . 'Middle.' . $key] = $value;
|
||||
$result['joinConditions'][$alias] = [$key => $value];
|
||||
$part[$alias . 'Middle.' . $key] = null;
|
||||
}
|
||||
} else if ($relationType == 'hasMany') {
|
||||
$alias = $link . 'Filter';
|
||||
$this->addLeftJoin([$link, $alias], $result);
|
||||
|
||||
$part[$alias . '.id'] = $value;
|
||||
$result['joinConditions'][$alias] = ['id' => $value];
|
||||
$part[$alias . '.id'] = null;
|
||||
} else if ($relationType == 'belongsTo') {
|
||||
$key = $seed->getRelationParam($link, 'key');
|
||||
if (!empty($key)) {
|
||||
$part[$key] = $value;
|
||||
$part[$key . '!='] = $value;
|
||||
}
|
||||
} else if ($relationType == 'hasOne') {
|
||||
$this->addLeftJoin([$link, $link . 'Filter'], $result);
|
||||
$part[$link . 'Filter' . '.id'] = $value;
|
||||
$this->addLeftJoin([$link, alias], $result);
|
||||
$part[$alias . '.id!='] = $value;
|
||||
} else {
|
||||
return;
|
||||
break;
|
||||
}
|
||||
$this->setDistinct(true, $result);
|
||||
}
|
||||
|
||||
@@ -850,6 +850,48 @@ abstract class Base
|
||||
return implode(' ', $joinsArr);
|
||||
}
|
||||
|
||||
protected function buildJoinConditionStatement($alias, $f, $v)
|
||||
{
|
||||
$join = '';
|
||||
|
||||
$operator = '=';
|
||||
|
||||
if (!preg_match('/^[a-z0-9]+$/i', $f)) {
|
||||
foreach (self::$comparisonOperators as $op => $opDb) {
|
||||
if (strpos($f, $op) !== false) {
|
||||
$f = trim(str_replace($op, '', $f));
|
||||
$operator = $opDb;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$join .= " AND {$alias}." . $this->toDb($this->sanitize($f)) . "";
|
||||
if (is_array($v)) {
|
||||
$arr = [];
|
||||
foreach ($v as $item) {
|
||||
$arr[] = $this->pdo->quote($item);
|
||||
}
|
||||
$operator = "IN";
|
||||
if ($operator == '<>') {
|
||||
$operator = 'NOT IN';
|
||||
}
|
||||
if (count($arr)) {
|
||||
$join .= " " . $operator . " (" . implode(', ', $arr) . ")";
|
||||
} else {
|
||||
if ($operator === 'IN') {
|
||||
$join .= " IS NULL";
|
||||
} else {
|
||||
$join .= " IS NOT NULL";
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$join .= " " . $operator . " " . $this->pdo->quote($v);
|
||||
}
|
||||
|
||||
return $join;
|
||||
}
|
||||
|
||||
protected function getJoinRelated(IEntity $entity, $relationName, $left = false, $conditions = array(), $joinAlias = null)
|
||||
{
|
||||
$relOpt = $entity->relations[$relationName];
|
||||
@@ -890,7 +932,7 @@ abstract class Base
|
||||
$conditions = array_merge($conditions, $relOpt['conditions']);
|
||||
}
|
||||
foreach ($conditions as $f => $v) {
|
||||
$join .= " AND {$midAlias}." . $this->toDb($this->sanitize($f)) . " = " . $this->pdo->quote($v);
|
||||
$join .= $this->buildJoinConditionStatement($midAlias, $f, $v);
|
||||
}
|
||||
|
||||
$join .= " {$pre}JOIN `{$distantTable}` AS `{$alias}` ON {$alias}." . $this->toDb($foreignKey) . " = {$midAlias}." . $this->toDb($distantKey)
|
||||
@@ -906,13 +948,15 @@ abstract class Base
|
||||
|
||||
$alias = $joinAlias;
|
||||
|
||||
// TODO conditions
|
||||
|
||||
$join =
|
||||
"{$pre}JOIN `{$distantTable}` AS `{$alias}` ON {$this->toDb($entity->getEntityType())}." . $this->toDb('id') . " = {$alias}." . $this->toDb($foreignKey)
|
||||
. " AND "
|
||||
. "{$alias}.deleted = " . $this->pdo->quote(0) . "";
|
||||
|
||||
foreach ($conditions as $f => $v) {
|
||||
$join .= $this->buildJoinConditionStatement($alias, $f, $v);
|
||||
}
|
||||
|
||||
return $join;
|
||||
|
||||
case IEntity::HAS_CHILDREN:
|
||||
|
||||
@@ -525,7 +525,8 @@
|
||||
"isFromTeams": "Is From Team",
|
||||
"isNot": "Is Not",
|
||||
"isNotOneOf": "Is Not One Of",
|
||||
"anyOf": "Any Of"
|
||||
"anyOf": "Any Of",
|
||||
"noneOf": "None Of"
|
||||
},
|
||||
"varcharSearchRanges": {
|
||||
"equals": "Equals",
|
||||
|
||||
@@ -58,7 +58,7 @@ Espo.define('views/fields/link-multiple', 'views/fields/base', function (Dep) {
|
||||
|
||||
sortable: false,
|
||||
|
||||
searchTypeList: ['anyOf', 'isEmpty', 'isNotEmpty'],
|
||||
searchTypeList: ['anyOf', 'isEmpty', 'isNotEmpty', 'noneOf'],
|
||||
|
||||
data: function () {
|
||||
var ids = this.model.get(this.idsName);
|
||||
@@ -148,7 +148,7 @@ Espo.define('views/fields/link-multiple', 'views/fields/base', function (Dep) {
|
||||
},
|
||||
|
||||
handleSearchType: function (type) {
|
||||
if (~['anyOf'].indexOf(type)) {
|
||||
if (~['anyOf', 'noneOf'].indexOf(type)) {
|
||||
this.$el.find('div.link-group-container').removeClass('hidden');
|
||||
} else {
|
||||
this.$el.find('div.link-group-container').addClass('hidden');
|
||||
@@ -349,6 +349,18 @@ Espo.define('views/fields/link-multiple', 'views/fields/base', function (Dep) {
|
||||
}
|
||||
};
|
||||
return data;
|
||||
} else if (type === 'noneOf') {
|
||||
var values = this.ids || [];
|
||||
|
||||
var data = {
|
||||
type: 'notLinkedWith',
|
||||
value: this.ids || [],
|
||||
nameHash: this.nameHash,
|
||||
data: {
|
||||
type: type
|
||||
}
|
||||
};
|
||||
return data;
|
||||
} else if (type === 'isEmpty') {
|
||||
var data = {
|
||||
type: 'isNotLinked',
|
||||
|
||||
@@ -432,8 +432,8 @@ Espo.define('views/fields/link', 'views/fields/base', function (Dep) {
|
||||
value: [
|
||||
{
|
||||
type: 'notIn',
|
||||
attribute: this.searchData.oneOfIdList,
|
||||
value: value
|
||||
attribute: this.idName,
|
||||
value: this.searchData.oneOfIdList
|
||||
},
|
||||
{
|
||||
type: 'isNull',
|
||||
|
||||
Reference in New Issue
Block a user