Skip to content

CFM-324-Attribute-Collector-Save-Attributes #292

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -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();
Expand Down Expand Up @@ -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();
Expand All @@ -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

Expand Down
4 changes: 1 addition & 3 deletions app/src/Model/Behavior/TimezoneBehavior.php
Expand Up @@ -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());
}
}
}
Expand Down
1 change: 0 additions & 1 deletion app/src/Model/Table/AddressesTable.php
Expand Up @@ -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;
}
Expand Down
29 changes: 29 additions & 0 deletions app/src/Model/Table/GroupMembersTable.php
Expand Up @@ -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));
}
}
2 changes: 0 additions & 2 deletions app/src/Model/Table/NamesTable.php
Expand Up @@ -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;
}
Expand Down
14 changes: 6 additions & 8 deletions app/src/Model/Table/PeopleTable.php
Expand Up @@ -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 {
Expand Down Expand Up @@ -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'));
}
Expand Down Expand Up @@ -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;
Expand All @@ -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);
}
}
23 changes: 16 additions & 7 deletions app/src/Model/Table/PersonRolesTable.php
Expand Up @@ -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;
Expand Down Expand Up @@ -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)) {
Expand Down Expand Up @@ -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));
}
}
1 change: 0 additions & 1 deletion app/src/Model/Table/TelephoneNumbersTable.php
Expand Up @@ -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;
}
Expand Down
40 changes: 21 additions & 19 deletions app/src/View/Helper/FieldHelper.php
Expand Up @@ -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 = '<time>' . $date_object->i18nFormat($dateFormat) . '</time>';
}

// 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;
Expand Down Expand Up @@ -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 = '<time>' . $date_object->i18nFormat($dateFormat) . '</time>';
}

// 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);
Expand Down