Skip to content

Commit

Permalink
Add support for attribute collection fieldsets
Browse files Browse the repository at this point in the history
  • Loading branch information
Ioannis committed Nov 5, 2024
1 parent 68db3dd commit 00ef4c9
Show file tree
Hide file tree
Showing 6 changed files with 474 additions and 79 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,12 @@ public function initialize(array $config): void {
'urlTypes' => [
'type' => 'type',
'attribute' => 'Urls.type'
]
],
// Required for attribute collection
'cosettings' => [
'type' => 'auxiliary',
'model' => 'CoSettings'
],
]);

$this->setLayout([ 'index' => 'iframe',
Expand Down
107 changes: 107 additions & 0 deletions app/plugins/CoreEnroller/templates/AttributeCollectors/attribute.inc
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
<?php
/**
* COmanage Registry Attribute Fields
*
* 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.0.0
* @license Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
*/

declare(strict_types = 1);

use App\Lib\Enum\StatusEnum;
use \Cake\Utility\Inflector;

// Field Options array
$options = [];


// 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]);

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
// problems with field names that are purely integers (even if cast to strings)
'fieldName' => 'field-' . $attr->id,
'fieldLabel' => $attr->label, // fieldLabel is only applicable to checkboxes
'fieldType' => $supportedAttributes['fieldType'],
'fieldDescription' => $attr->description,
'fieldNameAlias' => $attr->attribute // the field name to its enrollment attribute field name
];


/*
* Get the values for the attributes ending with _id
* Supported for attributes: group_id, cou_id, affiliation_type_id
*/
if(str_ends_with($attr->attribute, '_id')) {
$suffix = substr($attr->attribute, 0, -3);
$suffix = Inflector::pluralize(Inflector::camelize($suffix)) ;
$defaultValuesPopulated = 'defaultValue' . $suffix;
if ($this->get($defaultValuesPopulated) !== null) {
$formArguments['fieldType'] = 'select';
$formArguments['fieldSelectOptions'] = $this->get($defaultValuesPopulated);
}
}

// READ-ONLY
if (isset($attr->modifiable) && !$attr->modifiable) {
$options['readonly'] = true;
}

// REQUIRED
if (isset($attr->required) && $attr->required) {
$options['required'] = true;
}

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

// HIDDEN Field
// We print directly, we do not delegate to the element for further processing
if ($attr->hidden) {
// In case this is a hidden field, we need to get only the value
print $this->Form->hidden($formArguments['fieldName'], ['value' => $options['default']]);
} else {
// Print the element
print $this->element('form/listItem', [
'arguments' => $formArguments
]);
}
Original file line number Diff line number Diff line change
Expand Up @@ -57,80 +57,10 @@ foreach($vv_enrollment_attributes_sorted as $attr) {
// Get the static configuration of my attribute
$supportedAttributes = $this->Petition->getSupportedEnrollmentAttribute($attr->attribute);

// Field Options array
$options = [];


// 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 rerendering 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]);

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
// problems with field names that are purely integers (even if cast to strings)
'fieldName' => 'field-' . $attr->id,
'fieldLabel' => $attr->label, // fieldLabel is only applicable to checkboxes
'fieldType' => $supportedAttributes['fieldType'],
'fieldDescription' => $attr->description,
'fieldNameAlias' => $attr->attribute // the field name to its enrollment attribute field name
];


/*
* Get the values for the attributes ending with _id
* Supported for attributes: group_id, cou_id, affiliation_type_id
*/
if(str_ends_with($attr->attribute, '_id')) {
$suffix = substr($attr->attribute, 0, -3);
$suffix = Inflector::pluralize(Inflector::camelize($suffix)) ;
$defaultValuesPopulated = 'defaultValue' . $suffix;
if ($this->get($defaultValuesPopulated) !== null) {
$formArguments['fieldType'] = 'select';
$formArguments['fieldSelectOptions'] = $this->get($defaultValuesPopulated);
}
}

// READ-ONLY
if (isset($attr->modifiable) && !$attr->modifiable) {
$options['readonly'] = true;
}

// REQUIRED
if (isset($attr->required) && $attr->required) {
$options['required'] = true;
}

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

// HIDDEN Field
// We print directly, we do not delegate to the element for further processing
if ($attr->hidden) {
// In case this is a hidden field, we need to get only the value
print $this->Form->hidden($formArguments['fieldName'], ['value' => $options['default']]);
continue;
if(empty($attr->attribute_required_fields)) {
include( $vv_template_path . DS . 'attribute.inc');
} else {
include( $vv_template_path . DS . 'multifield_attribute.inc');
}

// Print the element
print $this->element('form/listItem', [
'arguments' => $formArguments
]);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
<?php
/**
* COmanage Registry Attribute Fields
*
* 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.0.0
* @license Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
*/

declare(strict_types = 1);

use App\Lib\Enum\StatusEnum;
use \Cake\Utility\Inflector;

// This field is called attribute_type and not attribute_type_id because we want this
// to behave as a hidden value populated by the appropriate select, and we don't want
// Cake to implement foreign key automagic.
$mveaAutoPopulatedVariable = $attr->attribute . 'Types';
// Check if this mvea model supports types, if it does then render the attribute type
// dropdown list
$fieldLabel = 'Not found';
if ($this->get($mveaAutoPopulatedVariable) !== null) {
$fieldLabel = $this->get($mveaAutoPopulatedVariable)[$attr->attribute_type] . ' ' . ucfirst($attr->attribute);
}

$required_fields_variable_name = "required_fields_$attr->attribute";
$permitted_fields_variable_name = "permitted_fields_$attr->attribute";
$permitted_fields_list = [];
$required_fields_list = [];
if (!empty($cosettings[0][$required_fields_variable_name])) {
$required_fields_list = explode(',', $cosettings[0][$required_fields_variable_name]);
}

if (!empty($cosettings[0][$permitted_fields_variable_name])) {
$permitted_fields_list = explode(',', $cosettings[0][$permitted_fields_variable_name]);
}
?>

<li class="fields-<?= $attr->attribute?>">
<fieldset>
<legend class="fieldset-<?= $attr->attribute?>">
<?= $fieldLabel ?>
</legend>
<div class="fieldset-info">

<?php foreach (explode(',', $attr->attribute_required_fields) as $field) : ?>
<?php if(!\in_array($field, $permitted_fields_list, true)) { continue; } ?>
<?php
// Construct the field arguments
$formArguments = [
// We prefix the attribute ID with a string because Cake seems to sometimes have
// problems with field names that are purely integers (even if cast to strings)
'fieldName' => "field-$field-$attr->id",
'fieldLabel' => $attr->label, // fieldLabel is only applicable to checkboxes
'fieldType' => $supportedAttributes['fieldType'],
'fieldNameAlias' => $attr->attribute // the field name to its enrollment attribute field name
];
?>

<div class="fieldset-field field-type-<?=$field?>">
<label for="<?= $field ?>"><?= ucfirst($field) . ' ' . ucfirst($attr->attribute) ?></label>
<?= \in_array($field, $required_fields_list, true) ? $this->element('form/requiredSpan') : ''?>
<div class="input text">
<?= $this->Field->formField(...$formArguments) ?>
</div>
</div>
<?php endforeach; ?>

</div>
</fieldset>
</li>
9 changes: 5 additions & 4 deletions app/src/Controller/StandardEnrollerController.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,11 @@ public function beforeRender(\Cake\Event\EventInterface $event) {
// Make the Petition available to the view
$this->set(
'vv_petition',
$Petition->findById($this->petition->id)
->contain($Petition->getIndexContains())
->firstOrFail()
);
$this->petition?->id ?
$Petition->findById($this->petition->id)
->contain($Petition->getIndexContains())
->firstOrFail() : null
);

return parent::beforeRender($event);
}
Expand Down
Loading

0 comments on commit 00ef4c9

Please sign in to comment.