Skip to content

Commit

Permalink
Join Nodel associations when using filtering
Browse files Browse the repository at this point in the history
  • Loading branch information
Ioannis Igoumenos committed Oct 1, 2023
1 parent c6c2af7 commit 1826c32
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 16 deletions.
2 changes: 1 addition & 1 deletion app/src/Controller/StandardController.php
Original file line number Diff line number Diff line change
Expand Up @@ -551,7 +551,7 @@ public function index() {

if(!empty($searchableAttributes)) {
// Here we iterate over the attributes, and we add a new where clause for each one
foreach(array_keys($searchableAttributes) as $attribute) {
foreach($searchableAttributes as $attribute => $options) {
if(!empty($this->request->getQuery($attribute))) {
$query = $table->whereFilter($query, $attribute, $this->request->getQuery($attribute));
} elseif (!empty($this->request->getQuery($attribute . "_starts_at"))
Expand Down
47 changes: 36 additions & 11 deletions app/src/Lib/Traits/SearchFilterTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,8 @@ public function getSearchableAttributes(string $controller, string $vv_tz=null):
$this->searchFilters[$field] = [
'type' => 'string', // XXX for now - this needs to be looked up.
'label' => \App\Lib\Util\StringUtilities::columnKey($fieldName, $field, $vv_tz, true),
'active' => isset($f['active']) ? $f['active'] : true
'active' => isset($f['active']) ? $f['active'] : true,
'model' => $f['model']
];
}
}
Expand Down Expand Up @@ -132,36 +133,60 @@ public function whereFilter(\Cake\ORM\Query $query, string $attribute, string|ar
return $query;
}

if(isset($this->searchFilters[$attribute]['model'])) {
$changelog_fk = strtolower(Inflector::underscore($this->searchFilters[$attribute]['model'])) . '_id';
$fk = strtolower(Inflector::underscore(Inflector::singularize($this->_alias))) . '_id';
$mtable_name = Inflector::tableize(Inflector::pluralize($this->searchFilters[$attribute]['model']));
$mtable_alias = Inflector::pluralize($this->searchFilters[$attribute]['model']);
$query->join([$mtable_alias => [
'table' => $mtable_name,
'conditions' => [
$mtable_alias . '.' . $fk . '=' . $this->_alias . '.id',
$mtable_alias . '.' . 'deleted IS NOT TRUE',
$mtable_alias . '.' . $changelog_fk . ' IS NULL'
],
'type' => 'INNER'
]]);
}

// Prepend the Model name to the attribute
$attributeWithModelPrefix = isset($this->searchFilters[$attribute]['model']) ?
Inflector::pluralize($this->searchFilters[$attribute]['model']) . '.' . $attribute :
$this->_alias . '.' . $attribute;

$search = $q;
$sub = false;
// Primitive types
$search_types = ['integer', 'boolean'];
if( $this->searchFilters[$attribute]['type'] == "string") {
$search = "%" . $search . "%";
$sub = true;
// Search type
} elseif(in_array($this->searchFilters[$attribute]['type'], $search_types, true)) {
return $query->where([$attribute => $search]);
return $query->where([$attributeWithModelPrefix => $search]);
// Date
} elseif($this->searchFilters[$attribute]['type'] == "date") {
// Parse the date string with FrozenTime to improve error handling
return $query->where([$attribute => FrozenTime::parseDate($search, 'y-M-d')]);
return $query->where([$attributeWithModelPrefix => FrozenTime::parseDate($search, 'y-M-d')]);
// Timestamp
} elseif( $this->searchFilters[$attribute]['type'] == "timestamp") {
// Date between dates
if(!empty($search[0])
&& !empty($search[1])) {
return $query->where(function (\Cake\Database\Expression\QueryExpression $exp, \Cake\ORM\Query $query) use ($attribute, $search) {
return $exp->between($attribute, "'" . $search[0] . "'", "'" . $search[1] . "'");
return $query->where(function (\Cake\Database\Expression\QueryExpression $exp, \Cake\ORM\Query $query) use ($attributeWithModelPrefix, $search) {
return $exp->between($attributeWithModelPrefix, "'" . $search[0] . "'", "'" . $search[1] . "'");
});
// The starts at is non-empty. So the data should be greater than the starts_at date
} elseif(!empty($search[0])
&& empty($search[1])) {
return $query->where(function (\Cake\Database\Expression\QueryExpression $exp, \Cake\ORM\Query $query) use ($attribute, $search) {
return $exp->gte("'" . FrozenTime::parse($search[0]) . "'", $attribute);
return $query->where(function (\Cake\Database\Expression\QueryExpression $exp, \Cake\ORM\Query $query) use ($attributeWithModelPrefix, $search) {
return $exp->gte("'" . FrozenTime::parse($search[0]) . "'", $attributeWithModelPrefix);
});
// The ends at is non-empty. So the data should be less than the ends at date
} elseif(!empty($search[1])
&& empty($search[0])) {
return $query->where(function (\Cake\Database\Expression\QueryExpression $exp, \Cake\ORM\Query $query) use ($attribute, $search) {
return $exp->lte("'" . FrozenTime::parse($search[1]) . "'", $attribute);
return $query->where(function (\Cake\Database\Expression\QueryExpression $exp, \Cake\ORM\Query $query) use ($attributeWithModelPrefix, $search) {
return $exp->lte("'" . FrozenTime::parse($search[1]) . "'", $attributeWithModelPrefix);
});
} else {
// We return everything
Expand All @@ -171,8 +196,8 @@ public function whereFilter(\Cake\ORM\Query $query, string $attribute, string|ar
}

// String values
return $query->where(function (\Cake\Database\Expression\QueryExpression $exp, \Cake\ORM\Query $query) use ($attribute, $search, $sub) {
$lower = $query->func()->lower([$attribute => 'identifier']);
return $query->where(function (\Cake\Database\Expression\QueryExpression $exp, \Cake\ORM\Query $query) use ($attributeWithModelPrefix, $search, $sub) {
$lower = $query->func()->lower([$attributeWithModelPrefix => 'identifier']);
return ($sub) ? $exp->like($lower, strtolower($search))
: $exp->eq($lower, strtolower($search));
});
Expand Down
8 changes: 4 additions & 4 deletions app/src/Model/Table/PeopleTable.php
Original file line number Diff line number Diff line change
Expand Up @@ -158,22 +158,22 @@ public function initialize(array $config): void {
$this->setFilterConfig([
'family' => [
'type' => 'relatedModel',
'model' => 'names',
'model' => 'Name',
'active' => true
],
'given' => [
'type' => 'relatedModel',
'model' => 'names',
'model' => 'Name',
'active' => true
],
'mail' => [
'type' => 'relatedModel',
'model' => 'email_addresses',
'model' => 'EmailAddress',
'active' => true
],
'identifier' => [
'type' => 'relatedModel',
'model' => 'identifiers',
'model' => 'Identifier',
'active' => true
],
'timezone' => [
Expand Down

0 comments on commit 1826c32

Please sign in to comment.