Skip to content

Commit

Permalink
Initial commit dynamic construct of Index filtering
Browse files Browse the repository at this point in the history
  • Loading branch information
Ioannis Igoumenos committed May 4, 2022
1 parent 54f7680 commit 28497db
Show file tree
Hide file tree
Showing 5 changed files with 89 additions and 67 deletions.
78 changes: 23 additions & 55 deletions app/src/Lib/Traits/SearchFilterTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,36 +29,12 @@

namespace App\Lib\Traits;

use Cake\Utility\Inflector;

trait SearchFilterTrait {
// Array (and configuration) of permitted search filters
private $searchFilters = array();

/**
* Determine the UI label for the specified attribute.
*
* @since COmanage Registry v5.0.0
* @param string $attribute Attribute
* @return string Label
* @todo Merge this with _column_key from index.ctp
*/

public function getLabel(string $attribute): string {
if(isset($this->searchFilters[$attribute]['label'])
&& $this->searchFilters[$attribute]['label'] !== null) {
return $this->searchFilters[$attribute]['label'];
}

// Try to construct a label from the language key.
$l = __d('field', $attribute);

if($l != $attribute) {
return $l;
}

// If we make it here, just return $attribute
return $attribute;
}


/**
* Obtain the set of permitted search attributes.
*
Expand All @@ -67,37 +43,28 @@ public function getLabel(string $attribute): string {
*/

public function getSearchableAttributes(): array {
// Not every configuration element is necessary for the search form, and
// some need to be calculated, so we do that work here.

$ret = [];

foreach(array_keys($this->searchFilters) as $attr) {
$ret[ $attr ] = [
'label' => $this->getLabel($attr)
foreach ($this->filterMetadataFields() as $column => $type) {
// If the column is an array then we are accessing the Metadata fields. Skip
if(is_array($type)) {
continue;
}
$this->searchFilters[$column] = [
'substring' => ($type === "string"),
// todo: Probably the following line is redundant but i am leaving it for now
'label' => (__d('field', $column) ?? Inflector::humanize($column)),
'caseSensitive' => false,
];

// Not every configuration element is necessary for the search form, and
// some need to be calculated, so we do that work here.
$ret[ $column ] = [
'label' => (__d('field', $column) ?? Inflector::humanize($column))
];
}

return $ret;
}

/**
* Add a permitted search filters.
*
* @since COmanage Registry v5.0.0
* @param string $attribute Attribute that filtering is permitted on (database name)
* @param bool $caseSensitive Whether this attribute is case sensitive
* @param string $label Label for this search field, or null to autocalculate
* @param bool $substring Whether substring searching is permitted for this attribute
*/

public function setSearchFilter(string $attribute,
bool $caseSensitive=false,
string $label=null,
bool $substring=true): void {
$this->searchFilters[$attribute] = compact('caseSensitive', 'label', 'substring');

return $ret ?? [];
}

/**
* Build a query where() clause for the configured attribute.
*
Expand All @@ -110,6 +77,7 @@ public function setSearchFilter(string $attribute,

public function whereFilter(\Cake\ORM\Query $query, string $attribute, string $q): object {
if(!empty($this->searchFilters[$attribute])) {
// todo: move caseSensitive into filter block itself
$cs = (isset($this->searchFilters[$attribute]['caseSensitive'])
&& $this->searchFilters[$attribute]['caseSensitive']);

Expand Down
61 changes: 61 additions & 0 deletions app/src/Lib/Traits/TableMetaTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@

namespace App\Lib\Traits;

use Cake\Utility\Inflector;

trait TableMetaTrait {
// Does this Table represent Registry objects or configuration?
private $confTable = false;
Expand All @@ -54,4 +56,63 @@ public function getIsConfigurationTable() {
public function setIsConfigurationTable(bool $confTable) {
$this->confTable = $confTable;
}


/**
* Filter metadata fields.
*
* @since COmanage Registry v5.0.0
* @return array An array of columns distinguished in metadata and non-metadata
*/

protected function filterMetadataFields() {
// Get the list of columns
$coltype = $this->getSchema()->typeMap();
$entity = $this->getEntityClass();
$entity_namespace = explode('\\', $entity);
$modelName = end($entity_namespace);

// Get the list of belongs_to associations and construct an exclude array
$assc_keys = [];
foreach ($this->associations() as $assc) {
if($assc->type() === "manyToOne") {
$assc_keys[] = Inflector::underscore(Inflector::classify($assc->getClassName())) . "_id";
}
}
// Map the model (eg: Person) to the changelog key (person_id)
$mfk = Inflector::underscore($modelName) . "_id";


$meta_fields = [
...$assc_keys,
$mfk,
'actor_identifier',
// 'provisioning_target_id',
'created', // todo: I might need to revisit this. We might want to filter according to date in some occassions. Like petitions
'deleted',
'id',
'modified',
'revision',
// 'source_ad_hoc_attribute_id',
// 'source_address_id',
// 'source_email_address_id',
// 'source_identifier_id',
// 'source_name_id',
// 'source_external_identity_id',
// 'source_telephone_number_id',
];

$newa = array();
foreach($coltype as $clmn => $type) {
if(in_array($clmn, $meta_fields,true)) {
// Move the value to metadata
$newa['meta'][$clmn] = $type;
} else {
// Just copy the value
$newa[$clmn] = $type;
}
}

return $newa ?? [];
}
}
5 changes: 0 additions & 5 deletions app/src/Model/Table/CousTable.php
Original file line number Diff line number Diff line change
Expand Up @@ -72,11 +72,6 @@ public function initialize(array $config): void {

$this->setPrimaryLink('co_id');
$this->setRequiresCO(true);

// Set up the fields that may be filtered in the index view
$this->setSearchFilter('name', false, null, true);
$this->setSearchFilter('parent_id', true, null, false);
$this->setSearchFilter('description', false, null, true);

$this->setPermissions([
// Actions that operate over an entity (ie: require an $id)
Expand Down
5 changes: 0 additions & 5 deletions app/src/Model/Table/TypesTable.php
Original file line number Diff line number Diff line change
Expand Up @@ -113,11 +113,6 @@ public function initialize(array $config): void {
'class' => 'SuspendableStatusEnum'
]
]);

// Set up the fields that may be filtered in the index view
$this->setSearchFilter('display_name', false, null, true);
$this->setSearchFilter('attribute', true, null, false);
$this->setSearchFilter('statuses', false, null, true);

$this->setPermissions([
// Actions that operate over an entity (ie: require an $id)
Expand Down
7 changes: 5 additions & 2 deletions app/templates/element/filter.php
Original file line number Diff line number Diff line change
Expand Up @@ -105,11 +105,14 @@
'required' => false,
];

if(isset($$key)) {
// The populated variables are in plural while the column names are singular
// Convention: It is a prerequisite that the vvar should be the plural of the column name
$populated_vvar = Cake\Utility\Inflector::pluralize($key);
if(isset($$populated_vvar)) {
// If we have an AutoViewVar matching the name of this key,
// convert to a select
$formParams['type'] = 'select';
$formParams['options'] = $$key;
$formParams['options'] = $$populated_vvar;
// Allow empty so a filter doesn't require (eg) SOR
$formParams['empty'] = true;
}
Expand Down

0 comments on commit 28497db

Please sign in to comment.