From 037840be396fa2a3dfa2a777b7f5f50cc2d193a6 Mon Sep 17 00:00:00 2001 From: Ioannis Igoumenos Date: Sun, 9 Nov 2025 08:40:22 +0200 Subject: [PATCH 1/2] Support filtering by COU for people index view.Fix COU top button label display. --- app/config/bootstrap.php | 2 ++ app/src/Lib/Traits/SearchFilterTrait.php | 18 +++++++++-- app/src/Model/Table/PeopleTable.php | 8 ++++- app/src/View/Helper/FilterHelper.php | 34 +++++++++++++++++++++ app/templates/element/filter/topButtons.php | 9 ++---- 5 files changed, 61 insertions(+), 10 deletions(-) diff --git a/app/config/bootstrap.php b/app/config/bootstrap.php index bba87c600..93e4c292f 100644 --- a/app/config/bootstrap.php +++ b/app/config/bootstrap.php @@ -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']); /* diff --git a/app/src/Lib/Traits/SearchFilterTrait.php b/app/src/Lib/Traits/SearchFilterTrait.php index c1641cb45..b6ba84e60 100644 --- a/app/src/Lib/Traits/SearchFilterTrait.php +++ b/app/src/Lib/Traits/SearchFilterTrait.php @@ -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 @@ -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 ".id"; otherwise ".". + */ + $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; diff --git a/app/src/Model/Table/PeopleTable.php b/app/src/Model/Table/PeopleTable.php index af25f5a44..55761198a 100644 --- a/app/src/Model/Table/PeopleTable.php +++ b/app/src/Model/Table/PeopleTable.php @@ -244,7 +244,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( diff --git a/app/src/View/Helper/FilterHelper.php b/app/src/View/Helper/FilterHelper.php index b6258bb14..74bda0c5c 100644 --- a/app/src/View/Helper/FilterHelper.php +++ b/app/src/View/Helper/FilterHelper.php @@ -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 @@ -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('/(?Filter->buildFilterButtonTitle( + $vv_searchable_attributes[$key]['label'] ?? $columns[$key]['label'] +); ?> From a2c8f24b2de0072f3ddde09c5bad0f3a95321970 Mon Sep 17 00:00:00 2001 From: Ioannis Igoumenos Date: Mon, 10 Nov 2025 18:18:27 +0200 Subject: [PATCH 2/2] Add cou list to autoviewvars --- app/src/Model/Table/PeopleTable.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/app/src/Model/Table/PeopleTable.php b/app/src/Model/Table/PeopleTable.php index 55761198a..a0f386752 100644 --- a/app/src/Model/Table/PeopleTable.php +++ b/app/src/Model/Table/PeopleTable.php @@ -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