Skip to content

Commit

Permalink
CFM-7_people_index_filter_by_cou (#351)
Browse files Browse the repository at this point in the history
* Support filtering by COU for people index view.Fix COU top button label display.

* Add cou list to autoviewvars
  • Loading branch information
Ioannis authored Nov 15, 2025
1 parent db634d2 commit be0ae11
Show file tree
Hide file tree
Showing 5 changed files with 66 additions and 11 deletions.
2 changes: 2 additions & 0 deletions app/config/bootstrap.php
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,9 @@
// \Cake\Utility\Inflector::rules('uninflected', ['dontinflectme']);

\Cake\Utility\Inflector::rules('irregular', ['co_terms_and_condition' => 'co_terms_and_conditions']);
\Cake\Utility\Inflector::rules('uninflected', ['co_terms_and_conditions' => 'co_terms_and_conditions']);
\Cake\Utility\Inflector::rules('irregular', ['cou' => 'cous']);
\Cake\Utility\Inflector::rules('uninflected', ['cous' => 'cous']);
\Cake\Utility\Inflector::rules('irregular', ['meta' => 'meta']);

/*
Expand Down
18 changes: 15 additions & 3 deletions app/src/Lib/Traits/SearchFilterTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ public function addJoins(Query $query, string $attribute, ServerRequest $request
return $query;
}

$parentTable = $this->_alias;
$parentTable = $this->getAlias();
$joinAssociations = [];
// Iterate over the dot notation and add the joins in the correct order
// People.Names
Expand Down Expand Up @@ -183,13 +183,25 @@ public function expressionsConstructor(Query $query, QueryExpression $exp, strin
}

// Prepend the Model name to the attribute
$modelPrefix = $this->_alias;
$modelPrefix = $this->getAlias();
if(isset($this->searchFilters[$attribute]['model'])) {
$associationNamesPath = explode('.', $this->searchFilters[$attribute]['model']);
$modelPrefix = Inflector::pluralize(end($associationNamesPath));
}

$attributeWithModelPrefix = $modelPrefix . '.' . $attribute;
/**
* Build a qualified attribute name. This is required for queries/associations that are beyond the
* first level. e.g. People.PersonRoles.Cous
* If the attribute matches the model's foreign-key pattern (eg, cou_id for Cous),
* return "<ModelPrefix>.id"; otherwise "<ModelPrefix>.<attribute>".
*/
$expectedFk = StringUtilities::classNameToForeignKey($modelPrefix);
if (strcasecmp($attribute, $expectedFk) === 0) {
// Attribute is the FK to this model -> target the model's primary key
$attributeWithModelPrefix = $modelPrefix . '.id';
} else {
$attributeWithModelPrefix = $modelPrefix . '.' . $attribute;
}

$search = $q;

Expand Down
14 changes: 12 additions & 2 deletions app/src/Model/Table/PeopleTable.php
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,11 @@ public function initialize(array $config): void {
'types' => [
'type' => 'type',
'attribute' => 'Names.type'
]
],
'cous' => [
'type' => 'select',
'model' => 'Cous'
],
]);

// XXX expand/revise this as needed to work best with looking up the related models
Expand Down Expand Up @@ -244,7 +248,13 @@ public function initialize(array $config): void {
'model' => 'People',
'active' => false,
'order' => 99
]
],
'cou_id' => [
'type' => 'select',
'model' => 'PersonRoles.Cous',
'active' => true,
'order' => 7
],
]);

$this->setTabsConfig(
Expand Down
34 changes: 34 additions & 0 deletions app/src/View/Helper/FilterHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
use Cake\Collection\Collection;
use Cake\ORM\TableRegistry;
use Cake\Utility\Hash;
use Cake\Utility\Inflector;
use Cake\View\Helper;

class FilterHelper extends Helper
Expand Down Expand Up @@ -176,4 +177,37 @@ public function getFullName(int $personId): string
$person = $ModelTable->primaryName($personId);
return "{$person->given} {$person->family}";
}

/**
* Normalize the filter button title for display.
* 1) Build initial title via humanize(underscore(label-source))
* 2) If the title is a sequence of capital letters separated by single spaces (e.g., "C O U"),
* remove all spaces -> "COU"
* 3) If the title is CamelCase with no spaces (e.g., "ThisIsAName"),
* insert a space before each capital and trim.
*
* @param string $rawLabel
* @return string
*/
public function buildFilterButtonTitle(string $rawLabel): string
{
// Humanize
$filterTitle = Inflector::humanize(
Inflector::underscore($rawLabel)
);

// If like "C O U" (series of capital letters separated by spaces), collapse spaces -> "COU"
if (preg_match('/^[A-Z](?:\s[A-Z])+$/', $filterTitle) === 1) {
return str_replace(' ', '', $filterTitle);
}

// If CamelCase with no spaces, insert spaces before capitals and trim
if (!str_contains($filterTitle, ' ') && preg_match('/[A-Z]/', $filterTitle) === 1) {
// Insert a space before every capital letter except the first character
$filterTitle = preg_replace('/(?<!^)(?=[A-Z])/', ' ', $filterTitle);
return trim((string)$filterTitle);
}

return $filterTitle;
}
}
9 changes: 3 additions & 6 deletions app/templates/element/filter/topButtons.php
Original file line number Diff line number Diff line change
Expand Up @@ -65,12 +65,9 @@
}
}

$filter_title =
Inflector::humanize(
Inflector::underscore(
$vv_searchable_attributes[$key]['label'] ?? $columns[$key]['label']
)
);
$filter_title = $this->Filter->buildFilterButtonTitle(
$vv_searchable_attributes[$key]['label'] ?? $columns[$key]['label']
);

?>

Expand Down

0 comments on commit be0ae11

Please sign in to comment.