diff --git a/app/plugins/CoreEnroller/src/Model/Table/AttributeCollectorsTable.php b/app/plugins/CoreEnroller/src/Model/Table/AttributeCollectorsTable.php
index 1ecd9bc8..bf8ab7e7 100644
--- a/app/plugins/CoreEnroller/src/Model/Table/AttributeCollectorsTable.php
+++ b/app/plugins/CoreEnroller/src/Model/Table/AttributeCollectorsTable.php
@@ -166,7 +166,7 @@ public function finalize(int $id, \App\Model\Entity\Petition $petition): bool
})->toArray();
$personRoleAttributes = array_keys($personRoleAttributes);
- // Get all the fields/values required to build the PrersonRole
+ // Get all the fields/values required to build the PersonRole
$fieldsForPersonRole = $attributesCollection->filter(function($attr, $key) use ($personRoleAttributes) {
return in_array($attr['enrollment_attribute']['attribute'], $personRoleAttributes);
})->toArray();
@@ -213,7 +213,7 @@ public function finalize(int $id, \App\Model\Entity\Petition $petition): bool
);
/****** PERSON ******/
- // Filter the MVEAS Attributes and keep the field name
+ // Keep the person attributes
$personAttributes = (new Collection($supportedAttributes))->filter(function($attr, $key) {
return isset($attr['model']) && $attr['model'] == 'Person';
})->toArray();
@@ -224,11 +224,38 @@ public function finalize(int $id, \App\Model\Entity\Petition $petition): bool
return in_array($attr['enrollment_attribute']['attribute'], $personAttributes);
})->toArray();
- if($People->saveAttributes($person->id, $fieldsForPerson) === false) {
+
+ try {
+ $People->saveAttributes($person->id, $fieldsForPerson);
+ } catch (\Exception $e) {
+ $this->llog('error', __d('error', 'save', [$e->getMessage()]));
$cxn->rollback();
throw new \RuntimeException(__d('error', 'save', ['Person']));
}
+
+ /****** GROUP ******/
+ // Filter the MVEAS Attributes and keep the field name
+ $groupAttributes = (new Collection($supportedAttributes))->filter(function($attr, $key) {
+ return isset($attr['model']) && $attr['model'] == 'Group';
+ })->toArray();
+ $groupAttributes = array_keys($groupAttributes);
+
+ // Get all the fields/values required to build the PrersonRole
+ $fieldsForGroup = $attributesCollection->filter(function($attr, $key) use ($groupAttributes) {
+ return in_array($attr['enrollment_attribute']['attribute'], $groupAttributes);
+ })->toArray();
+
+
+ try {
+ $groupMemberObj = TableRegistry::getTableLocator()->get('GroupMembers');
+ $groupMemberObj->saveAttributes($person->id, $fieldsForGroup);
+ } catch (\Exception $e) {
+ $this->llog('error', __d('error', 'save', [$e->getMessage()]));
+ $cxn->rollback();
+ throw new \RuntimeException(__d('error', 'save', ['GroupMembers']));
+ }
+
// Save the Date Of Birth. This is the only one that is single valued
// and goes under the Person
diff --git a/app/src/Model/Behavior/TimezoneBehavior.php b/app/src/Model/Behavior/TimezoneBehavior.php
index 6c782da6..dfa9655b 100644
--- a/app/src/Model/Behavior/TimezoneBehavior.php
+++ b/app/src/Model/Behavior/TimezoneBehavior.php
@@ -64,9 +64,7 @@ public function beforeMarshal(Event $event, ArrayObject $data, ArrayObject $opti
if(!empty($data[$f])) {
// This returns a DateTime object adjusting for localTZ
$offsetDT = new \DateTime($data[$f], $this->tz);
-
- // strftime converts a timestamp according to server localtime (which should be UTC)
- $data[$f] = strftime("%F %T", $offsetDT->getTimestamp());
+ $data[$f] = date("Y-m-d H:i:s", $offsetDT->getTimestamp());
}
}
}
diff --git a/app/src/Model/Table/AddressesTable.php b/app/src/Model/Table/AddressesTable.php
index 741ef659..2042a73c 100644
--- a/app/src/Model/Table/AddressesTable.php
+++ b/app/src/Model/Table/AddressesTable.php
@@ -316,7 +316,6 @@ public function saveAttributes(int $personId, ?int $roleId, string $parentModel,
$address['person_role_id'] = $roleId;
}
- // We need to get this from CoSettings??
foreach($fields as $fld) {
$address[$fld->column_name] = $fld->value;
}
diff --git a/app/src/Model/Table/GroupMembersTable.php b/app/src/Model/Table/GroupMembersTable.php
index 48d540b6..7f01f6d9 100644
--- a/app/src/Model/Table/GroupMembersTable.php
+++ b/app/src/Model/Table/GroupMembersTable.php
@@ -549,4 +549,33 @@ public function validationDefault(Validator $validator): Validator {
return $validator;
}
+
+
+ /**
+ * Save attributes for a person.
+ *
+ * This method is responsible for saving attributes for a given person.
+ * It constructs an entity with the provided fields and ensures the entity
+ * is saved successfully.
+ *
+ * @param int $personId The ID of the person to save attributes for.
+ * @param array $fields An array of fields to update, where each field
+ * includes an enrollment attribute and its value.
+ *
+ * @return GroupMember The saved entity representing the person's role.
+ *
+ */
+ public function saveAttributes(int $personId, array $fields): GroupMember
+ {
+ $member = [
+ 'person_id' => $personId,
+ ];
+
+ // We need to get this from CoSettings??
+ foreach($fields as $fld) {
+ $member[$fld->enrollment_attribute->attribute] = $fld->value;
+ }
+
+ return $this->saveOrFail($this->newEntity($member));
+ }
}
\ No newline at end of file
diff --git a/app/src/Model/Table/NamesTable.php b/app/src/Model/Table/NamesTable.php
index 11546b87..2aa2b2e5 100644
--- a/app/src/Model/Table/NamesTable.php
+++ b/app/src/Model/Table/NamesTable.php
@@ -494,8 +494,6 @@ public function saveAttributes(int $personId, ?int $roleId, string $parentModel,
$name[$fld->column_name] = $fld->value;
}
- // XXX Check if we already have an this value saved
-
$this->saveOrFail($this->newEntity($name));
return true;
}
diff --git a/app/src/Model/Table/PeopleTable.php b/app/src/Model/Table/PeopleTable.php
index 60c3d414..d35adea4 100644
--- a/app/src/Model/Table/PeopleTable.php
+++ b/app/src/Model/Table/PeopleTable.php
@@ -29,15 +29,16 @@
namespace App\Model\Table;
+use App\Model\Entity\Person;
use Cake\ORM\Query;
use Cake\ORM\RulesChecker;
use Cake\ORM\Table;
use Cake\Validation\Validator;
use \App\Lib\Enum\ActionEnum;
use \App\Lib\Enum\GroupTypeEnum;
+use \App\Lib\Enum\ProvisioningEligibilityEnum;
use \App\Lib\Enum\StatusEnum;
use \App\Lib\Enum\SuspendableStatusEnum;
-use \App\Lib\Enum\ProvisioningEligibilityEnum;
use \App\Lib\Util\PaginatedSqlIterator;
class PeopleTable extends Table {
@@ -368,7 +369,7 @@ public function findIndexed(Query $query): Query {
* @return string Display field
*/
- public function generateDisplayField(\App\Model\Entity\Person $entity): string {
+ public function generateDisplayField(Person $entity): string {
if(empty($entity->primary_name)) {
throw new \InvalidArgumentException(__d('error', 'Names.primary_name'));
}
@@ -745,14 +746,11 @@ public function validationDefault(Validator $validator): Validator {
* @param int $personId The ID of the person entity to update.
* @param array $fields An array of fields to update, where each field is expected to have an
* `enrollment_attribute` with an `attribute` property, and a `value` property containing the value to update.
- * @return \App\Model\Entity\Person The updated person entity after saving.
- * @throws \Cake\Datasource\Exception\RecordNotFoundException If the person with the given ID does not exist.
- * @throws \RuntimeException If the person entity could not be saved.
+ * @return Person The updated person entity after saving.
* @since COmanage Registry v5.1.0
*/
- public function saveAttributes(int $personId, array $fields): \App\Model\Entity\Person
+ public function saveAttributes(int $personId, array $fields): Person
{
-
$person = $this->get($personId);
foreach ($fields as $field) {
$attribute = $field->enrollment_attribute->attribute;
@@ -769,6 +767,6 @@ public function saveAttributes(int $personId, array $fields): \App\Model\Entity\
$person->$attribute = $value;
}
- return $this->save($person);
+ return $this->saveOrFail($person);
}
}
\ No newline at end of file
diff --git a/app/src/Model/Table/PersonRolesTable.php b/app/src/Model/Table/PersonRolesTable.php
index 548b57ac..2a292a71 100644
--- a/app/src/Model/Table/PersonRolesTable.php
+++ b/app/src/Model/Table/PersonRolesTable.php
@@ -29,10 +29,10 @@
namespace App\Model\Table;
+use App\Model\Entity\PersonRole;
use Cake\Event\EventInterface;
use \Cake\I18n\FrozenTime;
use Cake\ORM\Entity;
-use Cake\ORM\Query;
use Cake\ORM\RulesChecker;
use Cake\ORM\Table;
use Cake\Validation\Validator;
@@ -335,7 +335,7 @@ public function buildRules(RulesChecker $rules): RulesChecker {
* @return string Display field
*/
- public function generateDisplayField(\App\Model\Entity\PersonRole $entity): string {
+ public function generateDisplayField(PersonRole $entity): string {
// Try to find something renderable
if(!empty($entity->title)) {
@@ -717,23 +717,32 @@ public function validationDefault(Validator $validator): Validator {
* @param int $personId ID of the person for whom attributes are being saved
* @param array $fields Array of fields/attributes to be saved
*
- * @return \App\Model\Entity\PersonRole The newly saved Role
+ * @return PersonRole The newly saved Role
* @throws \Cake\Datasource\Exception\RecordNotFoundException If an issue occurs during saving
* @since COmanage Registry v5.1.0
*/
- public function saveAttributes(int $personId, array $fields): \App\Model\Entity\PersonRole
+ public function saveAttributes(int $personId, array $fields): PersonRole
{
+ $dateFormat = 'yyyy-MM-dd HH:mm:ss';
+
$role = [
'person_id' => $personId,
];
// We need to get this from CoSettings??
foreach($fields as $fld) {
- $role[$fld->enrollment_attribute->attribute] = $fld->value;
+ $attribute = $fld->enrollment_attribute->attribute;
+ $value = $fld->value;
+ if(
+ ($attribute === 'valid_from' || $attribute === 'valid_through')
+ && is_string($value)
+ ) {
+ $dob = FrozenTime::parse($value);
+ $value = $dob->i18nFormat($dateFormat);
+ }
+ $role[$attribute] = $value;
}
- // XXX Check if we already have one
-
return $this->saveOrFail($this->newEntity($role));
}
}
\ No newline at end of file
diff --git a/app/src/Model/Table/TelephoneNumbersTable.php b/app/src/Model/Table/TelephoneNumbersTable.php
index 72a938f5..00073179 100644
--- a/app/src/Model/Table/TelephoneNumbersTable.php
+++ b/app/src/Model/Table/TelephoneNumbersTable.php
@@ -254,7 +254,6 @@ public function saveAttributes(int $personId, ?int $roleId, string $parentModel,
$telephone['person_role_id'] = $roleId;
}
- // We need to get this from CoSettings??
foreach($fields as $fld) {
$telephone[$fld->column_name] = $fld->value;
}
diff --git a/app/src/View/Helper/FieldHelper.php b/app/src/View/Helper/FieldHelper.php
index 34ca57ce..33966e3f 100644
--- a/app/src/View/Helper/FieldHelper.php
+++ b/app/src/View/Helper/FieldHelper.php
@@ -315,25 +315,6 @@ public function dateField(string $fieldName,
// that will interact with the field value. Allowing direct access to the input field is for
// accessibility purposes.
- // ACTION VIEW or Readonly Field
- // The latter applies for the attribute collection view
- if($this->action == 'view'
- ||
- (isset($fieldArgs['readonly']) && $fieldArgs['readonly'])
- ) {
- // return the date as plaintext
- $element = $this->getView()->element('form/notSetDiv', [], [
- 'cache' => '_html_elements',
- ]);
- if ($date_object !== null) {
- // Adjust the time back to the user's timezone
- $element = '';
- }
-
- // Return this to the generic control() function
- return $element;
- }
-
// Special-case the very common "valid_from" and "valid_through" fields, so we won't need
// to specify their types in fields.inc.
$pickerTypeName = $fieldArgs['fieldNameAlias'] ?? $fieldName;
@@ -363,6 +344,27 @@ public function dateField(string $fieldName,
$pickerDate = $date_object->i18nFormat($dateFormat);
}
+ // ACTION VIEW or Readonly Field
+ // The latter applies for the attribute collection view
+ // For the Attribute Collection View we also need a hidden field
+ if($this->action == 'view'
+ ||
+ (isset($fieldArgs['readonly']) && $fieldArgs['readonly'])
+ ) {
+ // return the date as plaintext
+ // Add a hidden field
+ $element = $this->getView()->element('form/notSetDiv', [], [
+ 'cache' => '_html_elements',
+ ]);
+ if ($date_object !== null) {
+ // Adjust the time back to the user's timezone
+ $element = '';
+ }
+
+ // Return this to the generic control() function
+ return $this->Form->hidden($fieldName, $coptions) . $element;
+ }
+
// Set the date picker floor year value (-100 years)()
$pickerDateFT = new FrozenTime($pickerDate);
$pickerDateFT = $pickerDateFT->subYears(100);