Skip to content

Commit

Permalink
Save petition attribute collection data
Browse files Browse the repository at this point in the history
Save form and display.php render

phpv8.2 deprecation

Petition preview

parse people picker value

Petition Preview new structure

Add collapsable behavior

fix people link

Fix disabled fields. Fix affiliation_type petition render.

More improvements

Fixing Petition resume view
  • Loading branch information
Ioannis committed Feb 5, 2025
1 parent 9e5dcdb commit 05887e0
Show file tree
Hide file tree
Showing 16 changed files with 276 additions and 32 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,9 @@
namespace CoreEnroller\Controller;

use App\Controller\StandardEnrollerController;
use App\Lib\Enum\PetitionStatusEnum;
use Cake\Event\EventInterface;
use Cake\Http\Response;
use Cake\ORM\TableRegistry;

class AttributeCollectorsController extends StandardEnrollerController {
public $paginate = [
Expand Down Expand Up @@ -125,12 +125,19 @@ public function dispatch(string $id) {
/**
* Display information about this Step.
*
* @since COmanage Registry v5.0.0
* @since COmanage Registry v5.1.0
* @param string $id Attribute Collector ID
*/

public function display(string $id) {
debug("display something for this petition");
debug($this->getPetition());
public function display(string $id): void {
$petition = $this->getPetition();

$this->set('vv_petition_attributes',
$this->AttributeCollectors
->EnrollmentAttributes
->PetitionAttributes
->find()
->where(['petition_id' => $petition->id])
->all());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -166,15 +166,33 @@ public function upsert(int $id, int $petitionId, array $attributes) {

foreach($attributes as $enrollmentAttributeLabel => $value) {
// Remove field- prefix from the form field name
$enrollmentAttributeId = (int)substr($enrollmentAttributeLabel, 6);
$fieldToParts = explode('-', $enrollmentAttributeLabel);
// MVAs have multiple columns. For example a name has:
// given, surname, prefix, ...
$columnName = null;
if (count($fieldToParts) > 2) {
// There is a type ID in the middle
$columnName = $fieldToParts[1];
}
// The enrollment Attribute ID is the last part
$enrollmentAttributeId = (int)array_pop($fieldToParts);

// The people picker will send a complex string and not just the id. We need to extract it ourselves.
$re = '/^.*\(ID: (\d+)\)$/m';
preg_match_all($re, $value, $matches, PREG_SET_ORDER, 0);
if(!empty($matches)) {
$value = $matches[0][1];
}

$newAttribute = [
'petition_id' => $petitionId,
'enrollment_attribute_id' => $enrollmentAttributeId,
'value' => $value
'value' => $value,
// This is the column name for the attributes that consist of multiple fields, like the name or the address
'column_name' => $columnName,
];

if(array_key_exists($enrollmentAttributeId, $currentAttributes)) {
if(\array_key_exists($enrollmentAttributeId, $currentAttributes)) {
// This is an update of an existing attribute

$newAttribute['id'] = $currentAttributes[$enrollmentAttributeId];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ public function validationDefault(Validator $validator): Validator {
$validator->notEmptyString('enrollment_attribute_id');

$this->registerStringValidation($validator, $schema, 'value', false);
$this->registerStringValidation($validator, $schema, 'column', false);

return $validator;
}
Expand Down
3 changes: 2 additions & 1 deletion app/plugins/CoreEnroller/src/config/plugin.json
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,8 @@
"id": {},
"petition_id": {},
"enrollment_attribute_id": { "type": "integer", "foreignkey": { "table": "enrollment_attributes", "column": "id" } },
"value": { "type": "string", "size": 160 }
"value": { "type": "string", "size": 160 },
"column_name": { "notnull": false, "type": "string", "size": 64 }
},
"indexes": {
"petition_attributes_i1": { "columns": [ "petition_id" ] },
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?php
$petition_attributes = $vv_petition_attributes->toArray();
?>
<ul>
<?php foreach ($petition_attributes as $attribute): ?>
<li>ID: <?= $attribute->id?>, Value: <?= $attribute->value?>, Column Name: <?= $attribute->column_name ?></li>
<?php endforeach; ?>
</ul>
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,7 @@ use \Cake\Utility\Inflector;
$attribute_type = null;
if($vv_action == 'add') {
$attribute_type = $this->request->getQuery('attribute_type');
} else if($vv_action == 'edit' && !empty($vv_obj)
) {
} else if($vv_action == 'edit' && !empty($vv_obj)) {
$attribute_type = $vv_obj->attribute;
}

Expand Down
2 changes: 1 addition & 1 deletion app/plugins/CoreEnroller/templates/element/field.php
Original file line number Diff line number Diff line change
Expand Up @@ -119,5 +119,5 @@
'formArguments' => $formArguments
]),
// Default use case
default => $this->element('form/listItem', ['arguments' => $formArguments])
default => $this->Field->getElementsForDisabledInput('form/listItem', $formArguments)
};
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,39 @@
$isRequiredFromValidationRule = false;
$supportedAttributes = $this->Petition->getSupportedEnrollmentAttribute($attr->attribute);

// Field Options array
$options = [];

if(isset($supportedAttributes['mveaModel'])) {
$supportedAttributes = $this->Petition->getSupportedEnrollmentAttribute($attr->attribute);
$modelTable = $this->Petition->getTable($supportedAttributes['mveaModel']);
$isRequiredFromValidationRule = !$modelTable->getValidator()->field($field)->isEmptyAllowed();
}

// Do we have a default value configured?
// Either a value or an Environmental Variable,
// Each default value is mutually exclusive to the rest. We do not have to worry about a conflict.
$options['default'] = match(true) {
isset($attr->default_value) => $attr->default_value,
isset($attr->default_value_env_name)
&& getenv($attr->default_value_env_name) !== false => getenv($attr->default_value_env_name),
isset($attr->default_value_datetime) => $attr->default_value_datetime,
default => ''
};

// If we are re-rendering the Petition, override the default value with whatever
// was previously saved
if(!empty($vv_petition_attributes)) {
$curEntity = $vv_petition_attributes->firstMatch([
'enrollment_attribute_id' => $attr->id,
'column_name' => $field
]);

if(!empty($curEntity->value)) {
$options['default'] = $curEntity->value;
}
}

// Construct the field arguments
$formArguments = [
// We prefix the attribute ID with a string because Cake seems to sometimes have
Expand All @@ -53,6 +80,9 @@
'fieldType' => $modelTable->getSchema()->getColumn($field)['type'],
'fieldNameAlias' => $attr->attribute // the field name to its enrollment attribute field name
];

// Set the final fieldOptions
$formArguments['fieldOptions'] = $options;
?>

<div class="fieldset-field <?= "fields-$field"?>">
Expand Down
6 changes: 5 additions & 1 deletion app/src/Model/Table/PetitionsTable.php
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,9 @@ public function initialize(array $config): void {
$this->hasMany('PetitionStepResults')
->setDependent(true)
->setCascadeCallbacks(true);
$this->hasMany('PetitionAttributes')
->setDependent(true)
->setCascadeCallbacks(true);

$this->hasOne('Verifications')
->setDependent(true)
Expand All @@ -116,7 +119,8 @@ public function initialize(array $config): void {
'EnrolleePeople' => ['PrimaryName' => ['foreignKey' => 'person_id']],
'PetitionerPeople' => ['PrimaryName' => ['foreignKey' => 'person_id']],
'PetitionHistoryRecords',
'PetitionStepResults'
'PetitionStepResults',
'PetitionAttributes',
]);

$this->setAutoViewVars([
Expand Down
2 changes: 1 addition & 1 deletion app/src/View/Helper/FieldHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -304,7 +304,7 @@ public function dateField(string $fieldName,
isset($fieldArgs['default']) && is_string($fieldArgs['default']) => FrozenTime::parse($fieldArgs['default']),
// Petition View/ Value saved a FronzenTime
isset($fieldArgs['default'])
&& is_a($fieldArgs['default'], 'Cake\I18n\FrozenTime') => $fieldArgs['default'],
&& is_a($fieldArgs['default'], 'Cake\I18n\FrozenTime') => $fieldArgs['default'],
// Table record/ Retrieve it from the Entity object
default => $this->getEntity()?->$fieldName,
};
Expand Down
1 change: 1 addition & 0 deletions app/src/View/Helper/PetitionHelper.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
use Cake\Utility\Inflector;
use Cake\View\Helper;
use CoreEnroller\Model\Table\EnrollmentAttributesTable;
use DOMDocument;

class PetitionHelper extends Helper
{
Expand Down
38 changes: 20 additions & 18 deletions app/templates/Petitions/fields.inc
Original file line number Diff line number Diff line change
Expand Up @@ -230,35 +230,37 @@ if (!empty($vv_obj?->petitioner_person?->id)) {
</li>


<!-- XXX This needs work -->
<?php foreach($vv_obj->enrollment_flow->enrollment_flow_steps as $step): ?>
<?php
$result = Hash::extract($vv_obj->petition_step_results, "{n}[enrollment_flow_step_id=$step->id]");

if(!empty($result)) {
$resultLink = [
'controller' => 'petitions',
'action' => 'result',
$vv_obj->id,
'?' => [
'enrollment_flow_step_id' => $step->id
]
];
}
?>

<?php $result = Hash::extract($vv_obj->petition_step_results, "{n}[enrollment_flow_step_id=$step->id]"); ?>
<li>
<div class="field">
<div class="field-name ">
<div class="field-title">
<?= $step->description ?>
<?= $step->description ?>
</div>
</div>
<div class="field-info">
<?= !empty($result) ? $this->Html->link($result[0]->comment, $resultLink) : "" ?>
<?= !empty($result) ? $result[0]->comment : '' ?>
<a class="cm-toggle nospin petition-step-collapse-link"
data-bs-toggle="collapse"
href="#collapse-box-<?= $step->id ?>"
onclick="stepCollapseTongle(event, this)"
role="button"
aria-expanded="false"
aria-controls="collapse-box-<?= $step->id ?>">
<em class="material-symbols-outlined petition-step-collapse-icon" aria-hidden="true">
arrow_drop_down
</em>
</a>
</div>
</div>
</li>
<li id="collapse-box-<?= $step->id ?>" class="petition-attrs collapse">
<h3>
<?= __d('menu', 'co.attributes') ?>
</h3>
<?= $this->element('petition/enrollmentFlowStep', ['vv_step' => $step])?>
</li>
<?php endforeach; ?>


Expand Down
40 changes: 40 additions & 0 deletions app/templates/element/petition/enrollmentFlowStep.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?php
/*
* COmanage Registry Enrollment Flow Step
*
* Portions licensed to the University Corporation for Advanced Internet
* Development, Inc. ("UCAID") under one or more contributor license agreements.
* See the NOTICE file distributed with this work for additional information
* regarding copyright ownership.
*
* UCAID licenses this file to you under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* @link https://www.internet2.edu/comanage COmanage Project
* @package registry
* @since COmanage Registry v5.1.0
* @license Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
*
* This generic modal dialog stub is used for confirmations, e.g. when deleting a record.
* The text of the box is overridden with JavaScript, and the confirm button is intended to
* click a CakePHP postLink or postButton in the DOM. Use jsConfirmGeneric() to call it.
*/

declare(strict_types = 1);

$parsePluginName = explode('.', $vv_step->plugin);
$modelName = array_pop($parsePluginName);
$elementName = lcfirst($modelName) . 'Step';

// The convention is that the element name for each step is the name of the EnrollmentFlow Step model followed by
// the word Step
print $this->element("petition/enrollmentFlowSteps/$elementName", ['vv_step' => $vv_step]);
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
<?php
/*
* COmanage Registry Attibutte Collectors Step
*
* Portions licensed to the University Corporation for Advanced Internet
* Development, Inc. ("UCAID") under one or more contributor license agreements.
* See the NOTICE file distributed with this work for additional information
* regarding copyright ownership.
*
* UCAID licenses this file to you under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* @link https://www.internet2.edu/comanage COmanage Project
* @package registry
* @since COmanage Registry v5.1.0
* @license Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
*
* This generic modal dialog stub is used for confirmations, e.g. when deleting a record.
* The text of the box is overridden with JavaScript, and the confirm button is intended to
* click a CakePHP postLink or postButton in the DOM. Use jsConfirmGeneric() to call it.
*/

declare(strict_types = 1);

use Cake\Database\Expression\QueryExpression;
use Cake\ORM\Query;
use Cake\Utility\Hash;

// Extract unique enrollment attribute IDs
$vv_enrollment_atttributes_ids = Hash::extract($vv_obj->petition_attributes, '{n}.enrollment_attribute_id');
$vv_enrollment_atttributes_ids = array_unique($vv_enrollment_atttributes_ids);

$enrollmentAttributesTable = $this->Petition->getTable('EnrollmentAttributes');
$vv_enrollment_attributes = $enrollmentAttributesTable->find()
->where(fn(QueryExpression $exp, Query $q) => $exp->in('id', $vv_enrollment_atttributes_ids))
->toArray();

?>

<ul>
<?php foreach ($vv_enrollment_attributes as $attribute): ?>
<?php $vv_petition_atttributes = collection($vv_obj->petition_attributes)->filter(fn($attr) => $attr->enrollment_attribute_id === $attribute->id) ?>
<?php if($vv_petition_atttributes->count() === 1): ?>
<?php
$attr = $vv_petition_atttributes->first();
$value = $attr->value ?? 'N/A';
if(!empty($value) && str_ends_with($attribute->attribute, 'person_id')) {
// We need to load the associated model data
$associatedModel = $this->Petition->getRecordForId('person_id', $attr->value, ['PrimaryName']);
$value = $associatedModel[0]->primary_name->given . ' '
. $associatedModel[0]->primary_name->family . ' '
. '(ID: ' . $associatedModel[0]->id . ')';
$value = $this->Html->link($value,
['controller' => 'people', 'action' => 'edit', $attr->value]);
} elseif(!empty($value) && str_ends_with($attribute->attribute, '_id')) {
// We need to load the associated model data
$associatedModel = $this->Petition->getRecordForId($attribute->attribute, $attr->value);
$value = $associatedModel['name'] ?? $associatedModel['value'] ?? $associatedModel['description'] ?? 'N/A';
$value = $this->Html->link($value,
['controller' => \App\Lib\Util\StringUtilities::foreignKeyToController($attribute->attribute), 'action' => 'edit', $attr->value]);
}
?>
<li class="petition-attr-<?= $this->Petition->getClassPostfixFromAttributeName($attribute->attribute) ?>">
<h4 class="petition-attr-label"><?= $attribute->label ?></h4>
<div class="petition-attr-value"><?= $value ?>
</div>
</li>
<?php else: ?>
<li class="petition-attr-<?= $this->Petition->getClassPostfixFromAttributeName($attribute->attribute) ?>">
<h4 class="petition-attr-label"><?= $attribute->label ?></h4>
<ul class="petition-attrs-subset">
<?php foreach ($vv_petition_atttributes as $attr): ?>
<li>
<div class="petition-attrs-subset-label"><?= $attr->column_name ?></div>
<div class="petition-attr-subset-value"><?= $attr->value ?></div>
</li>
<?php endforeach; ?>
</ul>
</li>
<?php endif; ?>
<?php endforeach; ?>
</ul>
Loading

0 comments on commit 05887e0

Please sign in to comment.