diff --git a/app/src/Controller/StandardController.php b/app/src/Controller/StandardController.php index 696db82bb..1e161626e 100644 --- a/app/src/Controller/StandardController.php +++ b/app/src/Controller/StandardController.php @@ -35,7 +35,7 @@ use \Cake\Http\Exception\BadRequestException; use \App\Lib\Enum\ProvisioningContextEnum; use \App\Lib\Enum\SuspendableStatusEnum; -use \App\Lib\Util\StringUtilities; +use \App\Lib\Util\{StringUtilities, FunctionUtilities}; class StandardController extends AppController { use \App\Lib\Traits\IndexQueryTrait; @@ -656,13 +656,8 @@ protected function populateAutoViewVars(object $obj=null) { case 'select': $avvmodel = $avv['model']; $this->$avvmodel = TableRegistry::getTableLocator()->get($avvmodel); + $query = $this->$avvmodel->find($avv['type'] == 'auxiliary' ? 'all' : 'list'); - if($avv['type'] == 'auxiliary') { - $query = $this->$avvmodel->find(); - } else { - $query = $this->$avvmodel->find('list'); - } - if(!empty($avv['find'])) { if($avv['find'] == 'filterPrimaryLink') { // We're filtering the requested model, not our current model. @@ -693,18 +688,30 @@ protected function populateAutoViewVars(object $obj=null) { // Use the specified finder, if configured $query = $query->find($avv['find']); } - } else { -// XXX is this the best logic? maybe some relation to filterPrimaryLink? + } elseif($table->getSchema()->hasColumn('co_id')) { + // XXX is this the best logic? maybe some relation to filterPrimaryLink? // By default, filter everything on CO ID - $avv['where']['co_id'] = $this->getCOID(); //$query = $query->where([$table->getAlias().'.co_id' => $this->getCOID()]); } - + + // Where Rule. The rule will be transfered as is if(!empty($avv['where'])) { // Filter on the specified clause (of the form [column=>value]) $query = $query->where($avv['where']); } + + // Where rule that will be evaluated. We use the custom whereEvan key to + // distinguish from the plain where. Also it might contain more than one conditions + if(!empty($avv['whereEval'])) { + foreach ($avv['whereEval'] as $whereClauseColumn => $chainedMethodDescription) { + $calculatedValue = FunctionUtilities::dynamicChainedFunction( + $this, + $chainedMethodDescription + ); + $query = $query->where([$whereClauseColumn => $calculatedValue]); + } + } // Sort the list by display field if(!empty($avv['model']) && method_exists($this->$avvmodel, "getDisplayField")) { diff --git a/app/src/Lib/Util/FunctionUtilities.php b/app/src/Lib/Util/FunctionUtilities.php new file mode 100644 index 000000000..cb7728d8b --- /dev/null +++ b/app/src/Lib/Util/FunctionUtilities.php @@ -0,0 +1,83 @@ +getRequest()->getQuery(name: 'group_id) + * $rootObject: $this, + * $chainedDescriptionExample => [ + * // Chain of methods + * 'getRequest', + * 'getQuery' => [ + * // parameter name => parameter value, We are taking advantage the named parameters feature + * 'name' =>'group_id' + * ], + * ] + * + * @param mixed $rootObj Object of the intance method we are calling + * @param array $chainedDescription Description from root to final method call. + * + * @return mixed Return the intermediate objects or the final value + * @since COmanage Registry v5.0.0 + */ + + public static function dynamicChainedFunction(mixed $rootObj, array $chainedDescription): mixed { + if(!empty($chainedDescription)) { + $key = key($chainedDescription); + // This is the case where we pass a function with no parameters + $funcName = null; + $params = null; + // We pass a function with an array of parameters + if( \is_int($key)) { + $funcName = array_shift($chainedDescription); + } elseif (\is_string($key)) { + $funcName = $key; + $params = array_shift($chainedDescription); + } + + if(!empty($params)) { + $funcCall = $rootObj->$funcName(...$params); + } else { + $funcCall = $rootObj->$funcName(); + } + $value = self::dynamicChainedFunction($funcCall, $chainedDescription); + } + + return !\is_object($rootObj) ? $rootObj : $value; + } + +} \ No newline at end of file diff --git a/app/src/Model/Table/GroupNestingsTable.php b/app/src/Model/Table/GroupNestingsTable.php index 806584b67..26e76f323 100644 --- a/app/src/Model/Table/GroupNestingsTable.php +++ b/app/src/Model/Table/GroupNestingsTable.php @@ -77,9 +77,9 @@ public function initialize(array $config): void { $this->setPrimaryLink('group_id'); $this->setRequiresCO(true); - $this->setEditContains(['Groups', 'TargetGroups']); + $this->setEditContains(['Groups', 'GroupMembers', 'TargetGroups']); - $this->setIndexContains(['Groups', 'TargetGroups']); + $this->setIndexContains(['Groups', 'GroupMembers', 'TargetGroups']); $this->setPermissions([ // XXX update for couAdmins, group owners, etc @@ -95,6 +95,25 @@ public function initialize(array $config): void { 'index' => ['platformAdmin', 'coAdmin'] ] ]); + + $this->setAutoViewVars([ + 'groupMembers' => [ + 'type' => 'auxiliary', + 'model' => 'GroupMembers', + 'whereEval' => [ + // Where Clause column name + 'GroupMembers.group_id' => [ + // Chain of methods that will construct the whereClause condition value + // Method that accepts no parameters + 'getRequest', + // Method that accepts only one parameter + // getQuery(name: 'group_id') + 'getQuery' => [ + 'name' =>'group_id' + ] + ] + ] + ]]); } /** diff --git a/app/src/Model/Table/GroupsTable.php b/app/src/Model/Table/GroupsTable.php index 01f351f25..339693d10 100644 --- a/app/src/Model/Table/GroupsTable.php +++ b/app/src/Model/Table/GroupsTable.php @@ -123,7 +123,8 @@ public function initialize(array $config): void { // For an Owners Group, the group it manages owners for 'OwnersForGroup', // For a regular group, the Owners Group - 'OwnersGroup' + 'OwnersGroup', + 'GroupMembers' ]); $this->setViewContains([ @@ -131,7 +132,8 @@ public function initialize(array $config): void { // For an Owners Group, the group it manages owners for 'OwnersForGroup', // For a regular group, the Owners Group - 'OwnersGroup' + 'OwnersGroup', + 'GroupMembers' ]); // XXX Also used by SearchBlocks diff --git a/app/templates/Groups/fields.inc b/app/templates/Groups/fields.inc index 9f621f714..6669ba563 100644 --- a/app/templates/Groups/fields.inc +++ b/app/templates/Groups/fields.inc @@ -74,7 +74,7 @@ if($vv_action != 'add') { print $this->Field->statusControl( fieldName: 'owners_group_id', - status: $vv_obj->owners_group->name, + status: $vv_obj->owners_group->name ?? '', link: ['url' => ['controller' => 'groups', 'action' => 'edit', $vv_obj->owners_group_id]] ); } diff --git a/app/templates/element/subnavigation.php b/app/templates/element/subnavigation.php index 5aa1f15b1..0455fb437 100644 --- a/app/templates/element/subnavigation.php +++ b/app/templates/element/subnavigation.php @@ -301,14 +301,33 @@