From ccd4a8c62419bd9eb4b9d730a213728d7067009c Mon Sep 17 00:00:00 2001 From: iglocska Date: Wed, 28 Aug 2024 15:38:53 +0200 Subject: [PATCH 1/5] new: [individuals] add individual auto-saves an alignment - if a non community admin enrolls an individual, set the alignment by default - this will prevent them from becoming uneditable --- src/Controller/IndividualsController.php | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/Controller/IndividualsController.php b/src/Controller/IndividualsController.php index c37a0d2..ebd4539 100644 --- a/src/Controller/IndividualsController.php +++ b/src/Controller/IndividualsController.php @@ -62,7 +62,16 @@ class IndividualsController extends AppController public function add() { - $this->CRUD->add(); + $currentUser = $this->ACL->getUser(); + $params = [ + 'afterSave' => function($data) use ($currentUser) { + if (empty($currentUser['role']['perm_community_admin'])) { + $this->Individuals->Alignments->setAlignment($currentUser['organisation_id'], $data->id, 'Member'); + } + return $data; + } + ]; + $this->CRUD->add($params); $responsePayload = $this->CRUD->getResponsePayload(); if (!empty($responsePayload)) { return $responsePayload; From e39ece57c53fa6c0142c6f5e20627948ee34693f Mon Sep 17 00:00:00 2001 From: iglocska Date: Wed, 28 Aug 2024 15:39:46 +0200 Subject: [PATCH 2/5] new: [meta_field] API improved - simple way to add metafields added - simply pass a list of meta_fields to the object about to be saved - the only fields required are: template_uuid, template_version, field, value Example for an individual: ``` { "first_name": "Andras", "last_name": "Iklody", "email": "andras.iklody@circl.lu", "alignments": { "organisation": [ { "uuid": "9d4d7913-2602-4333-8440-c78b7f92eca3", "name": "Iglocska.eu" } ] }, "meta_fields": [ { "field": "perm_mattermost", "value": true, "template_uuid": "447ded8b-314b-41c7-a913-4ce32535b28d", "template_version": 2 } ] } ``` --- src/Controller/Component/CRUDComponent.php | 59 ++++++++++++++++++++-- 1 file changed, 55 insertions(+), 4 deletions(-) diff --git a/src/Controller/Component/CRUDComponent.php b/src/Controller/Component/CRUDComponent.php index 7d87fd5..441a5e7 100644 --- a/src/Controller/Component/CRUDComponent.php +++ b/src/Controller/Component/CRUDComponent.php @@ -458,6 +458,9 @@ class CRUDComponent extends Component $massagedData = $this->massageMetaFields($data, $input, $metaTemplates); unset($input['MetaTemplates']); // Avoid MetaTemplates to be overriden when patching entity $data = $massagedData['entity']; + if (isset($input['meta_fields'])) { + unset($input['meta_fields']); + } } $data = $this->Table->patchEntity($data, $input, $patchEntityParams); if (isset($params['beforeSave'])) { @@ -568,10 +571,35 @@ class CRUDComponent extends Component $this->Table->saveMetaFields($id, $input, $this->Table); } - // prune empty values and marshall fields - public function massageMetaFields($entity, $input, $allMetaTemplates = []) + private function handleSimpleMetaFieldInput($allMetaTemplates, $input, &$cleanupMetaFields) { - if (empty($input['MetaTemplates']) || !$this->metaFieldsSupported()) { + $input['MetaTemplates'] = []; + foreach ($input['meta_fields'] as $metaField) { + foreach ($allMetaTemplates as $metaTemplate) { + if ($metaTemplate->uuid != $metaField['template_uuid'] || $metaTemplate->version != $metaField['template_version']) { + continue; + } + foreach ($metaTemplate['meta_template_fields'] as $mtp) { + if ($mtp->field == $metaField['field']) { + // I feel dirty. I'm sorry. + $input['MetaTemplates'][$metaTemplate->id]['meta_template_fields'][$mtp->id]['metaFields']['new'][] = $metaField['value']; + $cleanupMetaFields[] = [ + 'scope' => $this->Table->getBehavior('MetaFields')->getScope(), + 'field' => $mtp->field, + 'meta_template_field_id' => $mtp->id, + 'meta_template_id' => $metaTemplate->id + ]; + } + } + } + } + return $input; + } + + // prune empty values and marshall fields + public function massageMetaFields($entity, $input, $allMetaTemplates = [], &$cleanupMetaFields = []) + { + if ((empty($input['MetaTemplates']) && !isset($input['meta_fields'])) || !$this->metaFieldsSupported()) { return ['entity' => $entity, 'metafields_to_delete' => []]; } @@ -580,6 +608,12 @@ class CRUDComponent extends Component if (empty($metaTemplates)) { $allMetaTemplates = $this->getMetaTemplates()->toArray(); } + // handle simpler format of meta_templates via the API + // the idea is that integrators shouldn't have to mimic the complex format used by the UI. + if (isset($input['meta_fields'])) { + $input = $this->handleSimpleMetaFieldInput($allMetaTemplates, $input, $cleanupMetaFields); + $entity->cleanupMetaFields = $cleanupMetaFields; + } if (!empty($entity->meta_fields)) { foreach ($entity->meta_fields as $i => $metaField) { $metaFieldsIndex[$metaField->id] = $i; @@ -738,11 +772,28 @@ class CRUDComponent extends Component throw new NotFoundException(__('Could not save {0} due to the marshaling failing. Your input is bad and you should feel bad.', $this->ObjectAlias)); } } + $cleanupMetaFields = []; if ($metaFieldsEnabled) { - $massagedData = $this->massageMetaFields($data, $input, $metaTemplates); + $massagedData = $this->massageMetaFields($data, $input, $metaTemplates, $cleanupMetaFields); + if (!empty($cleanupMetaFields)) { + foreach ($cleanupMetaFields as $cleanupMetaField) { + $this->Table->MetaFields->deleteAll([ + 'AND' => [ + 'scope' => $cleanupMetaField['scope'], + 'field' => $cleanupMetaField['field'], + 'meta_template_field_id' => $cleanupMetaField['meta_template_field_id'], + 'meta_template_id' => $cleanupMetaField['meta_template_id'], + 'parent_id' => $id + ] + ]); + } + } unset($input['MetaTemplates']); // Avoid MetaTemplates to be overriden when patching entity $data = $massagedData['entity']; $metaFieldsToDelete = $massagedData['metafields_to_delete']; + if (isset($input['meta_fields'])) { + unset($input['meta_fields']); + } } $data = $this->Table->patchEntity($data, $input, $patchEntityParams); if (isset($params['beforeSave'])) { From 5048c38ed653f60aa18129b3ac68fcd8fd7c5e6d Mon Sep 17 00:00:00 2001 From: iglocska Date: Wed, 28 Aug 2024 16:13:09 +0200 Subject: [PATCH 3/5] fix: [CRUD] run afterfind even if no metatemplates set --- src/Controller/Component/CRUDComponent.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Controller/Component/CRUDComponent.php b/src/Controller/Component/CRUDComponent.php index 441a5e7..f2683a2 100644 --- a/src/Controller/Component/CRUDComponent.php +++ b/src/Controller/Component/CRUDComponent.php @@ -432,9 +432,9 @@ class CRUDComponent extends Component if ($metaFieldsEnabled) { $metaTemplates = $this->getMetaTemplates(); $data = $this->attachMetaTemplatesIfNeeded($data, $metaTemplates->toArray()); - if (isset($params['afterFind'])) { - $data = $params['afterFind']($data, $params); - } + } + if (isset($params['afterFind'])) { + $data = $params['afterFind']($data, $params); } if ($this->request->is('post')) { $patchEntityParams = [ From d4880e7b56d67e9be1048a877b5427c76994ad3c Mon Sep 17 00:00:00 2001 From: iglocska Date: Wed, 28 Aug 2024 16:13:32 +0200 Subject: [PATCH 4/5] fix: [users] add load individual correctly and show it to the user --- src/Controller/UsersController.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/Controller/UsersController.php b/src/Controller/UsersController.php index 7be3d69..438b3bf 100644 --- a/src/Controller/UsersController.php +++ b/src/Controller/UsersController.php @@ -156,6 +156,10 @@ class UsersController extends AppController if (Configure::read('keycloak.enabled')) { $this->Users->enrollUserRouter($data); } + if ($data['individual_id']) { + $data['individual'] = $this->Users->Individuals->find('all')->where(['id' => $data['individual_id']])->contain(['Alignments' => 'Organisations'])->first(); + } + return $data; }, 'afterFind' => function ($user, &$params) use ($currentUser) { if (!empty($user)) { // We don't have a 404 From 4906cae0c7fe43cf0b1c7afee4f3420a98c2bbbd Mon Sep 17 00:00:00 2001 From: iglocska Date: Wed, 28 Aug 2024 16:19:04 +0200 Subject: [PATCH 5/5] fix: [crud] various minor fixes --- src/Controller/Component/CRUDComponent.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Controller/Component/CRUDComponent.php b/src/Controller/Component/CRUDComponent.php index f2683a2..02e3acb 100644 --- a/src/Controller/Component/CRUDComponent.php +++ b/src/Controller/Component/CRUDComponent.php @@ -612,7 +612,6 @@ class CRUDComponent extends Component // the idea is that integrators shouldn't have to mimic the complex format used by the UI. if (isset($input['meta_fields'])) { $input = $this->handleSimpleMetaFieldInput($allMetaTemplates, $input, $cleanupMetaFields); - $entity->cleanupMetaFields = $cleanupMetaFields; } if (!empty($entity->meta_fields)) { foreach ($entity->meta_fields as $i => $metaField) {